redis 分片集群概念
Redis分片集群将数据划分为 16384 (2^14)个槽位(哈希槽),每个Redis服务节点分配了一部分槽位,因为槽位的信息存储于每个节点中,客户端请求的key通过CRC16校验后对16384取模来决定放置哪个槽,这样也就定位到指定的节点中。
注: 每个节点都会记录哪些槽分配给了自己,哪些槽被分配给了其他节点
分片集群运维
增加节点
新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot(槽)到D上,会变成这样:
此时服务A、B、C、D通过分配各自有了对应的哈希槽,新增节点后集群会自动进行哈希槽的重新平均分配,比如上图中四个节点中每个节点的槽位数是:18384 / 4 = 4096。
当然这个你使用命令 【cluster addslots】为每个节点自定义分配槽的数量,这里有个特点,如果我们节点的机器性能有差异,那就可以为性能好的,配置更多槽位,更好的利用机器性能。
减少节点
如果减少一个节点C,redis cluster同样会自动进行槽数量的重新计算分配。整体流程就是将节点C上的slot 搬迁到节点A、B上
客户端访问节点数据
Redis cluster的主节点各自负责一部分槽,我们来看下来自客户端的请求的key是如何定位到具体的节点,然后返回对应的数据的。
来自Redis-Cli客户端的请求连接到的是集群中的任何一个节点
-
首先检查当前key是否存在集群中的节点。
-
在该节点的话就直接就直接返回key对应的结果
-
不在该节点的话,那么会 MOVED重定向(包含槽位和目标地址)指引客户端转向至正确的节点,并再次发送之前执行的命令
一致性哈希算法
cloud.tencent.com/developer/a…
为什么需要一致性hash算法
我们先看下如果不使用一致性hash算法,则k-v键值对是怎么样存储的
假设一开始系统中只有3个节点,则通过hash(key) % 节点个数 可以计算出 某个key 需要路由到那个redis 节点。
比如
-
key1 -> 节点1
-
key2 - > 节点2
-
key3 -> 节点3
-
key4 -> 节点1
-
key5 -> 节点2
-
key6 -> 节点3
-
key7 -> 节点1
-
key8-> 节点2
如果新增节点4,则key的路由规则将发生变化
-
key1 -> 节点1
-
key2 - > 节点2
-
key3 -> 节点3
-
key4 -> 节点4
-
key5 -> 节点1
-
key6 -> 节点2
-
key7 ->节点3
-
key8 -> 节点4
可以看到,从key4开始,所有的key的路由规则都发生了变化,因此每个节点都需要移动大量的数据。
一致性hash 如何解决这个问题
我们可以把一致哈希算法是对 2^32 进行取模运算的结果值虚拟成一个圆环,环上的刻度对应一个 0~2^32 - 1 之间。我们将节点id 进行hash 运算放入下面环中,一般我们会根据服务器的IP或者唯一别名进行哈希计算。
数据如何映射:同样key值经过哈希之后,结果映射到哈希环上,然后将结果值按顺时针方向找到离自己最近的节点上,将value存储到那个节点上。
不平衡问题:引入虚拟节点。多个虚拟节点映射一个实际节点,因为在哈希环上节点越多就分布的越均匀,即使我们现实中不会有那么多真实节点。
假设节点A被删除,那么原来落到节点A的数据需要落到节点B。因此只有B受到影响,其他节点不会受到影响。
假设在A、B之间增加节点D,那么原来落到B的部分数据将落到节点D,因此只有B受到影响,其他节点不会受到影响。
为什么Redis是使用哈希槽而不是一致性哈希呢?
-
当发生扩容时候,Redis可配置映射表的方式让哈希槽更灵活,可更方便组织映射到新增server上面的slot数,比一致性hash的算法更灵活方便。
-
在数据迁移时,一致性hash 需要重新计算key在新增节点的数据,然后迁移这部分数据,哈希槽则直接将一个slot对应的数据全部迁移,实现更简单。
-
可以灵活的分配槽位,比如性能更好的节点分配更多槽位,性能相对较差的节点可以分配较少的槽位。
为什么Redis Cluster哈希槽数量是16384?
-
Redis节点间通信时,心跳包会携带节点的所有槽信息,它能以幂等方式来更新配置。如果采用 16384 个插槽,占空间 2KB (16384/8);如果采用 65536 个插槽,占空间 8KB (65536/8)。
-
Redis Cluster 不太可能扩展到超过 1000 个主节点,太多可能导致网络拥堵。
-
16384 个插槽范围比较合适,当集群扩展到1000个节点时,也能确保每个master节点有足够的插槽
参考资料
cloud.tencent.com/developer/a…
redis 分片集群概念
Redis分片集群将数据划分为 16384 (2^14)个槽位(哈希槽),每个Redis服务节点分配了一部分槽位,因为槽位的信息存储于每个节点中,客户端请求的key通过CRC16校验后对16384取模来决定放置哪个槽,这样也就定位到指定的节点中。
注: 每个节点都会记录哪些槽分配给了自己,哪些槽被分配给了其他节点
分片集群运维
增加节点
新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot(槽)到D上,会变成这样:
此时服务A、B、C、D通过分配各自有了对应的哈希槽,新增节点后集群会自动进行哈希槽的重新平均分配,比如上图中四个节点中每个节点的槽位数是:18384 / 4 = 4096。
当然这个你使用命令 【cluster addslots】为每个节点自定义分配槽的数量,这里有个特点,如果我们节点的机器性能有差异,那就可以为性能好的,配置更多槽位,更好的利用机器性能。
减少节点
如果减少一个节点C,redis cluster同样会自动进行槽数量的重新计算分配。整体流程就是将节点C上的slot 搬迁到节点A、B上
客户端访问节点数据
Redis cluster的主节点各自负责一部分槽,我们来看下来自客户端的请求的key是如何定位到具体的节点,然后返回对应的数据的。
来自Redis-Cli客户端的请求连接到的是集群中的任何一个节点
-
首先检查当前key是否存在集群中的节点。
-
在该节点的话就直接就直接返回key对应的结果
-
不在该节点的话,那么会 MOVED重定向(包含槽位和目标地址)指引客户端转向至正确的节点,并再次发送之前执行的命令
一致性哈希算法
cloud.tencent.com/developer/a…
为什么需要一致性hash算法
我们先看下如果不使用一致性hash算法,则k-v键值对是怎么样存储的
假设一开始系统中只有3个节点,则通过hash(key) % 节点个数 可以计算出 某个key 需要路由到那个redis 节点。
比如
-
key1 -> 节点1
-
key2 - > 节点2
-
key3 -> 节点3
-
key4 -> 节点1
-
key5 -> 节点2
-
key6 -> 节点3
-
key7 -> 节点1
-
key8-> 节点2
如果新增节点4,则key的路由规则将发生变化
-
key1 -> 节点1
-
key2 - > 节点2
-
key3 -> 节点3
-
key4 -> 节点4
-
key5 -> 节点1
-
key6 -> 节点2
-
key7 ->节点3
-
key8 -> 节点4
可以看到,从key4开始,所有的key的路由规则都发生了变化,因此每个节点都需要移动大量的数据。
一致性hash 如何解决这个问题
我们可以把一致哈希算法是对 2^32 进行取模运算的结果值虚拟成一个圆环,环上的刻度对应一个 0~2^32 - 1 之间。我们将节点id 进行hash 运算放入下面环中,一般我们会根据服务器的IP或者唯一别名进行哈希计算。
数据如何映射:同样key值经过哈希之后,结果映射到哈希环上,然后将结果值按顺时针方向找到离自己最近的节点上,将value存储到那个节点上。
不平衡问题:引入虚拟节点。多个虚拟节点映射一个实际节点,因为在哈希环上节点越多就分布的越均匀,即使我们现实中不会有那么多真实节点。
假设节点A被删除,那么原来落到节点A的数据需要落到节点B。因此只有B受到影响,其他节点不会受到影响。
假设在A、B之间增加节点D,那么原来落到B的部分数据将落到节点D,因此只有B受到影响,其他节点不会受到影响。
为什么Redis是使用哈希槽而不是一致性哈希呢?
-
当发生扩容时候,Redis可配置映射表的方式让哈希槽更灵活,可更方便组织映射到新增server上面的slot数,比一致性hash的算法更灵活方便。
-
在数据迁移时,一致性hash 需要重新计算key在新增节点的数据,然后迁移这部分数据,哈希槽则直接将一个slot对应的数据全部迁移,实现更简单。
-
可以灵活的分配槽位,比如性能更好的节点分配更多槽位,性能相对较差的节点可以分配较少的槽位。
为什么Redis Cluster哈希槽数量是16384?
-
Redis节点间通信时,心跳包会携带节点的所有槽信息,它能以幂等方式来更新配置。如果采用 16384 个插槽,占空间 2KB (16384/8);如果采用 65536 个插槽,占空间 8KB (65536/8)。
-
Redis Cluster 不太可能扩展到超过 1000 个主节点,太多可能导致网络拥堵。
-
16384 个插槽范围比较合适,当集群扩展到1000个节点时,也能确保每个master节点有足够的插槽