三大集群各有什么优缺点?
- 主从:
-
- 优点读写分离。
- 缺点不能自动故障切换主节点。
- 哨兵:
-
- 优点,解决了主从集群不能自动故障切换的痛点,完成自动选主过程。
- 缺点:不能横向扩展,只有一个主节点,内存缓存容量有瓶颈。
- 分片:
-
- 优点:数据横向扩展。缓解内存压力。缓解并发写的压力。
- 缺点:去中心化。
单个Redis节点有什么问题?
- 存在单点故障问题(对应主从集群解决)
- 存在容量有限问题,存在高并发写问题。(对应分片集群解决)
主从集群
参考
高级篇-分布式缓存-08-Redis主从-主从的全量同步原理_哔哩哔哩_bilibili
zhuanlan.zhihu.com/p/675942562(redis集群)
全量同步----命令传播-----增量同步
主从同步 之 全量同步(三步)
高级篇-分布式缓存-08-Redis主从-主从的全量同步原理_哔哩哔哩_bilibili
- slave第一次请求增量同步,master根据repli_id判断不一致,拒绝增量同步;准备全量同步。
- master执行bgsave(后台子进程)生成RDB文件,并发送给slave,slave加载RDB进行同步。
- master将RDB期间的命令,写在replication buffer中,RDB结束后将replication buffer中的命令发送给slave,完成全量同步的所有步骤。
注意第三阶段,是将RDB期间的命令写入replication buffer中,不是repli_baklog中,master会为每个slave配置一个replication buffer,而repli_baklog全局只有一个。
主从同步之 命令传播(长连接)
主从服务器在完成第一次同步后,双方之间就会维护一个 TCP 连接。
后续主服务器可以通过这个连接继续将写操作命令传播给从服务器,然后从服务器执行该命令,使得与主服务器的数据库状态相同。
主从同步之 增量同步(差不多两步)
高级篇-分布式缓存-09-Redis主从-增量同步原理_哔哩哔哩_bilibili
主从服务器在完成第一次同步后,就会基于长连接进行命令传播。
可是,网络总是不按套路出牌的嘛,说延迟就延迟,说断开就断开。所以从节点重启后会进行增量同步。
- slave重启后,发起psync同步命令,提交自己的offset给master。
- matser去repli_baklog中获取 从节点offset之后的命令,发送给slave节点(从repli_baklog)。
repl_backlog_buffer 缓冲区是什么时候写入的呢?
repl_backlog_buffer是一个环形缓冲区
在命令写入之后,就会记录。
在主服务器进行命令传播时,不仅会将写命令发送给从服务器,还会将写命令写入到 repl_backlog_buffer 缓冲区里,因此 这个缓冲区里会保存着最近传播的写命令。
repl_backlog_buffer 和 replication_buffer有什么区别?
repl_backlog_buffer
- master只要一个这个buffer
- 增量同步的时候用
replication_buffer
- master为每个从节点都设置一个replication_buffer
- 增量同步和全量同步时都有用到
什么时候会进行全量同步?
- 第一次主从连接。
- 从节点断开太久,导致repli_baclog中offset被覆盖了。
什么时候执行增量同步?
从节点重启之后 且从节点的offset在repli_baclog中没有被覆盖。
从节点太多,导致主从同步压力太大怎么办?
为什么会主从复制压力大呢?因为这样主节点要给没一个从节点都进行 全量或增量同步。
采用 主-从-从,分摊主节点压力。
主从是短连接还是长连接?
长连接
分片集群
高级篇-分布式缓存-15-Redis分片集群-集群伸缩_哔哩哔哩_bilibili
字节喜欢问
为什么要分片集群?
- 缓存数据量太大的情况下需要,单机redis不够 (需要横向扩展)
- 并发 或者 并发写的量太大。主从无法缓解并发写的压力。 (缓解写压力)
所以需要横向扩展。
优点
- 横向扩展 缓解写压力 和 存储压力,支持动态扩容缩容。
- 同时具备主从复制、故障转移功能。
集群如何分片?
如何确定key分配的槽?(crc16校验码然后取模,得到槽位)
注重理解,关键信息:16384个哈希槽,平均分配到节点,每个key对应槽,每个key计算CRC16校验码 然后 对16384取模,就是这个key对应的哈希槽。
优点:解耦了数据和节点之间的关系(加了一层哈希槽),提升集群扩展性容错性。
扩展: 使用哈希槽 比 一致性哈希有什么优点?9.4 什么是一致性哈希?
- 一致性哈希算法并不保证节点能够在哈希环上分布均匀,这样就会带来一个问题,会有大量的请求集中在一个节点上。使用哈希槽没有这个问题,key可以均匀的分布在哈希槽上,而哈希槽是均匀分布在节点上的。
- 哈希槽可以手动分配槽位给节点。比如哪个节点多哪个节点少都可以手动决定,而一致性哈希没有那么灵活。
- 扩容缩容的时候更灵活,比如一致性哈希缩容导致下线节点的数据全部给到下一个节点。
总结:比一致性哈希更均匀。更加灵活,手动分配。
那一致性哈希引入虚拟节点 也可以解决数据倾斜(分布不均匀)的问题,哈希槽有什么优势?
虽然可以引入虚拟节点。但是还是没有哈希槽灵活,哈希槽可以手动分片槽位给节点。
什么是一致性哈希,解决什么问题?缺点是什么?
解决普通哈希 扩容缩容时 移动太多元素的问题。
但是一致性哈希也有数据倾斜的问题。
Redis Cluster 扩容缩容期间可以提供服务吗?
也就是迁移哈希槽的时候 可以提供服务吗?
可以提供服务。
Redis Cluster 中的节点是怎么进行通信的?
因为redis去中心化,所有没有注册中心,通过Gossip 协议进行通信。
很形象啊,Gossip翻译过来就是“流言蜚语”。
简单来说就是 新节点加入进来后,假如A知道了,A会告诉B,B又告诉C和D这样,最后一传十十传百就都知道了。
Redis分片集群如何实现故障转移?
虽然分片集群没有哨兵,但是各个节点之间互相进行心跳监控(gossip?),如果某个节点挂了其他节点也能感知,并完成主从切换。
Redis 分片集群的缺点?
去中心化,节点不能过多。
不然会造成难以管理监控,以及节点之间通信的问题。
Redis节点是不是越多越好?
不是(两点,元数据大小,通信的延迟性)
- 因为redis集群是去中心化。因此节点总是全量存储整个集群的信息(槽位及节点信息),节点越多占用 元数据占用空间更多。
- 去中心化很难清晰的掌握整个集群的状态,节点状态变化的延迟性也会带来极大的管理成本,就是说节点变化具有延迟性(某个节点挂了,需要让所有节点都知道具有一定延迟)
Redis的核心数是越多越好吗?
- 核心数不是 。因为只有主线程执行命令,其他的线程要么执行网络IO读写,要么是子进程进行RDB或aof重写。腾讯云那边建议是给redis分配两个核心。
分片集群key是如何路由的,就是key怎么知道我访问哪个节点哪个槽位?
默认情况下,当你操作一个 Key 的时候,你可以直接将请求打到集群中任意一个节点上,然后:
- Redis 实例将会根据 CRC16 算法计算出一个值,再对 16384 取模,从而得到该 Key 要落到的槽位;
- 若 Key 恰好落在当前节点拥有的槽位上,那就直接执行命令;
- 否则就检查拥有槽位的节点是否存在,如果存在,则它会返回一个 MOVED 响应,告知客户端应该访问哪一个节点;
- 接着,客户端将会根据(如果支持的话)MOVED 重定向命令将请求重定向到正确的 Redis 节点。
总结:随便访问一个节点,计算key之后得到槽位,如果槽位不在本节点则重定向(因为节点之间是通信的)
为什么哈希槽是16384?
Redis节点之间通信采用ping/pong心跳包,哈希槽信息会随着心跳包一起发送,(16384/8bit)占用2K,是个合适的大小。
如果是65536/8 = 8K,太大了。
哨兵集群
为什么要有哨兵?
自动完成 故障发现 和 主从切换。
主节点挂了 ,从节点是无法自动升级为主节点的,这个过程需要人工处理,在此期间 Redis 无法对外提供写操作。
此时,Redis 哨兵机制就登场了,哨兵在发现主节点出现故障时,由哨兵自动完成故障发现和故障转移,并通知给应用方,从而实现高可用性。
哨兵集群的 监控、选主以及切换 流程
1、服务状态监控
- 通过心跳机制,每秒发ping命令进行监控。
- 主观下线和客观下线
2、选举master规则
- 首先判断slave和master的断开时间,排除断开时间太长的slave。
- 判断slave的slave-priority优先级。
- 优先级一样,判断offset的值。
- offset一样,判断运行redis运行id。
3、进行切换,故障转移
- 给选举出来的节点发送 slaveof no one,成为master
- 给其他节点发送,slaveof ip:port(新master的)
- 修改故障节点的配置文件slaveof ip:port
Redis哨兵模式下的脑裂问题了解吗?如何解决?(阿里)
Redis脑裂就是主库假故障(通常可能是网络引起的),导致哨兵把原主库判断为客观下线,然后哨兵进行主从切换(在这期间原主库好了继续接收客户端请求),最后切换完成有了两个主库。
切换之后,哨兵对原主库执行slava of命令,全量同步新主库的数据,导致客户端写入原主库的数据丢失。
如何解决脑裂?
- Redis自身解决方案:通过minslaves-to-write 和 min-slaves-max-lag解决。
- 其他方案,RocketMQ中的Dleger集群,通过时间片分配,没有永远的主。(但是缺点就是选举阶段太频繁, 每次时间片走完都要选举)