美文网首页
Redis架构手记

Redis架构手记

作者: s1991721 | 来源:发表于2021-05-02 21:48 被阅读0次

    目录

    1、Redis持久化

    • 优缺点对比
    • 实际配置
    • 根据RDB文件的恢复过程

    2、Redis读写分离架构

    • 注意事项
    • 复制流程
    • 数据丢失场景
    • 哨兵

    3、Redis集群架构

    • 数据的负载均衡算法
    • 实际操作
    • 主备切换过程

    4、缓存架构

    • 一般缓存架构
    • 多级缓存架构

    5、数据清除策略

    • 配置
    • 流程

    Redis持久化

    持久化策略共提供了两种

    • RDB 全量备份
      每隔一个时间间隔做Redis的一份快照,记录当前Redis中的全都数据

    • AOF 增量备份
      记录Redis的每一次操作到AOF文件

    AOF流程:

    Redis只有一个AOF文件,在Redis和AOF文件间存在一个OSCache系统级缓存,Redis每次写操作先存储在OSCache中,每隔一段时间执行fsync操作,将OSCache中的数据再写入磁盘中的AOF文件,这时才真正的存储在磁盘上。

    Redis的内存是一定量的,AOF则是记录每条数据的操作,所以会逐渐变大。当Redis执行LRU策略淘汰某些数据时,AOF中记录的数据就会过期,所以当AOF到一定程度时会有rewrite操作。rewrite操作会根据当前Redis中的数据,重新构建一个新AOF文件,以清除过期失效的记录缩小AOF文件大小,构建完成后替换旧的AOF文件。

    优缺点对比

    RDB优点:适合冷备、性能高(不必一条条记录写磁盘)、数据恢复快
    RDB缺点:丢数据多(时间间隔内的数据)、数据量多时恢复会有延迟

    AOF优点:最多丢时间间隔内的数据(间隔比RDB短)、append-only模式不需寻址写入AOF文件性能高,文件不易破损
    AOF缺点:相同情况下AOF文件大于RDB文件大小、拖慢Redis的QPS、数据恢复慢(重放操作)

    实际配置

    RDB

    redis.conf文件,SNAPSHOTTING节点下设置RDB的相关参数

    默认设置
    save 900 1
    save 300 10
    save 60 1000
    即:每隔60秒超过1000个key发生变更,则生成一个dump.rdb文件
    配置文件内可配置多个检查点
    

    生成的dump.rdb文件在配置的dir目录下,新文件覆盖旧文件

    安全退出Redis,会自动触发生成当前Redis的dump.rdb文件

    AOF

    redis.conf文件,APPEND ONLY MODE节点下设置AOF的相关参数

    RDB是默认打开的,而AOF是默认关闭

    appendonly yes 打开AOF
    

    若Redis重启且AOF和RDB都开启的情况下,优先AOF恢复(数据完整性较RDB好)在dir目录下查找AOF文件进行恢复

    fsync操作的设置,会影响数据的丢失量

    appendfsync always 每写入一条数据,立即执行fsync操作将数据写入磁盘,性能差、吞吐量低
    appendfsync everysec 每秒将OSCache中的数据刷入磁盘,QPS在万级别,默认项
    appendfsync no 数据进入OSCache后,由OS决定刷入磁盘的时机
    

    rewrite策略,控制AOF文件不至于无限增长

    auto-aof-rewrite-percentage 100 
    auto-aof-rewrite-min-size 64mb
    

    较上次rewrite的AOF文件大小,增长比例达到100%,且AOF文件大于min-size大小,则触发rewrite操作

    rewrite流程:

    • Redis fork一个子进程,基于当前内存的数据构建日志,写入新AOF文件中。
    • 此时Redis主进程能继续接收外部的写操作,并将操作记录存入一块内存同时写入旧AOF文件中。
    • 子进程完成后,主进程将内存中新记录追加到新AOF文件中
    • 新AOF文件替换旧AOF文件

    AOF 文件修复

    因为AOF文件采用append-only模式写入,所以文件破损只会发生在文件尾部

    redis-check-aof --fix [file] 通过此命令进行AOF的文件修复
    

    RDB全量备份与AOF的rewrite不会同时进行,若发生则等待前一操作完成后执行(磁盘IO开销太大)

    根据RDB文件的恢复过程

    1.关闭AOF配置项,否则默认根据AOF恢复,如没有发现AOF文件则会生成一份空的AOF文件,并根据空的AOF文件恢复

    2.拷贝RDB文件到目录,重启Redis,完成恢复

    3.热修改开启AOF,这时生成的AOF文件会存储当前数据,但通过热修改配置的方式在配置文件内并没有实际修改

    4.关闭Redis,手动修改配置开启AOF,再次重启Redis

    Redis读写分离架构

    Redis缓存主要应对的是读请求场景,对于未命中项则会请求到数据库,MySQL正常的QPS在1~2K。要想达到高并发,需要将读请求在Redis缓存层处理掉。

    单机Redis可承载万级的QPS(视业务场景、机器而定),要承载更高的并发需要进行读写分离,master node只负责写操作,slave node负责读操作,两者数据一致。当并发量增加时,可横向扩展增加slave node来分摊QPS。

    注意事项

    • master node采用异步的方式复制数据到slave node,不会影响master node的正常操作

    • slave node复制数据期间会提供对外的读操作,只不过数据复制完成前提供的数据是旧数据。复制完成后,删除旧数据加载新数据阶段,会暂停对外的服务。

    • 采用主从架构需要对master node做持久化,否则master node故障重启后(侦测机制还未触发)数据丢失,将会影响所有的slave node

    • slave node不会过期key,master node过期key后会del通知给slave node

    • master node和slave node之间通过心跳相互联系

    • 一个master node可以配置多个slave node,slave node之间也可以互相连接

    复制流程

    slave node启动时,读取conf配置slaveof中master node的IP和port,slave node内部的定时任务,定期检查是否有新的master node需要连接和复制,并进行socket连接

    slave node发送ping命令给master node,若master node设置了requirepass,则slave node必须发送masterauth口令进行认证

    如果是第一次连接会触发full resynchronization,master node采用异步的方式复制数据到slave node;如果是重连,master node仅会复制slave node缺少的数据。

    开始full resynchronization时,master node会用后台线程做一份RDB的快照文件,slave node会将RDB文件写入自己的磁盘后再加载到内存。期间master node的写操作会记录在内存,master node会将内存中的写命令发送给slave node

    master node和slave node都会维护一个offset,且在不断累加,记录当前的数据。slave node会定期上报master node自己的offset,master node也会记录各个slave node的offset,用来知晓相互间的数据差异。

    若在复制的过程中连接断开重连,slave node可以从offset的位置继续复制,如果找不到对应的offset则会执行resynchronization;slave node也会记录master run id,若发现master run id不同,可能是master node重启或发生变化,需要做全量复制

    配置文件redis.conf中可以设置生成的RDB文件是否落在本地磁盘

    repl-diskless-sync no 是否开启无磁盘化复制
    repl-diskless-sync-delay [] 延迟复制,等待更多的slave node连接
    

    参数配置

    slaveof [ip] [port] 填入master node的信息
    slave-read-only yes 默认开启slave node只读
    

    数据丢失场景

    异步复制 集群脑裂

    解决方法

    min-slaves-to-write 1 最少要写入slave node的数量为1
    min-slaves-max-lag 10 master node和slave node间数据延迟不能超过10秒
    此配置默认未开启
    

    此配置只是降低数据损失量,剩余要client做降级操作减少损失

    哨兵

    哨兵是分布式的架构,最少有3个实例,以保证自己的健壮性。

    哨兵只保证Redis的高可用,不保证数据的零丢失

    哨兵间的通讯通过Redis的pub/sub系统实现

    功能

    • 集群监控 监控Redis中master node和slave node是否正常工作
    • 消息通知 Redis实例故障时发送通知
    • 故障转移 如果master node故障,会选举新master node
    • 配置中心 故障转移时会将新配置项通知各个端

    工作流程

    哨兵有两种失败状态,1个哨兵认为master node挂了就是sdown(主观宕机),quorum数量个哨兵认为master node挂了就是odown(客观宕机)。

    当哨兵ping master node响应时间超过设置的down-after-milliseconds时进入sdown状态

    如果master node被认为odown,且有majority数量的哨兵允许主备切换,就会有一个哨兵执行主备切换的操作,选举一个slave node作为新master node

    考虑因素包括:与master node断开的时长、slave node的优先级、offset值、run id值

    配置参数

    sentinel.conf
    
    哨兵可以监控多个Redis的主从架构
    sentinel monitor [架构名] [ip] [quorum] 监控的主从架构信息
    sentinel down-after-milliseconds [架构名] 60000 超过设置时间认为sdown
    sentinel failover-timeout [架构名] 180000 执行故障转移的超时时间
    sentinel parallel-sync [架构名] 1 并行同步数,新选举的master node,每次同步slave node的数据量,数据同步完成后才会执行后面slave node的同步
    
    port [] 端口号
    bind [ip] 绑定本机IP
    daemonize yes 后台执行
    logfile /var/log/sentinel/*.log 设置日志文件
    

    Redis集群架构

    • 读写分离架构:master node负责写操作,slave node负责读操作,配合哨兵能够达到高可用。

    • 集群架构:存在多个master node,每个master node上可挂载多个slave node。各个master node之间数据不同,能够提供读写操作。当master node挂掉后,slave node顶上以达到高可用。

    读写分离的架构能够存储的数据量仅为master node的内存容量,在海量数据场景下会产生瓶颈,因此在海量数据场景下适用集群架构

    数据的负载均衡算法

    Hash算法(散列算法)用一种较短的信息来保证内容唯一性的算法。在Redis集群架构下如果某一节点挂了,则会导致全部信息失效。

    一致性Hash算法,节点之间采用环形,在Redis集群架构下如果某一节点挂了,则只会丢失此节点数据。热点问题采用虚拟节点来负载均衡

    Hash slot算法,数据存储在slot上,slot存储在节点上,如果某一节点挂了,数据是寻找slot而不是节点,且挂掉的节点会将本节点上的slot迁移到其他节点。

    实际操作

    配置参数

    cluster-enabled yes 启动集群架构,不可同时开启读写分离架构
    cluster-config-file [配置文件] 指定配置文件
    cluster-node-timeout [] 节点超时时长,超时则主备切换
    
    port []
    daemonize yes
    pidfile /var/run/redis_[port].pid
    dir /var/redis/[port]
    logfile /var/log/redis/[port].log
    bind [ip]
    appendonly yes
    

    集群操作

    redis-trib.rb create --replicas [slave node数量] [ip:port] [ip:port] [ip:port] [ip:port]... 启动cluster
    
    redis-trib.rb add-node [ip:port]... 扩容master
    
    redis-trib.rb reshard [ip:port] 会有交互提示输入数据迁移的参数
    
    redis-trib.rb add-node --slave --master-id [id] [ip:port] 给master节点增加slave
    
    redis-trib.rb del-node [ip:port] [id] 删除节点
    

    master node不存在slot时,cluster会将其slave node挂到其他master node上

    cluster会将冗余的slave node分配给其他master node,以保证高可用

    主备切换过程

    各个节点保存集群元数据,节点间采用gossip协议进行通讯,通过节点间不断的通讯以保持整个集群的数据完整性

    当一个节点认为另一个节点宕机了(响应时间超过cluster-node-timeout)称为pfail(主观宕机),多个节点认为一个节点宕机了称为fail(客观宕机)

    对于宕机的master node,从其slave node中选取一个切换为master node

    筛选的条件和哨兵类似:断开连接时间(时间超过cluster-node-timeout*cluster-slave-validity-factory的slave node没有资格参见选举)、priority、offset、run id

    缓存架构

    一般缓存架构

    1.用户发起请求
    2.读请求发起后被web服务器转发到web服务上
    3.web服务先向Redis缓存查询
    4.数据命中则将数据返回给用户
    5.未命中则去数据库查询数据
    6.数据命中后返回给web服务
    7.web服务接收到数据后将数据返回给用户,同时缓存数据

    多级缓存架构

    缓存操作

    • 同步缓存操作

    1.用户向XX服务发送写请求
    2.XX服务将数据同步更新到DB和Redis缓存

    • 异步缓存操作

    1.用户向XX服务发送写请求
    2.XX服务将数据更新到DB同时向MQ发送消息
    3.web服务接收到消息后,将数据写到本地缓存和Redis缓存中

    读取操作

    1.用户向web服务器发送读请求
    2.在web服务器缓存中命中则返回,否则向Redis缓存请求数据
    3.Redis缓存命中则返回数据
    4.web服务器接收到Redis缓存中的数据则返回,否则向web服务发起读请求
    5.web服务在堆缓存中查找数据,命中则返回并缓存到Redis缓存
    6.web服务在堆缓存中未命中数据,则向DB请求数据
    7.DB将数据返回给web服务
    8.web服务拿到数据后,将数据在堆缓存、Redis缓存中保存,并返回web服务器

    web服务器Nginx本地缓存主要存储热点数据,避免不必要的访问网络开销

    Redis分布式大规模缓存,对应的是海量离散数据

    web服务的堆缓存是为了避免Redis宕机,导致web服务器大量的请求涌入,打死DB(虽然效果甚微,总比没有要强)

    数据清除策略

    • 一种是对key设置存活时间(TTL),当访问的key超过存活时间,则返回null并删除本地数据

    • 另一种则是存储的数据量超过了最大设置量

    以下内容为第二种策略

    配置

    maxmemory 设置数据清除策略开始的大小
    maxmemory-policy 数据满是所执行的策略
    
    noeviction 拒绝写入
    allkeys-lru 所有key执行LRU
    volatile-lru 仅对设置了存活时间(TTL)的key执行LRU
    allkeys-random 随机删除key
    volatile-random 随机挑选设置了存活时间(TTL)的key删除
    volatile-ttl 移除TTL较短的key
    

    流程

    1.外部有写入请求
    2.检查是否超过maxmemory限制,是则执行maxmemory-policy策略清除部分数据
    3.执行写入操作

    常用策略:allkeys-lru

    Redis的LRU清除策略是近似的LRU算法,它通过采样采集数据进行处理而非全量数据,采样参数maxmemory-sample

    相关文章

      网友评论

          本文标题:Redis架构手记

          本文链接:https://www.haomeiwen.com/subject/unwslctx.html