Redis集群与插槽分配(动态新增或删除结点)

https://blog.csdn.net/IT_hejinrong/article/details/79205528

1. 集群

 

 

  即使有了主从复制,每个数据库都要保存整个集群中的所有数据,容易形成木桶效应。

使用Jedis实现了分片集群,是由客户端控制哪些key数据保存到哪个数据库中,如果在水平扩容时就必须手动进行数据迁移,而且需要将整个集群停止服务,这样做非常不好的。

Redis3.0版本的一大特性就是集群(Cluster),接下来我们一起学习集群。

 

1.1 架构

 

Redis集群与插槽分配(动态新增或删除结点)_第1张图片

(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.

(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.

(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

(4)redis-cluster把所有的物理节点映射到[0-16383]slot(插槽)上,cluster 负责维护node<->slot<->value

 

4.2. 修改配置文件

 

1、 设置不同的端口,6379、6380、6381

2、 开启集群,cluster-enabled yes

3、 指定集群的配置文件,cluster-config-file "nodes-xxxx.conf"

Redis集群与插槽分配(动态新增或删除结点)_第2张图片

 

 

4.3. 创建集群

 

因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。

 yum -y install zlib ruby rubygems

 gem install redis

手动安装:

 rz上传redis-3.2.1.gem

 gem install -l redis-3.2.1.gem

 

注:该文件[redis-3.2.1.gem]链接地址:链接: https://pan.baidu.com/s/1ggsUBhp,如链接失效,可以联系我

 

4.3.2 创建集群

 

首先,进入redis的安装包路径下:

cd /usr/local/src/redis/redis-3.0.1/src/

Redis集群与插槽分配(动态新增或删除结点)_第3张图片

 

 

执行命令:

./redis-trib.rb create --replicas 0 192.168.56.102:6379 192.168.56.102:6380 192.168.56.102:6381

--replicas 0:指定了从数据的数量为0

注意:这里不能使用127.0.0.1,否则在Jedis客户端使用时无法连接到!

redis-trib用法:

Redis集群与插槽分配(动态新增或删除结点)_第4张图片

Redis集群与插槽分配(动态新增或删除结点)_第5张图片

 

4.3.3. 测试

 

Redis集群与插槽分配(动态新增或删除结点)_第6张图片

 

什么情况??(error) MOVED 7638 127.0.0.1:6380  

因为abc的hash槽信息是在6380上,现在使用redis-cli连接的6379,无法完成set操作,需要客户端跟踪重定向。

redis-cli -c

Redis集群与插槽分配(动态新增或删除结点)_第7张图片

 

看到由6379跳转到了6380,然后再进入6379看能否get到数据

 

Redis集群与插槽分配(动态新增或删除结点)_第8张图片

还是被重定向到了6380,不过已经可以获取到数据了。

 

 

4.4.使用Jedis连接到集群

 

添加依赖,要注意jedis的版本为2.7.2

Redis集群与插槽分配(动态新增或删除结点)_第9张图片

 

Redis集群与插槽分配(动态新增或删除结点)_第10张图片

 

说明:这里的jc不需要关闭,因为内部已经关闭连接了。

 

 

4.5. 插槽的分配

 

通过cluster nodes命令可以查看当前集群的信息:

Redis集群与插槽分配(动态新增或删除结点)_第11张图片

 

该信息反映出了集群中的每个节点的id、身份、连接数、插槽数等。

当我们执行set abc 123命令时,redis是如何将数据保存到集群中的呢?执行步骤:

 1、 接收命令set abc 123

 2、 通过key(abc)计算出插槽值,然后根据插槽值找到对应的节点。(abc的插槽值为:7638)

 3、 重定向到该节点执行命令

整个Redis提供了16384个插槽,也就是说集群中的每个节点分得的插槽数总和为16384。

./redis-trib.rb 脚本实现了是将16384个插槽平均分配给了N个节点。

注意:如果插槽数有部分是没有指定到节点的,那么这部分插槽所对应的key将不能使用。

 

 

4.6. 插槽和Key的关系

 

计算key的插槽值:

key的有效部分使用CRC16算法计算出哈希值,再将哈希值对16384取余,得到插槽值。

什么是有效部分?

1、 如果key中包含了{符号,且在{符号后存在}符号,并且{和}之间至少有一个字符,则有效部分是指{和}之间的部分;

a) key={hello}_tatao的有效部分是hello

2、 如果不满足上一条情况,整个key都是有效部分;

a) key=hello_taotao的有效部分是全部

 

 

4.7. 新增集群结点

 

再开启一个实例的端口为6382

Redis集群与插槽分配(动态新增或删除结点)_第12张图片

 

执行脚本:

./redis-trib.rb add-node 192.168.56.102:6382 192.168.56.102:6379

 

Redis集群与插槽分配(动态新增或删除结点)_第13张图片

 

 

已经添加成功!查看集群信息:

Redis集群与插槽分配(动态新增或删除结点)_第14张图片

 

 

发现没有插槽数。

 

接下来需要给6382这个服务分配插槽,将6379的一部分(1000个)插槽分配给6382:

Redis集群与插槽分配(动态新增或删除结点)_第15张图片

Redis集群与插槽分配(动态新增或删除结点)_第16张图片

 

 

查看节点情况:

 

 

4.8. 删除集群结点

 

 

 

想要删除集群节点中的某一个节点,需要严格执行2步:

1、 将这个节点上的所有插槽转移到其他节点上;

 a) 假设我们想要删除6380这个节点

 b) 执行脚本:./redis-trib.rb reshard 192.168.56.102:6380

