Redis Cluster是Redis官方提供的Redis集群功能

1.为什么要实现Redis Cluster

1.主从复制不能实现高可用
2.随着公司发展,用户数量增多,并发越来越多,业务需要更高的QPS,而主从复制中单机的QPS可能无法满足业务需求
3.数据量的考虑,现有服务器内存不能满足业务数据的需要时,单纯向服务器添加内存不能达到要求,此时需要考虑分布式需求,把数据分布到不同服务器上
4.网络流量需求:业务的流量已经超过服务器的网卡的上限值,可以考虑使用分布式来进行分流
5.离线计算,需要中间环节缓冲等别的需求

2.数据分布

在讲redis cluster数据分布之前,提一下分布式数据存储的核心算法,数据分布的算法:取模算法-->hash算法-->一致性hash算法(memcached)--> hash slot算法(redis cluster)

  1. 取模算法:扩容时,从变主,新增从,服务器增长要成倍增长,
  2. hash算法:增加减少节点时,数据迁移工作量大,重建维护困难
  3. 一致性hash算法:自动缓存迁移+虚拟节点(自动负载均衡)
  4. redis cluster的hash slot算法:redis cluster有16384个hash slot,对每个key技术CRC16值,然后对16384取模,得到hash slot,hash slot的增加/移除简单,数据移动成本相对低一些。客户端api,可以对指定的数据,让他们走同一个hash slot,通过hash tag来实现Hash Tag 。允许用key的部分字符串来计算hash。当一个key包含 {} 的时候,就不对整个key做hash,而仅对 {} 包括的字符串做hash。假设hash算法为sha1。对user:{user1}:ids和user:{user1}:tweets,其hash值都等同于sha1(user1)。
     

2.1 为什么要做数据分布

全量数据,单机Redis节点无法满足要求,按照分区规则把数据分到若干个子集当中

高可用Redis:Redis Cluster

2.2 常用数据分布方式之顺序分布

比如:1到100个数字,要保存在3个节点上,按照顺序分区,把数据平均分配三个节点上
1号到33号数据保存到节点1上,34号到66号数据保存到节点2上,67号到100号数据保存到节点3上

高可用Redis:Redis Cluster

顺序分区常用在关系型数据库的设计

2.3 常用数据分布方式之哈希分布

例如1到100个数字,对每个数字进行哈希运算,然后对每个数的哈希结果除以节点数进行取余,余数为1则保存在第1个节点上,余数为2则保存在第2个节点上,余数为0则保存在第3个节点,这样可以保证数据被打散,同时保证数据分布的比较均匀

高可用Redis:Redis Cluster

哈希分布方式分为三个分区方式:

2.3.1 节点取余分区

比如有100个数据,对每个数据进行hash运算之后,与节点数进行取余运算,根据余数不同保存在不同的节点上

高可用Redis:Redis Cluster

节点取余方式是非常简单的一种分区方式

节点取余分区方式有一个问题:即当增加或减少节点时,原来节点中的80%的数据会进行迁移操作,对所有数据重新进行分布

节点取余分区方式建议使用多倍扩容的方式,例如以前用3个节点保存数据,扩容为比以前多一倍的节点即6个节点来保存数据,这样只需要适移50%的数据。数据迁移之后,第一次无法从缓存中读取数据,必须先从数据库中读取数据,然后回写到缓存中,然后才能从缓存中读取迁移之后的数据

高可用Redis:Redis Cluster

节点取余方式优点:

客户端分片
配置简单:对数据进行哈希,然后取余

节点取余方式缺点:

数据节点伸缩时,导致数据迁移
迁移数量和添加节点数据有关,建议翻倍扩容
            

2.3.2 一致性哈希分区

一致性哈希原理:

将所有的数据当做一个token环,token环中的数据范围是0到2的32次方。然后为每一个数据节点分配一个token范围值,这个节点就负责保存这个范围内的数据。

高可用Redis:Redis Cluster

对每一个key进行hash运算,被哈希后的结果在哪个token的范围内,则按顺时针去找最近的节点,这个key将会被保存在这个节点上。

高可用Redis:Redis Cluster

高可用Redis:Redis Cluster

