4. 高可用
一、主从
Redis 提供了主从库模式,以保证数据副本的一致,主从库之间采用的是读写分离的方式。
redis读写分离:
- 读操作:主库、从库都可以接收;
- 写操作:首先到主库执行,然后,主库将写操作同步给从库
1.1 建立主从关系
replicaof <主节点地址> <从节点地址>
1.2 全量复制
全量复制一般发生在第一次主从同步数据时。第一次主从同步分为三个阶段:
- 第一阶段是建立链接、协商同步
- 第二阶段是主服务器同步数据给从服务器,传输的是rdb文件(全量复制)
- 第三阶段是主服务器发送新写操作命令给从服务器(命令传播)
1.3 命令传播
在完成全量复制之后,双方之间就会维护一个 TCP 连接。主节点会将命令同步给从节点去执行,去保证双方数据一致性。
1.2 增量复制
如果主从之间断开后,又重连了,中间这段时间本该使用命令传播同步的数据该怎么办呢?
- Redis 2.8 之前,会重新全量复制一次。。。
- Redis 2.8 开始,主节点会把中间这段时间的命令存储起来,等连接恢复后,发送给从节点
二、哨兵
哨兵机制是实现主从库自动切换的关键机制,它有效地解决了主从复制模式下故障转移的问题
Redis Sentinel,即Redis哨兵,在Redis 2.8版本开始引入。哨兵的核心功能是主节点的自动故障转移。
2.1 哨兵机制
哨兵是一个redis进程,但其比较不负责数据读写,只负责监控主从节点、选举主节点
2.1.1 哨兵判断主节点故障
哨兵会每隔 1 秒给主从节点发送 PING 命令,当主从节点收到 PING 命令后,会发送一个响应命令给哨兵,这样就可以判断它们是否在正常运行。
当主节点没有在规定时间(down-after-milliseconds)内应答,哨兵就会将它们标记为主观下线。
当一个哨兵判断主节点为主观下线后,就会向哨兵集群中的其他哨兵发起命令,其他哨兵收到这个命令后,就会根据自身和主节点的网络状况,做出赞成投票或者拒绝投票的响应。当赞同票数quorum值后,这个主节点就会被客观下线。
为了减少误判,通常情况下会有多个哨兵组成一个哨兵集群,由哨兵集群投票判断 quorum 的值一般设置为哨兵个数的二分之一加1,例如 3 个哨兵就设置 2。
2.2 主从故障转移
前面说过,为了更加“客观”的判断主节点故障了,一般不会只由单个哨兵的检测结果来判断,而是多个哨兵一起判断,这样可以减少误判概率,所以哨兵是以哨兵集群的方式存在的。
问题来了,由哨兵集群中的哪个节点进行主从故障转移呢?
这个时候就需要在哨兵集群中选取一个leader,让leader主持主从切换。
2.2.1 主从切换流程
- 在已下线主节点(旧主节点)属下的所有「从节点」里面,挑选出一个从节点,并将其转换为主节点。
- 让已下线主节点属下的所有「从节点」修改复制目标,修改为复制「新主节点」;
- 将新主节点的 IP 地址和信息,通过「发布者/订阅者机制」通知给客户端;
- 继续监视旧主节点,当这个旧主节点重新上线时,将它设置为新主节点的从节点
2.3 哨兵集群
sentinel monitor <主节点名字> <主节点ip> <主节点端口> <quorum>
三、集群
Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施。
3.1 哈希槽
Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现。
一个 Redis 集群包含 16384 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
集群中的每个节点负责处理一部分哈希槽。 举个例子, 一个集群可以有三个哈希槽, 其中:
- 节点 A 负责处理 0 号至 5500 号哈希槽
- 节点 B 负责处理 5501 号至 11000 号哈希槽
- 节点 C 负责处理 11001 号至 16384 号哈希槽
3.2 主从复制
为了避免因为某个节点挂掉导致的数据丢失,每个从节点都有1~n个副本节点。
与前面提到的主从结构不一样的是,集群下的从节点不提供服务,节点之间相互通信,相互选举,不再依赖sentinel。
。。。。。。有些复杂,待续