1.哨兵与集群
1)、Redis 哨兵 着眼于高可用,在 master 宕机时会自动将 slave 提升为master,继续提供服务。 2)、Redis 集群(Cluster)着眼于扩展性,在单个 redis 内存不足时,使用 Cluster 进行分片存储。
2.集群的配置
根据官方推荐,集群部署至少要 3 台以上的master节点,最好使用 3 主 3 从六个节点的模式。
3.集群方案什么情况下会导致整个集群不可用?**
- 比如有 A,B,C 三个节点的集群
- 在没有复制模型的情况下,如果节点 B 失败了。
- 那么整个集群就会以为缺少 5501-11000 这个范围的槽而不可用。
4.故障检测**
- 集群中的每个节点都会定期地向及集群中的其他节点发送PING消息,以检测对方是否在线,
- 若在规定时间内没有返回PONG消息,
- 那么发送PING消息的节点就会将接收PING消息的节点标记为疑似下线(PFAIL)。
- 如果半数以上负责处理槽的主节点将某个节点X报告为疑似下线,那么这个主节点将被标记为已下线。
5.故障转移
转移过程
- 从节点中选中一个一个节点,执行SLAVEOF no one,称为新节点。
- 新节点撤销所有已下线主节点的槽指派,并将槽指派给自己
- 新的节点向集群广播一条PONG消息,告知其他节点自己的信息变更
- 新的节点开始接受和自己负责处理槽有关的命令请求
6.集群选举流程**
- 当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新的master。
- 由于挂掉的master可能会有多个slave,从而存在多个slave竞争成为master节点的过程, 其过程如下:
- slave发现自己的master变为FAIL
- 将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST信息
- 其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack
- 尝试failover的slave收集FAILOVER_AUTH_ACK
- 超过半数后变成新Master
- 广播Pong通知其他集群节点。
从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票
7.集群重新分片流程
指的是可以将已经指派的某个节点的槽指派给另外一个节点,同时键值跟随移动。
重新分片可以在线进行,由集群管理软件redis-trib负责向源节点和目标节点发送命令,Redis本身提供了重新分片的所有命令。
- 目标节点准备导入键值对
- 源节点准备迁移键值对
- 向源节点统计属于迁移槽的所有键值名
- 根据键值名向每个源节点都发送一个迁移的键值
- 迁移完成之后,将槽指派给目标节点。
8.什么是集群脑裂问题?**
- redis 集群会由于网络等原因出现脑裂的情况
- 由于redis master节点和redis salve节点和sentinel处于不同的网络分区,使得sentinel没有能够心跳感知到master,
- 所以通过选举的方式提升了一个salve为master,这样就存在了两个master,就像大脑分裂了一样,
- 这样会导致客户端还在old master那里写入数据,新节点无法同步数据,当网络恢复后,
- sentinel会将old master降为salve,这时再从新master同步数据,这会导致大量数据丢失。
9.Redis集群脑裂解决方案?
# 4.0 版本 之前配置
min-slaves-to-write 3
min-slaves-max-lag 10
# 5.0 版本 之后配置
min-replicas-to-write 3
min-replicas-max-lag 10
- 第一个参数表示最少的salve节点为3个。
- 第二个参数表示数据复制和同步的延迟不能超过10秒
配置了这两个参数:如果发生脑裂:原master会在客户端写入操作的时候拒绝请求。这样可以避免大量数据丢失
10.Redis集群最大节点个数是多少?
16384个桶(哈希槽)
11.哈希槽介绍
Redis集群(Cluster)并没有选用上面一致性哈希,而是采用了哈希槽(SLOT)的这种概念。主要的原因就是上面所说的,一致性哈希算法对于数据分布、节点位置的控制并不是很友好。
首先哈希槽其实是两个概念,第一个是哈希算法。Redis Cluster的hash算法不是简单的hash(),而是crc16算法,一种校验算法。
12.为什么集群的最大槽数是16384个?
在redis节点发送心跳包时需要把所有的槽放到这个心跳包里,以便让节点知道当前集群信息,16384=16k,在发送心跳包时使用char进行bitmap压缩后是2k(2 * 8 (8 bit) * 1024(1k) = 2K),也就是说使用2k的空间创建了16k的槽数。 虽然使用CRC16算法最多可以分配65535(2^16-1)个槽位,65535=65k,压缩后就是8k(8 * 8 (8 bit) * 1024(1k) = 8K),也就是说需要需要8k的心跳包,作者认为这样做不太值得;并且一般情况下一个redis集群不会有超过1000个master节点,所以16k的槽位是个比较合适的选择。
13.Redis集群的主从复制模型是怎样的?
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会N-1个复制品.
14.Redis集群会有写操作丢失吗?为什么?
Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。
15.Redis集群之间是如何复制的?
异步复制
16.Redis 集群如何选择数据库?
默认在 0 数据库,目前无法数据库选择,
|