在上面的图中,有4个key被hash之后的值在在n1节点和n2节点之间,按照顺时针规则,这4个key都会被保存在n2节点上,
如果在n1节点和n2节点之间添加n5节点,当下次有key被hash之后的值在n1节点和n5节点之间,这些key就会被保存在n5节点上面了
在上面的例子里,添加n5节点之后,数据迁移会在n1节点和n2节点之间进行,n3节点和n4节点不受影响,数据迁移范围被缩小很多

同理,如果有1000个节点,此时添加一个节点,受影响的节点范围最多只有千分之2
一致性哈希一般用在节点比较多的时候

一致性哈希分区优点:

采用客户端分片方式:哈希 + 顺时针(优化取余)
节点伸缩时,只影响邻近节点,但是还是有数据迁移

一致性哈希分区缺点:

翻倍伸缩,保证最小迁移数据和负载均衡

2.3.3 虚拟槽分区

虚拟槽分区是Redis Cluster采用的分区方式

预设虚拟槽,每个槽就相当于一个数字,有一定范围。每个槽映射一个数据子集,一般比节点数大

Redis Cluster中预设虚拟槽的范围为0到16383

高可用Redis:Redis Cluster

步骤:

1.把16384槽按照节点数量进行平均分配,由节点进行管理
2.对每个key按照CRC16规则进行hash运算
3.把hash结果对16383进行取余
4.把余数发送给Redis节点
5.节点接收到数据,验证是否在自己管理的槽编号的范围
    如果在自己管理的槽编号范围内,则把数据保存到数据槽中,然后返回执行结果
    如果在自己管理的槽编号范围外,则会把数据发送给正确的节点,由正确的节点来把数据保存在对应的槽中

需要注意的是:Redis Cluster的节点之间会共享消息,每个节点都会知道是哪个节点负责哪个范围内的数据槽

虚拟槽分布方式中,由于每个节点管理一部分数据槽,数据保存到数据槽中。当节点扩容或者缩容时,对数据槽进行重新分配迁移即可,数据不会丢失。
虚拟槽分区特点:

使用服务端管理节点,槽,数据:例如Redis Cluster
可以对数据打散,又可以保证数据分布均匀

顺序分布与哈希分布的对比

高可用Redis:Redis Cluster

2.3.4 Hash Tag

仔细观察user:user1:ids和user:user1:tweets,两个key其实有相同的地方,即user1。能不能拿这一部分去计算hash呢?

这就是 Hash Tag允许用key的部分字符串来计算hash。当一个key包含 {} 的时候,就不对整个key做hash,而仅对 {} 包括的字符串做hash

假设hash算法为sha1。对user:{user1}:ids和user:{user1}:tweets,其hash值都等同于sha1(user1)。

Hash Tag是用于hash的部分字符串开始和结束的标记,例如"{}"、"$$"等。
配置时,只需更改hash_tag字段即可

beta:
  listen: 127.0.0.1:22122
  hash: fnv1a_64
  hash_tag: "{}"
  distribution: ketama
  auto_eject_hosts: false
  timeout: 400
  redis: true
  servers:
   - 127.0.0.1:6380:1 server1
   - 127.0.0.1:6381:1 server2
   - 127.0.0.1:6382:1 server3
   - 127.0.0.1:6383:1 server4

 

3.1 节点

Redis Cluster是分布式架构:即Redis Cluster中有多个节点,每个节点都负责进行数据读写操作

每个节点之间会进行通信。

3.2 meet操作

节点之间会相互通信

meet操作是节点之间完成相互通信的基础,meet操作有一定的频率和规则

高可用Redis:Redis Cluster

3.3 分配槽

把16384个槽平均分配给节点进行管理,每个节点只能对自己负责的槽进行读写操作

由于每个节点之间都彼此通信,每个节点都知道另外节点负责管理的槽范围

高可用Redis:Redis Cluster

客户端访问任意节点时,对数据key按照CRC16规则进行hash运算,然后对运算结果对16383进行取模,如果余数在当前访问的节点管理的槽范围内,则直接返回对应的数据
如果不在当前节点负责管理的槽范围内,则会告诉客户端去哪个节点获取数据,由客户端去正确的节点获取数据

高可用Redis:Redis Cluster

高可用Redis:Redis Cluster

3.4 复制

保证高可用,每个主节点都有一个从节点,当主节点故障,Cluster会按照规则实现主备的高可用性

对于节点来说,有一个配置项:cluster-enabled,即是否以集群模式启动

3.5 客户端路由

3.5.1 moved重定向

