Redis Cluster集群方式

Posted by KANG's BLOG on Tuesday, March 15, 2022

1 部署方式

至少为3主3从,以保证可靠性,比如下面这种部署架构:

preview

2 如何负载均衡

cluster采用hash槽方式进行key和redis实例的匹配,共2^14个槽,即16384个槽。

集群中,每个redis主节点都负责一部分槽,从节点仅冷备作用。

当redis设置值时,槽公式如下:

slot = CRC16(key) & 16383

每个节点和槽的映射关系手动配置,如:

redis节点 负责的槽位
节点1 0-5461
节点2 5462-10922
节点3 10923-16383

增删节点,都要将槽重新分配,比如新增节点4,那么可以将节点3的一部分槽分给节点4,分配后映射关系如下:

redis节点 负责的槽位
节点1 0-5461
节点2 5462-10922
节点3 10923-13680
节点4 13681-16383

3 如何判定节点下线

集群中的每个节点都会定期向其他节点发送ping命令,如果接受ping消息的节点在指定时间内没有回复pong,则发送ping的节点就把接受ping的节点标记为主观下线

如果集群半数以上的主节点都将主节点A标记为主观下线,则节点A将被标记为客观下线(通过节点的广播)即下线。

4 Redis回收进程如何工作的?

一个客户端运行了新的命令,添加了新的数据。

Redis检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收。

5 Redis回收使用的是什么算法?

5.1 引用计数算法

对于创建的每一个对象都有一个与之关联的计数器,垃圾回收时,计数器为0的对象将被回收,并将该对象引用的其他对象的计数器减一。

5.2 LRU算法

最近最少使用(Least Recently Used)算法,redis的LRU就是随机取出5个key(在配置文件中可以通过maxmemory-samples的值来设置redis需要检查key的个数),然后按照访问时间排序后,淘汰掉最不经常使用的那个

6 Redis有哪些适合的场景?

  1. Session共享(单点登录)
  2. 页面缓存
  3. 队列
  4. 排行榜/计数器
  5. 发布/订阅

7 Redis如何做内存优化?

尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面.

8 Redis集群最大节点个数是多少?

Redis集群预分好16384个桶(哈希槽:2^14 = 16384)

为什么是16384个桶而不是65535(2^16)呢?

官方解答

The reason is:

  1. Normal heartbeat packets carry the full configuration of a node, that can be replaced in an idempotent way with the old in order to update an old config. This means they contain the slots configuration for a node, in raw form, that uses 2k of space with16k slots, but would use a prohibitive 8k of space using 65k slots.
  2. At the same time it is unlikely that Redis Cluster would scale to more than 1000 mater nodes because of other design tradeoffs.

So 16k was in the right range to ensure enough slots per master with a max of 1000 maters, but a small enough number to propagate the slot configuration as a raw bitmap easily. Note that in small clusters the bitmap would be hard to compress because when N is small the bitmap would have slots/N bits set that is a large percentage of bits set.

首先,16k的桶,压缩成bitmap是2k的数据大小(2 * 8 (8 bit) * 1024(1k) = 16K),65k的桶是8k的数据大小(8 * 8 (8 bit) * 1024(1k) =65K)。

redis心跳每次都会携带所有槽的信息,且通常redis集群下不会超过1000个节点,所以65535相对没那么有必要。

所以16384是一个相对平衡的值。