Redis复制 replica
- 就是主从复制,master以写为主,slave以读为主,当主节点数据有变化时,自动同步到从节点。
- 可以实现 读写分离,容灾恢复,数据备份,水平扩展
- 配置实现 配从库不配主库 master配置了requirepass密码,需要密码登录,那么slave就要配置masterauth来设置校验密码,否则的话master会拒绝slave访问
- 基本操作命令
info replication #可以查看复制节点的主从关系和配置信息
replicaof #主库IP 主库端口 配置进conf文件
salveof #主库IP 主库端口,在运行期间修改同步关系
slaveof no one #使当前数据库停止与其他数据库同步,转成主数据库,自立为王
- 从机无法写入数据
- 首次启动,从节点会全量复制主节点数据,后续依次复制
- 主节点掉线后,从节点等待主节点恢复,从节点支持读数据
- 命令搭建的主从关系重启后丢失主从关系
- 上一个slave可以是下一个的master,slave可以接受其他slave的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻主master的写压力。中途变更转向会清除之前的数据,重新建立拷贝最新的。
- 同步工作流程
slave启动 同步初次请求
slave启动成功后连接到master后会发送一个sync命令,一次完全同步(全量复制)将被自动执行,slave自身原有的数据会被master的数据覆盖清除
首次连接 全量复制
master节点收到sync命令后会开始在后头保存rdb快照,同时收集所有接收到的用于修改的命令,将其缓存起来,master节点执行完rdb后master将rdb快照文件和所有缓存的命令发送到所有slave,以完成一次同步 slave在收到数据库文件后,将其存盘并加载到内存中,从而完成复制初始化
心跳持续 保持通信
repl-ping-replica-period 10,master节点会读取该配置,在指定周期内向所有slave发送心跳包,保持连接
进入平稳,增量复制
master继续将新的所收集到的写操作指令集,发送给slave
从机下线 重连续传
master会检查backlog里面的offset,master和slave都会保存一个复制的offset还有一个masterId,offset是保存在backlog中的,master只会把已经复制的offset后面的数据复制给slave,类似断点续传
- 复制的缺点
复制延时,信号衰减
由于所有的写操作都是发生在master,然后同步到slave,所以从master到slave之间有一定延时,当系统繁忙的时候,延迟问题会更加严重,slave机器数量的增加也会使这个问题更加严重master掉线 怎么办
默认情况下不会发生slave上位,集群半瘫痪状态,只能读取,不能写入,需要人工干预,这样就需要自动的主从替换逻辑。
Redis哨兵 sentinel
-
哨兵巡查监控后台master主机是否故障,如果故障了根据投票数自动将某一个从库转为主库,继续对外提供服务,实现Redis服务的无人值守运维。
-
Redis哨兵主要提供四种功能
主从监控
监控主从redis库运行是否正常
消息通知
哨兵可以将故障转移的结果发送给客户端
故障转移
如果master异常,则会进行主从切换,将其中一个slave作为新的master
配置中心
客户端通过连接哨兵来获取当前redis服务的主节点地址
-
broken pipe
认识broken pipe
pipe是管道的意思,管道里面是数据流,通常是文件或网络套接字读取的数据。当管道从另一端突然关闭时,会发生数据中断,即是broken,对于socket来说,可能是网络被拔出或另一端的进程崩溃。
解决问题
其实当该异常产生的时候,对于服务端来说,并没有多少影响。因为可能是某个客户端的进程突然中止,导致了该错误
总结broken
这个异常是客户端读取超时关闭了连接,这时候服务器端再向客户端已经断开的连接写数据时就发生了broken pipe 异常
-
SDOWM 主观不可用
所谓主观下线 ( subjectively down 简称sdown )指的是单个 sentinel 实例对服务器做出的下线判断,即单个sentinel认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。主观下线就是说如果服务器在 【sentinel down-after-millseconds】给定的毫秒之内没有回应ping命令,或者返回一个错误消息,那么这个sentinel会主观认为这个master不可用 -
ODOWN 客观不可用
quorum这个参数是进行客观下线的一个依据,法定人数/法定票数
意识是至少有quorum个sentinel认为这个master有故障才会对这个master进行下线以及故障转移。因为有的时候,某个sentinel几点可能因为自身网络原因导致无法连接master,而此时master并没有出现故障,所以这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。 -
哨兵选举
当主节点被判断客观下线后,各个哨兵节点会进行协商,先选举出一个领导者哨兵节点,并由该领导者节点进行failover故障迁移
使用raft算法进行领导者哨兵选举,基本思路就是先到先得 -
由领导者节点进行故障切换
新主登基
priority 选举权限高的节点 权限一样进行下一步判断 在redis.conf 文件中配置,数字越小优先级越高
replication offset 选举偏移量大的节点,偏移一样进行下一步判断
run id 根据run id 谁最小选谁群臣俯首
新主节点执行slaveof no one 命令让选出来的节点成为新的主节点,并通过slaveof命令让其他节点成为其从节点
sentinel leader 会让新主节点执行该命令
sentinel leader 让剩余的slave成为新master节点的slave旧主拜服
sentinel leader 会让原来的master降级成为slave 并恢复工作
Redis集群(cluster)
-
定义
由于数据量不断增加,单个master复制集难以承担,因此需要对多个复制集进行集群,形成水平扩展每个复制集只负责存储整个数据集的一部分,这就是Redis的集群,其作用是提供在多个Redis节点间共享数据的程序集,Redis集群是提供多个Redis节点间共享数据的程序集,Redis集群支持多个master -
作用
redis 集群支持多个master,每个master后可以挂载多个slave,支持读写分离,数据高可用,海量数据的读写存储操作
由于cluster自带sentinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能
客户端与redis的节点连接,不再需要连接集群中所有节点,只需要连接集群中的一个可用节点即可
槽位slot复则分配到各个物理服务节点,由对应的集群来复则维护节点,插槽和数据之间的关系 -
集群算法 分片 槽位slot
redis集群使用了哈希槽的概念,redis集群有16384个哈希槽,每个key通过crc16校验后对16384取模来决定放在哪个槽,集群的每个节点复则一部分hash槽
官网推荐主节点不要超过1000个
使用Redis集群的时候,我们会将存储的数据分散到多台redis机器上,这称为分片。简言之,集群中的每个redis实例都被认为是整个数据的分片。
最大的优势,方便扩容和缩容,由于从一个节点移动到另一个节点不需要停机,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群的不可用。
一致性哈希换,将0到2的32次方减一构造成一个圆环,这个环就是哈希环,当我们需要存储一个kv键值对的时候,首先计算key的hash值,将这个值落在哈希环上的某个位置,然后顺时针寻找遇到的第一个节点就是存储的节点。节点少的时候会发生数据倾斜问题。-
哈希槽
为了解决一致性hash算法的数据倾斜问题,哈希槽实质就是一个数据 2的14次方个元素
解决均匀分配问题,在数据和节点之间加入一层哈希槽,用于管理数据和节点之间的关系,现在相当于节点上放的是槽,槽里放的是数据
一个机器只能有16384个槽,编号0-16383这些槽会分配给机器中的所有主节点,集群会记录节点和槽位的关系,解决了节点和槽位的关系后,接下来就需要对key求hash值,然后对16384取模,余数就是槽位 -
为什么redis的集群槽数是16384个
redis集群会发送心跳信息包,如果槽位为65536消息包得8k,而16384只需要2k
redis的主节点不会超过1000个,16384个槽位够用
redis主节点配置信息中他所负责的哈希槽是通过一张bitmap存储的,在传输过程中会对bitmap进行压缩,如果bitmap的填充率slots/N bitmap的压缩率就很低,槽位越小节点少的情况下压缩比高,容易传输
-
-
创建集群
复制redis.conf 并修改相关配置,分别启动6个redis实例
使用集群创建命令创建集群
redis-cli -a xxx --cluster create – cluster-replicas 1 ip:port ip:port ip:port ip:port ip:port ip:port
`- -cluster-replicas 1 表示为每个master创建一个slave节点