1.每个节点通过通信都会共享Redis Cluster中槽和集群中对应节点的关系
2.客户端向Redis Cluster的任意节点发送命令,接收命令的节点会根据CRC16规则进行hash运算与16383取余,计算自己的槽和对应节点
3.如果保存数据的槽被分配给当前节点,则去槽中执行命令,并把命令执行结果返回给客户端
4.如果保存数据的槽不在当前节点的管理范围内,则向客户端返回moved重定向异常
5.客户端接收到节点返回的结果,如果是moved异常,则从moved异常中获取目标节点的信息
6.客户端向目标节点发送命令,获取命令执行结果
 

高可用Redis:Redis Cluster

需要注意的是:客户端不会自动找到目标节点执行命令

槽命中:直接返回

高可用Redis:Redis Cluster

[root@mysql ~]# redis-cli -p 9002 cluster keyslot hello
(integer) 866

槽不命中:moved异常

[root@mysql ~]# redis-cli -p 9002 cluster keyslot php
(integer) 9244

高可用Redis:Redis Cluster

[root@mysql ~]# redis-cli -c -p 9002
127.0.0.1:9002> cluster keyslot hello
(integer) 866
127.0.0.1:9002> set hello world
-> Redirected to slot [866] located at 192.168.81.100:9003
OK
192.168.81.100:9003> cluster keyslot python
(integer) 7252
192.168.81.100:9003> set python best
-> Redirected to slot [7252] located at 192.168.81.101:9002
OK
192.168.81.101:9002> get python
"best"
192.168.81.101:9002> get hello
-> Redirected to slot [866] located at 192.168.81.100:9003
"world"
192.168.81.100:9003> exit
[root@mysql ~]# redis-cli -p 9002
127.0.0.1:9002> cluster keyslot python
(integer) 7252
127.0.0.1:9002> set python best
OK
127.0.0.1:9002> set hello world
(error) MOVED 866 192.168.81.100:9003
127.0.0.1:9002> 

Redis Cluster是Redis官方提供的Redis集群功能

1.为什么要实现Redis Cluster

1.主从复制不能实现高可用
2.随着公司发展,用户数量增多,并发越来越多,业务需要更高的QPS,而主从复制中单机的QPS可能无法满足业务需求
3.数据量的考虑,现有服务器内存不能满足业务数据的需要时,单纯向服务器添加内存不能达到要求,此时需要考虑分布式需求,把数据分布到不同服务器上
4.网络流量需求:业务的流量已经超过服务器的网卡的上限值,可以考虑使用分布式来进行分流
5.离线计算,需要中间环节缓冲等别的需求

2.数据分布

在讲redis cluster数据分布之前,提一下分布式数据存储的核心算法,数据分布的算法:取模算法-->hash算法-->一致性hash算法(memcached)--> hash slot算法(redis cluster)

  1. 取模算法:扩容时,从变主,新增从,服务器增长要成倍增长,
  2. hash算法:增加减少节点时,数据迁移工作量大,重建维护困难
  3. 一致性hash算法:自动缓存迁移+虚拟节点(自动负载均衡)
  4. redis cluster的hash slot算法:redis cluster有16384个hash slot,对每个key技术CRC16值,然后对16384取模,得到hash slot,hash slot的增加/移除简单,数据移动成本相对低一些。客户端api,可以对指定的数据,让他们走同一个hash slot,通过hash tag来实现Hash Tag 。允许用key的部分字符串来计算hash。当一个key包含 {} 的时候,就不对整个key做hash,而仅对 {} 包括的字符串做hash。假设hash算法为sha1。对user:{user1}:ids和user:{user1}:tweets,其hash值都等同于sha1(user1)。
     

2.1 为什么要做数据分布

全量数据,单机Redis节点无法满足要求,按照分区规则把数据分到若干个子集当中

高可用Redis:Redis Cluster

2.2 常用数据分布方式之顺序分布

比如:1到100个数字,要保存在3个节点上,按照顺序分区,把数据平均分配三个节点上
1号到33号数据保存到节点1上,34号到66号数据保存到节点2上,67号到100号数据保存到节点3上

高可用Redis:Redis Cluster

顺序分区常用在关系型数据库的设计

2.3 常用数据分布方式之哈希分布

例如1到100个数字,对每个数字进行哈希运算,然后对每个数的哈希结果除以节点数进行取余,余数为1则保存在第1个节点上,余数为2则保存在第2个节点上,余数为0则保存在第3个节点,这样可以保证数据被打散,同时保证数据分布的比较均匀

