Redis架构手记

2021-05-02  本文已影响0人  s1991721

目录

1、Redis持久化

2、Redis读写分离架构

3、Redis集群架构

4、缓存架构

5、数据清除策略


Redis持久化

持久化策略共提供了两种

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流程:

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。

注意事项

复制流程

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系统实现

功能

工作流程

哨兵有两种失败状态,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的内存容量,在海量数据场景下会产生瓶颈,因此在海量数据场景下适用集群架构

数据的负载均衡算法

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(虽然效果甚微,总比没有要强)

数据清除策略

以下内容为第二种策略

配置

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

上一篇 下一篇

猜你喜欢

热点阅读