Redis入门到实战(虎哥版)个人笔记-高级篇“分布式缓存”

一、单机redis存在的问题

1.数据安全问题,当redis宕机时会存在数据丢失问题:数据持久化

2.并发能力低,不能承载很大的并发量:主从集群

3.故障恢复问题:哨兵集群

4.存储能力问题,提高存储量:分片集群,利用散列插槽动态扩容

二、数据持久化

1.RDB持久化

RDB方式是利用了数据快照的方式,将内存中的所有数据读入到磁盘中,存放数据的文件为RDB文件。当redis重启后,会读取该RDB文件做数据恢复。

执行RDB的条件:

(1)关机自动执行;

(2)手动用save命令;

(3)手动用bgsave命令;

(4)通过配置执行条件,满足条件时触发;

bgsave的基本流程:

(1)fork主进程创建一个子进程,它们共享内存空间

(2)子进程读取内存数据写到新的RDB文件中

(3)将新的RDB文件替换旧的RDB文件

RDB方式的缺点:

(1)两次RDB操作间隔比较长,如果在这之间发生宕机,数据会丢失

(2)因为涉及到磁盘IO,再加上数据量可能也很大,都会导致RDB文件的写操作比较耗时

2.AOF持久化

AOF是追加文件。redis在每执行一个命令之后,就会把该命令写入到AOF文件中保存,也叫做命令日志文件。

AOF功能默认不开启,需要在配置文件中设置。写入AOF文件的频率也可配置,有三种:

文件重写:因为是记录命令,AOF文件会比RDB文件大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。

3.RDB和AOF的区别

两者结合,yyds

三、主从集群

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。

1.主从集群搭建(略)

2.主从同步原理

(1)全量同步

自己描述一遍:首先,slave携带自己的replid和offset向master请求建立连接,master根据发来replid和自己的replid比较来判断是不是第一次连接,如果不一样则代表第一次连接(返回master的id和offset),就做全量同步。然后通过bgsave命令将master的内存数据写入到一个RDB文件中,写入完成后将RDB文件发给slave做数据同步。在此期间master会有新的命令请求,master都会记录这些命令到baklog中,随后发给slave继续同步数据。

完整流程描述:

  • slave节点请求增量同步

  • master节点判断replid,发现不一致,拒绝增量同步

  • master将完整内存数据生成RDB,发送RDB到slave

  • slave清空本地数据,加载master的RDB

  • master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave

  • slave执行接收到的命令,保持与master之间的同步

(2)增量同步

全量同步需要先做RDB,然后将RDB文件通过网络传输个slave,成本太高了。因此除了第一次做全量同步,其它大多数时候slave与master都是做增量同步

增量同步就是就是只更新slave与master存在差异的部分数据。就是master收到slave发来的replid和offset后,判断是不是第一次,不是则提醒slave继续干活!然后master去baklog中获取offset后的命令数据,将这些命令发送给slave做同步

(3)repl-baklog原理

底层是一个类似于环形的数组,当写入的数据到末尾时会重新从头开始写。

总的来说,master和slave都有自己的偏移量,slave的偏移量永远不超过master的偏移量,当它们的偏移量不相等时,slave就要不断的做增量同步。如果数组写满了数据,后面新的数据就会覆盖数组前面的数据,只要被覆盖的部分slave已经同步过了就没事,如果slave没同步,那就要做全量同步。

(4)主从同步优化

  • 在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时的磁盘IO。

  • Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO

  • 适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步

  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力

(5)小结

简述全量同步和增量同步区别?

  • 全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在repl_baklog,逐个发送给slave。

  • 增量同步:slave提交自己的offset到master,master获取repl_baklog中从offset之后的命令给slave

什么时候执行全量同步?

  • slave节点第一次连接master节点时

  • slave节点断开时间太久,repl_baklog中的offset已经被覆盖时

什么时候执行增量同步?

  • slave节点断开又恢复,并且在repl_baklog中能找到offset时

四、哨兵集群

哨兵集群:解决自动故障恢复问题,就是出问题了,可以自己恢复正常

三大作用:

(1)监控:监控集群的健康状态

(2)自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主

(3)通知:通知客户端redis集群的变化

1.哨兵集群搭建(略)

2.哨兵原理

(1)集群监控原理

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:

主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线

客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

客观下线才被认为是出故障了。

(2)自动故障恢复原理

当检测到master出故障了,哨兵会选一个slave做master,流程如下:

        先看哪个slave和master断开的时间超过规定时间,超过就排除

        再看优先级,优先级越小越优先

        优先级一样,再看offset,offset越大代表未同步的数据的越少,数据越新

        最后看id,越小越优先

当选出一个新的master后,该如何实现切换呢?

流程如下:

  • sentinel给备选的slave1节点发送slaveof no one命令,让该节点成为master

  • sentinel给所有其它slave发送slaveof 192.168.150.101 7002 命令,让这些slave成为新master的从节点,开始从新的master上同步数据。

  • 最后,sentinel将故障节点标记为slave,当故障节点恢复后会自动成为新的master的slave节点

五、分片集群

分片集群解决问题:

  • 海量数据存储问题

  • 高并发写的问题

1.分片集群的特点

  • 集群中有多个master,每个master保存不同数据

  • 每个master都可以有多个slave节点

  • master之间通过ping监测彼此健康状态

  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

2.散列插槽

redis会将每个redis节点映射到0~16383共16384个插槽上。

数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:

  • key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分

  • key中不包含“{}”,整个key都是有效部分

3.小结

Redis如何判断某个key应该在哪个实例?

  • 将16384个插槽分配到不同的实例

  • 根据key的有效部分计算哈希值,对16384取余

  • 余数作为插槽,寻找插槽所在实例即可

如何将同一类数据固定的保存在同一个Redis实例?

  • 这一类数据使用相同的有效部分,例如key都以{typeId}为前缀

以上图片和部分文字均来自虎哥资料

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值