Redis
2021-08-02 17:43:20 0 举报
AI智能生成
redis知识点
作者其他创作
大纲/内容
Redis持久化
RDB
优点
1、RDB生产多个数据文件,每个文件都代表了某一时刻redis的数据
2、redis生成快照时会fork出子进程,对redis本身对外提供的服务影响非常小,可以让redis一直保持在高可用状态
3、相对于AOF来说,使用RDB来重启和恢复文件非常快速
缺点
1、redis子生成快照文件时,是每隔几分钟生成一次,这个时候就会出现,一旦redis宕机,将会丢失近几分钟的数据
2、redis在fork出子进程时,如果文件过大,将会导致redis客户端暂停数秒,所以不要让RDB的时间间隔太长
配置
save 60 1000 : 每隔60s,如果有超过1000个key发生了变更,那么就生成一个新的dump.rdb文件,就是当前redis内存中完整的数据快照,这个操作也被称之为snapshotting,快照。也可以手动调用save或者bgsave命令,同步或异步执行rdb快照生成,save可以设置多个,就是多个snapshotting检查点,每到一个检查点,就会去check一下,是否有指定的key数量发生了变更,如果有,就生成一个新的dump.rdb文件
AOF
工作流程
1、fork出一个子进程
2、子进程将数据存到rdb文件中
3、完成rdb快照之后,替换原有快照文件
优点
1、每隔1秒,通过后台线程执行sync操作
2、AOF日志文件以append-only模式写入,没有任何磁盘寻址的开销,写入性能比较高,而且文件不容易破损,即使文件尾部破损,也很容易修
3、AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写,因为在rewrite log的时候,会对其中的指令进行压缩,创建出一份需要恢复数据的最小日志出来。再创建新日志文件的时候,老的日志文件还是照常写入。当新的merge后的日志文件ready的时候,再交换新老日志文件即可
4、适合做灾难性的误删除紧急恢复,AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据;
缺点
1、对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大,恢复速度慢
2、AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的
配置
1.AOF持久化,默认是关闭的,默认是打开RDB持久化,appendonly yes,可以打开AOF持久化机制,在生产环境里面,一般来说AOF都是要打开的,除非你说随便丢个几分钟的数据也无所谓,打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下
工作流程
1、redis fork一个子进程
2、子进程基于当前内存中的数据,构建日志,开始往一个新的临时的AOF文件中写入日志
3、redis主进程,接收到client新的写操作之后,在内存中写入日志,同时新的日志也继续写入旧的AOF文件
4、子进程写完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中
5、用新的日志文件替换掉旧的日志文件
2、子进程基于当前内存中的数据,构建日志,开始往一个新的临时的AOF文件中写入日志
3、redis主进程,接收到client新的写操作之后,在内存中写入日志,同时新的日志也继续写入旧的AOF文件
4、子进程写完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中
5、用新的日志文件替换掉旧的日志文件
RDB与AOF
区别
RDB可以做冷备,生成多个文件,每个文件都代表了某一个时刻的完整的数据快照
AOF可以做冷备,只有一个文件,但是你可以,每隔一定时间,去copy一份这个文件出来
AOF可以做冷备,只有一个文件,但是你可以,每隔一定时间,去copy一份这个文件出来
RDB,每次写,都是直接写redis内存,只是在一定的时候,才会将数据写入磁盘中
AOF,每次都是要写文件的,虽然可以快速写入os cache中,但是还是有一定的时间开销的,速度肯定比RDB略慢一些
AOF,每次都是要写文件的,虽然可以快速写入os cache中,但是还是有一定的时间开销的,速度肯定比RDB略慢一些
AOF,存放的指令日志,做数据恢复的时候,其实是要回放和执行所有的指令日志,来恢复出来内存中的所有数据的
RDB,就是一份数据文件,恢复的时候,直接加载到内存中即可
RDB,就是一份数据文件,恢复的时候,直接加载到内存中即可
工作时
如果RDB在执行snapshotting操作,那么redis不会执行AOF rewrite; 如果redis再执行AOF rewrite,那么就不会执行RDB snapshotting
3同时有RDB snapshot文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整
如果RDB在执行snapshotting,此时用户执行BGREWRITEAOF命令,那么等RDB快照生成之后,才会去执行AOF rewrite
回收算法
(1)noeviction: 如果内存使用达到了maxmemory,client还要继续写入数据,那么就直接报错给客户端
(2)allkeys-lru: 就是我们常说的LRU算法,移除掉最近最少使用的那些keys对应的数据
(3)volatile-lru: 也是采取LRU算法,但是仅仅针对那些设置了指定存活时间(TTL)的key才会清理掉
(4)allkeys-random: 随机选择一些key来删除掉
(5)volatile-random: 随机选择一些设置了TTL的key来删除掉
(6)volatile-ttl: 移除掉部分keys,选择那些TTL时间比较短的keys
集群
哨兵模式
主要功能
集群监控,负责监控redis master和slave进程是否正常工作
消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
故障转移,如果master node挂掉了,会自动转移到slave node上
配置中心,如果故障转移发生了,通知client客户端新的master地址
分布式
故障转移时,判断一个master node是宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题
即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很坑爹了
核心知识
哨兵至少需要3个实例,来保证自己的健壮性
哨兵 + redis主从的部署架构,是不会保证数据零丢失的,只能保证redis集群的高可用性
对于哨兵 + redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练
数据丢失
异步复制
因为master -> slave的复制是异步的,所以可能有部分数据还没复制到slave,master就宕机了,此时这些部分数据就丢失了
脑裂
某个master所在机器突然脱离了正常的网络,跟其他slave机器不能连接,但是实际上master还运行着 此时哨兵可能就会认为master宕机了,然后开启选举,将其他slave切换成了master 这个时候,集群里就会有两个master,也就是所谓的脑裂 此时虽然某个slave被切换成了master,但是可能client还没来得及切换到新的master,还继续写向旧master的数据可能也丢失了 因此旧master再次恢复的时候,会被作为一个slave挂到新的master上去,自己的数据会清空,重新从新的master复制数据
解决
min-slaves-to-write 1
min-slaves-max-lag 10
要求至少有1个slave,数据复制和同步的延迟不能超过10秒 如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,
master就不会再接收任何请求了 上面两个配置可以减少异步复制和脑裂导致的数据丢失
min-slaves-max-lag 10
要求至少有1个slave,数据复制和同步的延迟不能超过10秒 如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,
master就不会再接收任何请求了 上面两个配置可以减少异步复制和脑裂导致的数据丢失
减少异步复制的数据丢失 有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延时太长,就认为可能master宕机后损失的数据太多了,那么就拒绝写请求,这样可以把master宕机时由于部分数据未同步到slave导致的数据丢失降低的可控范围内
减少脑裂的数据丢失 如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求 这样脑裂后的旧master就不会接受client的新数据,也就避免了数据丢失 上面的配置就确保了,如果跟任何一个slave丢了连接,在10秒后发现没有slave给自己ack,那么就拒绝新的写请求 因此在脑裂场景下,最多就丢失10秒的数据
底层原理
sdown和odown 两种失败状态转换机制
sdown是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机 sdown达成的条件很简单,
如果一个哨兵ping一个master,超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机
如果一个哨兵ping一个master,超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机
odown是客观宕机,如果quorum数量的哨兵都觉得一个master宕机了,那么就是客观宕机 sdown到odown转换的条件很简单,如果一个哨兵在指定时间内,收到了quorum指定数量的其他哨兵也认为那个master是sdown了,那么就认为是odown了,客观认为master宕机
哨兵集群的自动发现机制
哨兵互相之间的发现,是通过redis的pub/sub系统实现的,每个哨兵都会往__sentinel__:hello这个channel里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在 每隔两秒钟,每个哨兵都会往自己监控的某个master+slaves对应的__sentinel__:hello channel里发送一个消息,内容是自己的host、ip和runid还有对这个master的监控配置 每个哨兵也会去监听自己监控的每个master+slaves对应的__sentinel__:hello channel,然后去感知到同样在监听这个master+slaves的其他哨兵的存在 每个哨兵还会跟其他哨兵交换对master的监控配置,互相进行监控配置的同步
slave->master选举算法
如果一个master被认为odown了,而且majority哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个slave来,会考虑slave的一些信息: (1)跟master断开连接的时长 (2)slave优先级 (3)复制offset (4)run id
如果一个slave跟master断开连接已经超过了down-after-milliseconds的10倍,外加master宕机的时长,那么slave就被认为不适合选举为master (down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state
接下来会对slave进行排序 (1)按照slave优先级进行排序,slave priority越低,优先级就越高 (2)如果slave priority相同,那么看replica offset,哪个slave复制了越多的数据,offset越靠后,优先级就越高 (3)如果上面两个条件都相同,那么选择一个run id比较小的那个slave
瓶颈
如果你的数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就几个G,单机足够了 replication,一个mater,多个slave,要几个slave跟你的要求的读吞吐量有关系,然后自己搭建一个sentinal集群,去保证redis主从架构的高可用性,就可以了
主从核心机制
(1)redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量
(2)一个master node是可以配置多个slave node的
(3)slave node也可以连接其他的slave node
(4)slave node做复制的时候,是不会block master node的正常工作的
(5)slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了
(6)slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量
(2)一个master node是可以配置多个slave node的
(3)slave node也可以连接其他的slave node
(4)slave node做复制的时候,是不会block master node的正常工作的
(5)slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了
(6)slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量
0 条评论
下一页
为你推荐
查看更多