高可用Redis:Redis Cluster

哈希分布方式分为三个分区方式:

2.3.1 节点取余分区

比如有100个数据,对每个数据进行hash运算之后,与节点数进行取余运算,根据余数不同保存在不同的节点上

高可用Redis:Redis Cluster

节点取余方式是非常简单的一种分区方式

节点取余分区方式有一个问题:即当增加或减少节点时,原来节点中的80%的数据会进行迁移操作,对所有数据重新进行分布

节点取余分区方式建议使用多倍扩容的方式,例如以前用3个节点保存数据,扩容为比以前多一倍的节点即6个节点来保存数据,这样只需要适移50%的数据。数据迁移之后,第一次无法从缓存中读取数据,必须先从数据库中读取数据,然后回写到缓存中,然后才能从缓存中读取迁移之后的数据

高可用Redis:Redis Cluster

节点取余方式优点:

客户端分片
配置简单:对数据进行哈希,然后取余

节点取余方式缺点:

数据节点伸缩时,导致数据迁移
迁移数量和添加节点数据有关,建议翻倍扩容
            

2.3.2 一致性哈希分区

一致性哈希原理:

将所有的数据当做一个token环,token环中的数据范围是0到2的32次方。然后为每一个数据节点分配一个token范围值,这个节点就负责保存这个范围内的数据。

高可用Redis:Redis Cluster

对每一个key进行hash运算,被哈希后的结果在哪个token的范围内,则按顺时针去找最近的节点,这个key将会被保存在这个节点上。

高可用Redis:Redis Cluster

高可用Redis:Redis Cluster

在上面的图中,有4个key被hash之后的值在在n1节点和n2节点之间,按照顺时针规则,这4个key都会被保存在n2节点上,
如果在n1节点和n2节点之间添加n5节点,当下次有key被hash之后的值在n1节点和n5节点之间,这些key就会被保存在n5节点上面了
在上面的例子里,添加n5节点之后,数据迁移会在n1节点和n2节点之间进行,n3节点和n4节点不受影响,数据迁移范围被缩小很多

同理,如果有1000个节点,此时添加一个节点,受影响的节点范围最多只有千分之2
一致性哈希一般用在节点比较多的时候

一致性哈希分区优点:

采用客户端分片方式:哈希 + 顺时针(优化取余)
节点伸缩时,只影响邻近节点,但是还是有数据迁移

一致性哈希分区缺点:

翻倍伸缩,保证最小迁移数据和负载均衡

2.3.3 虚拟槽分区

虚拟槽分区是Redis Cluster采用的分区方式

预设虚拟槽,每个槽就相当于一个数字,有一定范围。每个槽映射一个数据子集,一般比节点数大

Redis Cluster中预设虚拟槽的范围为0到16383

高可用Redis:Redis Cluster

步骤:

1.把16384槽按照节点数量进行平均分配,由节点进行管理
2.对每个key按照CRC16规则进行hash运算
3.把hash结果对16383进行取余
4.把余数发送给Redis节点
5.节点接收到数据,验证是否在自己管理的槽编号的范围
    如果在自己管理的槽编号范围内,则把数据保存到数据槽中,然后返回执行结果
    如果在自己管理的槽编号范围外,则会把数据发送给正确的节点,由正确的节点来把数据保存在对应的槽中

需要注意的是:Redis Cluster的节点之间会共享消息,每个节点都会知道是哪个节点负责哪个范围内的数据槽

虚拟槽分布方式中,由于每个节点管理一部分数据槽,数据保存到数据槽中。当节点扩容或者缩容时,对数据槽进行重新分配迁移即可,数据不会丢失。
虚拟槽分区特点:

使用服务端管理节点,槽,数据:例如Redis Cluster
可以对数据打散,又可以保证数据分布均匀

顺序分布与哈希分布的对比

高可用Redis:Redis Cluster

相关文章:

  • 2021-11-19
  • 2021-12-17
  • 2022-01-11
  • 2021-10-21
  • 2022-12-23
  • 2022-12-23
  • 2021-06-30
  • 2021-12-21
猜你喜欢
  • 2021-11-29
  • 2022-12-23
  • 2022-01-07
  • 2021-11-27
  • 2021-06-26
  • 2021-08-08
相关资源
相似解决方案