c)选择需要转移的插槽的数量,因为3380有5128个,所以转移5128个

Redis集群与插槽分配(动态新增或删除结点)_第17张图片

 

 d) 输入转移的节点的id,我们转移到6382节点:82ed0d63cfa6d19956dca833930977a87d6ddf7

 e) 输入插槽来源id,也就是6380的id

f)输入done,开始转移

Redis集群与插槽分配(动态新增或删除结点)_第18张图片

 

g)查看集群信息,可以看到6380节点已经没有插槽了。

Redis集群与插槽分配(动态新增或删除结点)_第19张图片
 

 

2、 使用redis-trib.rb删除节点

 a) ./redis-trib.rb del-node 192.168.56.102:6380 4a9b8886ba5261e82597f5590fcdb49ea47c4c6c

 b) del-node host:port node_id

Redis集群与插槽分配(动态新增或删除结点)_第20张图片

 

 

d)查看集群信息,可以看到已经没有6380这个节点了。

 

 

4.9. 故障转移

 

如果集群中的某一节点宕机会出现什么状况?我们这里假设6381宕机。

Redis集群与插槽分配(动态新增或删除结点)_第21张图片

 

我们尝试连接下集群,并且查看集群信息,发现6381的节点断开连接:

Redis集群与插槽分配(动态新增或删除结点)_第22张图片

 

 

我们尝试执行set命令,结果发现无法执行:

 

什么情况?集群不可用了?? 这集群也太弱了吧??

 

 

4.9.1. 故障机制

 

 

1、 集群中的每个节点都会定期的向其它节点发送PING命令,并且通过有没有收到回复判断目标节点是否下线;

2、 集群中每一秒就会随机选择5个节点,然后选择其中最久没有响应的节点放PING命令;

3、 如果一定时间内目标节点都没有响应,那么该节点就认为目标节点疑似下线

4、 当集群中的节点超过半数认为该目标节点疑似下线,那么该节点就会被标记为下线

5、 当集群中的任何一个节点下线,就会导致插槽区有空档,不完整,那么该集群将不可用;

6、 如何解决上述问题?

 a) 在Redis集群中可以使用主从模式实现某一个节点的高可用

 b) 当该节点(master)宕机后,集群会将该节点的从数据库(slave)转变为(master)继续完成集群服务;

 

 

4.9.2. 集群中的主从复制架构

 

架构:

Redis集群与插槽分配(动态新增或删除结点)_第23张图片
 

 

出现故障:

Redis集群与插槽分配(动态新增或删除结点)_第24张图片
 

 

4.9.3. 创建主从集群

 

 

需要启动6个redis实例,分别是:

6379(主) 6479(从)

6380(主) 6480(从)

6381(主) 6481(从)

 

Redis集群与插槽分配(动态新增或删除结点)_第25张图片

 

 

启动redis实例:

cd 6379/ && redis-server ./redis.conf && cd ..

cd 6380/ && redis-server ./redis.conf && cd ..

cd 6381/ && redis-server ./redis.conf && cd ..

cd 6479/ && redis-server ./redis.conf && cd ..

cd 6480/ && redis-server ./redis.conf && cd ..

cd 6481/ && redis-server ./redis.conf && cd ..

 

Redis集群与插槽分配(动态新增或删除结点)_第26张图片

 

创建集群,指定了从库数量为1,创建顺序为主库(3个)、从库(3个):

./redis-trib.rb create --replicas 1 192.168.56.102:6379 192.168.56.102:6380 192.168.56.102:6381 192.168.56.102:6479 192.168.56.102:6480 192.168.56.102:6481

 

Redis集群与插槽分配(动态新增或删除结点)_第27张图片

Redis集群与插槽分配(动态新增或删除结点)_第28张图片

 

创建成功!查看集群信息:

 

 

4.9.4. 测试

 

Redis集群与插槽分配(动态新增或删除结点)_第29张图片

保存、读取数据OK!

 

查看下6480的从库数据:

Redis集群与插槽分配(动态新增或删除结点)_第30张图片

看到从6480查看数据也是被重定向到6380.

说明集群一切运行OK!

 

 

4.9.5. 测试集群中slave结点宕机

 

我们将6480节点kill掉,查看情况。

 

Redis集群与插槽分配(动态新增或删除结点)_第31张图片

 

 

查看集群情况:

发现6480节点不可用。

 

那么整个集群可用吗?

Redis集群与插槽分配(动态新增或删除结点)_第32张图片

 

发现集群可用,可见从数据库宕机不会影响集群正常服务。

 

 

恢复6480服务:

Redis集群与插槽分配(动态新增或删除结点)_第33张图片
 

测试6480中的数据:

Redis集群与插槽分配(动态新增或删除结点)_第34张图片

看到已经更新成最新数据。

 

 

4.9.6. 测试集群中master宕机

 

假设6381宕机:

Redis集群与插槽分配(动态新增或删除结点)_第35张图片

 

查看集群情况:

 

发现:

1、6381节点失效不可用

2、6481节点从slave转换为master

 

测试集群是否可用:

Redis集群与插槽分配(动态新增或删除结点)_第36张图片

集群可用!

 

恢复6381:

 

发现:

1、6381节点可用

2、6481依然是主节点

3、6381成为6481的从数据库

 

4.10. 使用集群需要注意的事项

 

 1、 多键的命令操作(如MGET、MSET),如果每个键都位于同一个节点,则可以正常支持,否则会提示错误。

 2、 集群中的节点只能使用0号数据库,如果执行SELECT切换数据库会提示错误。

你可能感兴趣的:(redis,redis)