Redis-Cluster

即使是使用哨兵,此时的Redis集群的每个数据库依然存有集群中的所有数据,从而导致集群的总数据存储量受限
于可用存储内存最小的节点,形成了木桶效应。而因为Redis是基于内存存储的,所以这一个问题在redis中就显得尤为突出了

在redis3.0之前,我们是通过在客户端去做的分片,通过hash环的方式对key进行分片存储。分片虽然能够解决各个节点的存储压力,但是导致维护成本高、增加、移除节点比较繁琐。
因此在redis3.0以后的版本最大的一个好处就是支持集群功能,集群的特点在于拥有和单机实例一样的性能,
同时在网络分区以后能够提供一定的可访问性以及对主数据库故障恢复的支持。
哨兵和集群是两个独立的功能,当不需要对数据进行分片使用哨兵就够了,如果要进行水平扩容,集群是一个比较好的方式

拓扑结构

一个Redis Cluster由多个Redis节点构成。不同节点组服务的数据没有交集,也就是每个一节点组对应数据sharding的一个分片。
节点组内部分为主备两类节点,对应master和slave节点。两者数据准实时一致,通过异步化的主备复制机制来保证。
一个节点组有且只有一个master节点,同时可以有0到多个slave节点,在这个节点组中只有master节点对用户提供些服务,读服务可以由master或者slave提供

redis-cluster是基于gossip协议实现的无中心化节点的集群,因为去中心化的架构不存在统一的配置中心,各个节点对整个集群状态的认知来自于节点之间的信息交互。
在Redis Cluster,这个信息交互是通过Redis Cluster Bus来完成的

Redis的数据分区

分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集, Redis Cluster采用哈希分区规则,采用虚拟槽分区。
虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。比如Redis Cluster槽的范围是0 ~ 16383。
槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,每个节点负责一定数量的槽。
计算公式:slot = CRC16(key)%16383。每一个节点负责维护一部分槽以及槽所映射的键值数据。

HashTags

通过分片手段,可以将数据合理的划分到不同的节点上,这本来是一件好事。但是有的时候,我们希望对相关联的业务以原子方式进行操作。举个简单的例子
我们在单节点上执行MSET , 它是一个原子性的操作,所有给定的key会在同一时间内被设置,不可能出现某些指定的key被更新另一些指定的key没有改变的情况。
但是在集群环境下,我们仍然可以执行MSET命令,但它的操作不在是原子操作,会存在某些指定的key被更新,而另外一些指定的key没有改变,原因是多个key可能会被分配到不同的机器上。

所以,这里就会存在一个矛盾点,及要求key尽可能的分散在不同机器,又要求某些相关联的key分配到相同机器。这个也是在面试的时候会容易被问到的内容。怎么解决呢?
从前面的分析中我们了解到,分片其实就是一个hash的过程,对key做hash取模然后划分到不同的机器上。所以为了解决这个问题,我们需要考虑如何让相关联的key得到的hash值都相同呢?
如果key全部相同是不现实的,所以怎么解决呢?
在redis中引入了HashTag的概念,可以使得数据分布算法可以根据key的某一个部分进行计算,然后让相关的key落到同一个数据分片

举个简单的例子,加入对于用户的信息进行存储, user:user1:id、user:user1:name/ 那么通过hashtag的方式,
user:{user1}:id、user:{user1}.name; 表示
当一个key包含 {} 的时候,就不对整个key做hash,而仅对 {} 包括的字符串做hash。

重定向客户端

Redis Cluster并不会代理查询,那么如果客户端访问了一个key并不存在的节点,这个节点是怎么处理的呢?比如我想获取key为msg的值,msg计算出来的槽编号为254,
当前节点正好不负责编号为254的槽,那么就会返回客户端下面信息:
-MOVED 254 127.0.0.1:6381
表示客户端想要的254槽由运行在IP为127.0.0.1,端口为6381的Master实例服务。如果根据key计算得出的槽恰好由当前节点负责,则当期节点会立即返回结果

分片迁移

在一个稳定的Redis cluster下,每一个slot对应的节点是确定的,但是在某些情况下,节点和分片对应的关系会发生变更
\1. 新加入master节点
\2. 某个节点宕机
也就是说当动态添加或减少node节点时,需要将16384个槽做个再分配,槽中的键值也要迁移。当然,这一过程,在目前实现中,还处于半自动状态,需要人工介入。

新增一个主节点
新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot到D上。大致就会变成这样:
节点A覆盖1365-5460
节点B覆盖6827-10922
节点C覆盖12288-16383
节点D覆盖0-1364,5461-6826,10923-12287

删除一个主节点
先将节点的数据移动到其他节点上,然后才能执行删除

槽迁移的过程

槽迁移的过程中有一个不稳定状态,这个不稳定状态会有一些规则,这些规则定义客户端的行为,从而使得RedisCluster不必宕机的情况下可以执行槽的迁移。
下面这张图描述了我们迁移编号为1、2、3的槽的过程中,他们在MasterA节点和MasterB节点中的状态

简单的工作流程
\1. 向MasterB发送状态变更命令,吧Master B对应的slot状态设置为IMPORTING
\2. 向MasterA发送状态变更命令,将Master对应的slot状态设置为MIGRATING
当MasterA的状态设置为MIGRANTING后,表示对应的slot正在迁移,为了保证slot数据的一致性,MasterA此时对于slot内部数据提供读写服务的行为和通常状态下是有区别的,

MIGRATING状态
\1. 如果客户端访问的Key还没有迁移出去,则正常处理这个key
\2. 如果key已经迁移或者根本就不存在这个key,则回复客户端ASK信息让它跳转到MasterB去执行

IMPORTING状态
当MasterB的状态设置为IMPORTING后,表示对应的slot正在向MasterB迁入,及时Master仍然能对外提供该slot的读写服务,但和通常状态下也是有区别的
\1. 当来自客户端的正常访问不是从ASK跳转过来的,说明客户端还不知道迁移正在进行,很有可能操作了一个目前
还没迁移完成的并且还存在于MasterA上的key,如果此时这个key在A上已经被修改了,那么B和A的修改则会发生
冲突。所以对于MasterB上的slot上的所有非ASK跳转过来的操作,MasterB都不会uu出去护理,而是通过MOVED命令让客户端跳转到MasterA上去执行

这样的状态控制保证了同一个key在迁移之前总是在源节点上执行,迁移后总是在目标节点上执行,防止出现两边同时写导致的冲突问题。
而且迁移过程中新增的key一定会在目标节点上执行,源节点也不会新增key,是的整个迁移过程既能对外正常提供服务,又能在一定的时间点完成slot的迁移。

Redis-Cluster环境搭建三主三从

为方便演示,我们在一台机器上演示三主六从的rediscluster

  

1..创建存放多个实例的目录

  1. mkdir /data/cluster -p
  2. cd /data/cluster
  3. mkdir 7000 7001 7002 7003 7004 7005 7006 7007 7008

2.修改配置文件

  1. cp redis上一层目录
    cp redis/redis.conf /data/cluster/7000/

修改配置文件中下面选项

port 7000

daemonize yes

cluster-enabled yes

cluster-config-file nodes.conf

cluster-node-timeout 5000

appendonly yes

  1. (注意:找到相应的信息修改,或者把修改的信息全部注释掉,重新添加下面信息到头部,有利于以后修改和查看)
  2.  
  3. #注释掉ip或者设置0.0.0.0都是局域网访问
  4. #bind 127.0.0.1
  5. #端口号
  6. port 7777
  7.  
  8. #指定了记录日志的文件
  9. logfile "/root/svr/redis-3.2.9/cluster-conf/7777/redis.log"
  10.  
  11. #该目录要事先创建好,数据目录,数据库的写入会在这个目录。rdb、aof文件也会写在这个目录
  12. dir /root/svr/redis-3.2.9/cluster-conf/7777/
  13.  
  14. #是否开启集群
  15. cluster-enabled yes
  16.  
  17. #集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息,
  18. #这个文件并不需要手动配置,这个配置文件有Redis生成并更新,
  19. #每个Redis集群节点需要一个单独的配置文件,请确保与实例运行的系统中配置文件名称不冲突。
  20. cluster-config-file nodes.conf
  21.  
  22. #节点互连超时的阀值。集群节点超时毫秒数
  23. cluster-node-timeout 5000
  24.  
  25. #默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,
  26. #但是redis如果中途宕机,会导致可能有几分钟的数据丢失,
  27. #根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性,
  28. #Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,
  29. #每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。
  30. appendonly yes

  

文件中的 cluster-enabled 选项用于开实例的集群模式, 而 cluster-conf-file 选项则设定了保存节点配置文件的路径, 默认值为nodes.conf 。其他参数相信童鞋们都知道。节点配置文件无须人为修改, 它由 Redis 集群在启动时创建, 并在有需要时自动进行更新。

修改完成后,把修改完成的redis.conf复制到7001-7008目录下,并且端口修改成和文件夹对应。

3.启动9个redis实例

  1. cd /data/cluster/7000
  2. redis-server redis.conf
  3. cd /data/cluster/7001
  4. redis-server redis.conf
  5. cd /data/cluster/7002
  6. redis-server redis.conf
  7. cd /data/cluster/7003
  8. redis-server redis.conf
  9. cd /data/cluster/7004
  10. redis-server redis.conf
  11. cd /data/cluster/7005
  12. redis-server redis.conf
  13. cd /data/cluster/7006
  14. redis-server redis.conf
  15. cd /data/cluster/7007
  16. redis-server redis.conf
  17. cd /data/cluster/7008
  18. redis-server redis.conf

  查看进程否存在

  1. [root@localhost 7008]# ps -ef |grep redis
  2. root 5464 1 0 10:01 ? 00:00:00 redis-server 127.0.0.1:7000 [cluster]
  3. root 5469 1 0 10:01 ? 00:00:00 redis-server 127.0.0.1:7001 [cluster]
  4. root 5473 1 0 10:01 ? 00:00:00 redis-server 127.0.0.1:7002 [cluster]
  5. root 5478 1 0 10:01 ? 00:00:00 redis-server 127.0.0.1:7003 [cluster]
  6. root 5482 1 0 10:01 ? 00:00:00 redis-server 127.0.0.1:7004 [cluster]
  7. root 5486 1 0 10:01 ? 00:00:00 redis-server 127.0.0.1:7005 [cluster]
  8. root 5490 1 0 10:01 ? 00:00:00 redis-server 127.0.0.1:7006 [cluster]
  9. root 5495 1 0 10:02 ? 00:00:00 redis-server 127.0.0.1:7007 [cluster]
  10. root 5499 1 0 10:02 ? 00:00:00 redis-server 127.0.0.1:7008 [cluster]
  11. root 5504 4941 0 10:02 pts/2 00:00:00 grep redis

  

4.执行命令创建集群,首先安装依赖,否则创建集群失败。

  1. yum install ruby rubygems -y

有时候yum安装某个软件的时候特别慢,不想再继续安装下去了,或者想做其他的操作,可以按照以下终止yum进程

ctrl+z #中断当前的安装显示
ps -ef | grep yum #查找当前yum相关的进程
kill -9 进程号(pid) #杀掉进程
举个例子

安装 ca-certificates,停着好久不动了,按 ctrl+z 中断

查看当前的进程号pid

第一条记录是需要杀掉的,不然接下来yum用不了

杀掉之后,再次查看,发现进程没有了,可以进行其他的操作了。
有时候是否有网:ping www.baidu.com

查看是否能ping通,不同则可能是虚拟机网络连接选择的问题(本人由仅主机改为net连接,对应子网改变,对应虚拟机的ip则会发生改变),下面是虚拟机的三种网络:

1、桥接:虚拟机通过本机的真实网卡和主机进行通讯。不仅可以和你的本机进行通讯,如果局域网内有同网段的计算机,也可以进行通讯。不过需要占用同网段的一个ip地址。
2、NAT:虚拟机通过VMware-8这块虚拟出来的网卡和你的本机进行通讯。
3、host-only:虚拟机通过VMware-1这块虚拟出来的网卡和你的本机进行通讯。

NAT和host-only 不会占用一个ip地址,只能和你的本机进行通讯。
NAT和host-only还有一个区别就是,host-only只能和你的本机进行通讯,不可以访问互联网。NAT除了只可以和你的本机进行通讯之外,如果你的本机可以访问互联网,你的虚拟机同样可以访问互联网。

安装gem-redis

下载地址:https://rubygems.org/gems/redis/versions/3.0.0

  1. gem install -l redis-3.0.0.gem

复制集群管理程序到/usr/local/bin

  1. cp redis-3.0.0/src/redis-trib.rb /usr/local/bin/redis-trib

创建集群:

  1. redis-trib create --replicas 2 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 127.0.0.1:7007 127.0.0.1:7008

  

命令的意义如下:

  • 给定 redis-trib.rb 程序的命令是 create , 这表示我们希望创建一个新的集群。
  • 选项 --replicas 2 表示我们希望为集群中的每个主节点创建2个从节点。
  • 之后跟着的其他参数则是实例的地址列表, 我们希望程序使用这些地址所指示的实例来创建新集群。

简单来说, 以上命令的意思就是让 redis-trib 程序创建一个包含三个主节点和三个从节点的集群。

接着, redis-trib 会打印出一份预想中的配置给你看, 如果你觉得没问题的话, 就可以输入 yes , redis-trib 就会将这份配置应用到集群当中:

  1. >>> Creating cluster
  2. >>> Performing hash slots allocation on 9 nodes...
  3. Using 3 masters:
  4. 127.0.0.1:7000
  5. 127.0.0.1:7001
  6. 127.0.0.1:7002
  7. Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
  8. Adding replica 127.0.0.1:7004 to 127.0.0.1:7000
  9. Adding replica 127.0.0.1:7005 to 127.0.0.1:7001
  10. Adding replica 127.0.0.1:7006 to 127.0.0.1:7001
  11. Adding replica 127.0.0.1:7007 to 127.0.0.1:7002
  12. Adding replica 127.0.0.1:7008 to 127.0.0.1:7002
  13. M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
  14. slots:0-5460 (5461 slots) master
  15. M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
  16. slots:5461-10922 (5462 slots) master
  17. M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
  18. slots:10923-16383 (5461 slots) master
  19. S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
  20. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  21. S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
  22. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  23. S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
  24. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  25. S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
  26. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  27. S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
  28. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  29. S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
  30. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  31. Can I set the above configuration? (type 'yes' to accept):

  输入 yes 并按下回车确认之后, 集群就会将配置应用到各个节点, 并连接起(join)各个节点 —— 也即是, 让各个节点开始互相通讯

  1. Can I set the above configuration? (type 'yes' to accept): yes
  2. >>> Nodes configuration updated
  3. >>> Assign a different config epoch to each node
  4. >>> Sending CLUSTER MEET messages to join the cluster
  5. Waiting for the cluster to join....
  6. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  7. M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
  8. slots:0-5460 (5461 slots) master
  9. 2 additional replica(s)
  10. M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
  11. slots:5461-10922 (5462 slots) master
  12. 2 additional replica(s)
  13. S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
  14. slots: (0 slots) slave
  15. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  16. S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
  17. slots: (0 slots) slave
  18. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  19. S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
  20. slots: (0 slots) slave
  21. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  22. S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
  23. slots: (0 slots) slave
  24. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  25. S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
  26. slots: (0 slots) slave
  27. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  28. M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
  29. slots:10923-16383 (5461 slots) master
  30. 2 additional replica(s)
  31. S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
  32. slots: (0 slots) slave
  33. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  34. [OK] All nodes agree about slots configuration.
  35. >>> Check for open slots...
  36. >>> Check slots coverage...
  37. [OK] All 16384 slots covered.

  

集群的客户端

Redis 集群现阶段的一个问题是客户端实现很少。 以下是一些我知道的实现:

  • redis-rb-cluster 是我(@antirez)编写的 Ruby 实现, 用于作为其他实现的参考。 该实现是对 redis-rb 的一个简单包装, 高效地实现了与集群进行通讯所需的最少语义(semantic)。
  • redis-py-cluster 看上去是 redis-rb-cluster 的一个 Python 版本, 这个项目有一段时间没有更新了(最后一次提交是在六个月之前), 不过可以将这个项目用作学习集群的起点。
  • 流行的 Predis 曾经对早期的 Redis 集群有过一定的支持, 但我不确定它对集群的支持是否完整, 也不清楚它是否和最新版本的 Redis 集群兼容 (因为新版的 Redis 集群将槽的数量从 4k 改为 16k 了)。
  • Redis unstable 分支中的 redis-cli 程序实现了非常基本的集群支持, 可以使用命令 redis-cli -c 来启动。

测试 Redis 集群比较简单的办法就是使用 redis-rb-cluster 或者 redis-cli , 接下来我们将使用 redis-cli 为例来进行演示:

[root@localhost 7008]# redis-cli -c -p 7001
127.0.0.1:7001> set name lf
OK
127.0.0.1:7001> get name
"lf"

我们可以看看还有哪些命令可以用:

  1. [root@localhost 7008]#  redis-trib help
  2. Usage: redis-trib <command> <options> <arguments ...>
  3.  
  4. set-timeout host:port milliseconds
  5. add-node new_host:new_port existing_host:existing_port
  6. --master-id <arg>
  7. --slave
  8. fix host:port
  9. help (show this help)
  10. del-node host:port node_id
  11. import host:port
  12. --from <arg>
  13. check host:port
  14. call host:port command arg arg .. arg
  15. create host1:port1 ... hostN:portN
  16. --replicas <arg>
  17. reshard host:port
  18. --yes
  19. --to <arg>
  20. --from <arg>
  21. --slots <arg>
  22.  
  23. For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
  24. [root@localhost 7008]# 

可以看见有add-node,不用想了,肯定是添加节点。那么del-node就是删除节点。还有check肯定就是检查状态了。

  1. [root@localhost 7008]#  redis-cli -p 7000 cluster nodes
  2. 2d03b862083ee1b1785dba5db2987739cf3a80eb 127.0.0.1:7001 master - 0 1428293673322 2 connected 5461-10922
  3. 37b251500385929d5c54a005809377681b95ca90 127.0.0.1:7003 slave 2774f156af482b4f76a5c0bda8ec561a8a1719c2 0 1428293672305 4 connected
  4. e2e2e692c40fc34f700762d1fe3a8df94816a062 127.0.0.1:7004 slave 2d03b862083ee1b1785dba5db2987739cf3a80eb 0 1428293674340 5 connected
  5. 0456869a2c2359c3e06e065a09de86df2e3135ac 127.0.0.1:7002 master - 0 1428293670262 3 connected 10923-16383
  6. 2774f156af482b4f76a5c0bda8ec561a8a1719c2 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
  7. 9923235f8f2b2587407350b1d8b887a7a59de8db 127.0.0.1:7005 slave 0456869a2c2359c3e06e065a09de86df2e3135ac 0 1428293675362 6 connected
  8. [root@redis-server ~]#

可以看到7000-7002是master,7003-7005是slave。

故障转移测试:

  1. 127.0.0.1:7001> KEYS *
  2. 1) "name"
  3. 127.0.0.1:7001> get name
  4. "lf"
  5. 127.0.0.1:7001>

可以看见7001是正常的,并且获取到了key,value,现在kill掉7000实例,再进行查询。

  1. [root@localhost 7008]#  ps -ef | grep 7000
  2. root 4168 1 0 11:49 ? 00:00:03 redis-server *:7000 [cluster]
  3. root 4385 4361 0 12:39 pts/3 00:00:00 grep 7000
  4. [root@localhost 7008]#  kill 4168
  5. [root@localhost 7008]#  ps -ef | grep 7000
  6. root 4387 4361 0 12:39 pts/3 00:00:00 grep 7000
  7. [root@localhost 7008]# redis-cli -c -p 7001
  8. 127.0.0.1:7001> get name
  9. "lf"
  10. 127.0.0.1:7001>

可以正常获取到value,现在看看状态。

  1. [root@localhost 7008]# redis-cli -c -p 7001 cluster nodes
  2. 2d03b862083ee1b1785dba5db2987739cf3a80eb 127.0.0.1:7001 myself,master - 0 0 2 connected 5461-10922
  3. 0456869a2c2359c3e06e065a09de86df2e3135ac 127.0.0.1:7002 master - 0 1428295271619 3 connected 10923-16383
  4. 37b251500385929d5c54a005809377681b95ca90 127.0.0.1:7003 master - 0 1428295270603 7 connected 0-5460
  5. e2e2e692c40fc34f700762d1fe3a8df94816a062 127.0.0.1:7004 slave 2d03b862083ee1b1785dba5db2987739cf3a80eb 0 1428295272642 5 connected
  6. 2774f156af482b4f76a5c0bda8ec561a8a1719c2 127.0.0.1:7000 master,fail - 1428295159553 1428295157205 1 disconnected
  7. 9923235f8f2b2587407350b1d8b887a7a59de8db 127.0.0.1:7005 slave 0456869a2c2359c3e06e065a09de86df2e3135ac 0 1428295269587 6 connected

原来的7000端口实例已经显示fail,原来的7003是slave,现在自动提升为master。

关于更多的在线添加节点,删除节点,以及对集群进行重新分片请参考官方文档。

redis-cluster是个好东西,只是stable才出来不久,肯定坑略多,而且现在使用的人比较少,前期了解学习一下是可以的,生产环境肯定要慎重考虑。且需要进行严格的测试。生产环境中redis的集群可以考虑使用Twitter开源的twemproxy,以及豌豆荚开源的codis,这两个项目都比较成熟,现在使用的公司很多。

redis-cluster的自动扩容、缩容机制

如何在不停掉Cluster集群环境的情况下,动态的往集群环境中增加主、从节点和动态的从集群环境中删除节点。

redis的动态扩容操作都是通过redis-trib.rb脚本文件来完成的

  1. [root@localhost cluster]# redis-trib

  

Cluster集群增加操作

  增加节点的顺序是先增加Master主节点,然后在增加Slave从节点。

  节点信息

  1. [root@localhost cluster]# ps -ef |grep redis
  2. root 5464 1 0 03:31 ? 00:00:00 redis-server 127.0.0.1:7000 [cluster]
  3. root 5469 1 0 03:31 ? 00:00:00 redis-server 127.0.0.1:7001 [cluster]
  4. root 5473 1 0 03:31 ? 00:00:00 redis-server 127.0.0.1:7002 [cluster]
  5. root 5478 1 0 03:31 ? 00:00:00 redis-server 127.0.0.1:7003 [cluster]
  6. root 5482 1 0 03:31 ? 00:00:00 redis-server 127.0.0.1:7004 [cluster]
  7. root 5486 1 0 03:31 ? 00:00:00 redis-server 127.0.0.1:7005 [cluster]
  8. root 5490 1 0 03:31 ? 00:00:00 redis-server 127.0.0.1:7006 [cluster]
  9. root 5495 1 0 03:32 ? 00:00:00 redis-server 127.0.0.1:7007 [cluster]
  10. root 5499 1 0 03:32 ? 00:00:00 redis-server 127.0.0.1:7008 [cluster]
  11. root 5813 5752 0 03:52 pts/1 00:00:00 grep redis

  连接集群:

  1. redis-cli -c -h 127.0.0.1 -p 7000

  查看集群节点详细信息,三主六从如下

  1. 127.0.0.1:7000> CLUSTER nodes
  2. 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001 master - 0 1557226729070 2 connected 5461-10922
  3. e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557226729070 8 connected
  4. 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557226730087 7 connected
  5. 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557226729578 6 connected
  6. c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557226730087 9 connected
  7. 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557226730598 5 connected
  8. cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002 master - 0 1557226730598 3 connected 10923-16383
  9. 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
  10. ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557226728566 4 connected

  1、动态增加Master主服务器节点

     1.1、创建目录7009(Master主节点文件夹)和7010、7011(Slave从节点文件夹),并从以前Cluster集群节点7000-7008任一节点中拷贝配置文件redis.conf到其目录下,注意修改端口号。

       1.2、启动7009和7010、7011目录下Redis实例,并查看效果。

 启动实例

  1. cd /data/cluster/7009
  2. redis-server redis.conf
  3. cd /data/cluster/7010
  4. redis-server redis.conf
  5. cd /data/cluster/7011
  6. redis-server redis.conf

  效果:新添加的redis服务,已加入集群里

  1. [root@localhost 7011]# ps -ef |grep redis
  2. root 5464 1 0 03:31 ? 00:00:01 redis-server 127.0.0.1:7000 [cluster]
  3. root 5469 1 0 03:31 ? 00:00:01 redis-server 127.0.0.1:7001 [cluster]
  4. root 5473 1 0 03:31 ? 00:00:01 redis-server 127.0.0.1:7002 [cluster]
  5. root 5478 1 0 03:31 ? 00:00:01 redis-server 127.0.0.1:7003 [cluster]
  6. root 5482 1 0 03:31 ? 00:00:01 redis-server 127.0.0.1:7004 [cluster]
  7. root 5486 1 0 03:31 ? 00:00:01 redis-server 127.0.0.1:7005 [cluster]
  8. root 5490 1 0 03:31 ? 00:00:01 redis-server 127.0.0.1:7006 [cluster]
  9. root 5495 1 0 03:32 ? 00:00:01 redis-server 127.0.0.1:7007 [cluster]
  10. root 5499 1 0 03:32 ? 00:00:01 redis-server 127.0.0.1:7008 [cluster]
  11. root 5953 1 0 04:06 ? 00:00:00 redis-server 127.0.0.1:7009 [cluster]
  12. root 5958 1 0 04:06 ? 00:00:00 redis-server 127.0.0.1:7010 [cluster]
  13. root 5962 1 0 04:06 ? 00:00:00 redis-server 127.0.0.1:7011 [cluster]
  14. root 5967 5935 0 04:07 pts/3 00:00:00 grep redis

  登录到7009的端口:

  1. redis-cli -c -h 127.0.0.1 -p 7009

  查看当前节点信息:

  1. 127.0.0.1:7009> info replication
  2. # Replication
  3. role:master
  4. connected_slaves:0
  5. master_repl_offset:0
  6. repl_backlog_active:0
  7. repl_backlog_size:1048576
  8. repl_backlog_first_byte_offset:0
  9. repl_backlog_histlen:0

  退出7009的端口,登录7010、7011的端口,查看节点信息:

  1. 127.0.0.1:7009> quit
  2. [root@localhost 7011]# redis-cli -c -h 127.0.0.1 -p 7010
  3. 127.0.0.1:7010> info replication
  4. # Replication
  5. role:master
  6. connected_slaves:0
  7. master_repl_offset:0
  8. repl_backlog_active:0
  9. repl_backlog_size:1048576
  10. repl_backlog_first_byte_offset:0
  11. repl_backlog_histlen:0
  12. 127.0.0.1:7010> quit
  13. [root@localhost 7011]# redis-cli -c -h 127.0.0.1 -p 7011
  14. 127.0.0.1:7011> info replication
  15. # Replication
  16. role:master
  17. connected_slaves:0
  18. master_repl_offset:0
  19. repl_backlog_active:0
  20. repl_backlog_size:1048576
  21. repl_backlog_first_byte_offset:0
  22. repl_backlog_histlen:0
  23. 127.0.0.1:7011>

  将7009主节点加入到Cluster集群

  1. redis-trib add-node 127.0.0.1 7009 127.0.0.1 7000

  添加后的信息:

  1. [root@localhost 7011]# redis-trib add-node 127.0.0.1 7009 127.0.0.1 7000
  2. [ERR] Wrong number of arguments for specified sub command
  3. [root@localhost 7011]# cd cd /data/cluster/
  4. -bash: cd: cd: No such file or directory
  5. [root@localhost 7011]# cd /data/cluster/
  6. [root@localhost cluster]# redis-trib add-node 127.0.0.1 7009 127.0.0.1 7000
  7. [ERR] Wrong number of arguments for specified sub command
  8. [root@localhost cluster]# redis-trib add-node 127.0.0.1:7009 127.0.0.1:7000
  9. >>> Adding node 127.0.0.1:7009 to cluster 127.0.0.1:7000
  10. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  11. M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
  12. slots:0-5460 (5461 slots) master
  13. 2 additional replica(s)
  14. M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
  15. slots:5461-10922 (5462 slots) master
  16. 2 additional replica(s)
  17. S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
  18. slots: (0 slots) slave
  19. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  20. S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
  21. slots: (0 slots) slave
  22. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  23. S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
  24. slots: (0 slots) slave
  25. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  26. S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
  27. slots: (0 slots) slave
  28. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  29. S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
  30. slots: (0 slots) slave
  31. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  32. M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
  33. slots:10923-16383 (5461 slots) master
  34. 2 additional replica(s)
  35. S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
  36. slots: (0 slots) slave
  37. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  38. [OK] All nodes agree about slots configuration.
  39. >>> Check for open slots...
  40. >>> Check slots coverage...
  41. [OK] All 16384 slots covered.
  42. >>> Send CLUSTER MEET to node 127.0.0.1:7009 to make it join the cluster.
  43. [OK] New node added correctly.
  44. [root@localhost cluster]#

  注意:当添加新节点成功以后,新的节点不会有任何数据,因为他没有分配任何的数据Slot(哈希slots),这一步需要手动操作

  查看当前节点数:

  1.   CLUSTER info
  1. 127.0.0.1:7000> CLUSTER info
  2. cluster_state:ok
  3. cluster_slots_assigned:16384
  4. cluster_slots_ok:16384
  5. cluster_slots_pfail:0
  6. cluster_slots_fail:0
  7. cluster_known_nodes:10 原来是九个,现在变成十个了
  8. cluster_size:3
  9. cluster_current_epoch:9
  10. cluster_my_epoch:1
  11. cluster_stats_messages_sent:16601
  12. cluster_stats_messages_received:16601

  cluster nodes验证:

  1. 127.0.0.1:7000> CLUSTER nodes
  2. 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001 master - 0 1557228003126 2 connected 5461-10922
  3. e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557228003126 8 connected
  4. 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557228002517 7 connected
  5. 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557228003024 6 connected
  6. c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557228001603 9 connected
  7. 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557228002517 5 connected
  8. cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002 master - 0 1557228002111 3 connected 10923-16383
  9. 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
  10. c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009 master - 0 1557228001908 0 connected
  11. ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557228002111 4 connected

  为7009Master主节点分配数据Slots,分配方法是从集群中知道任何一个主节点(因为只有Master主节点才有数据slots),然后对其进行重新分片工作

  1. redis-trib reshard 127.0.0.1:7000

  分配信息:

  1. [root@localhost cluster]# redis-trib reshard 127.0.0.1:7000
  2. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  3. M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
  4. slots:0-5460 (5461 slots) master
  5. 2 additional replica(s)
  6. M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
  7. slots:5461-10922 (5462 slots) master
  8. 2 additional replica(s)
  9. S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
  10. slots: (0 slots) slave
  11. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  12. S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
  13. slots: (0 slots) slave
  14. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  15. S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
  16. slots: (0 slots) slave
  17. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  18. S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
  19. slots: (0 slots) slave
  20. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  21. S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
  22. slots: (0 slots) slave
  23. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  24. M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
  25. slots:10923-16383 (5461 slots) master
  26. 2 additional replica(s)
  27. M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
  28. slots: (0 slots) master
  29. 0 additional replica(s)
  30. S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
  31. slots: (0 slots) slave
  32. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  33. [OK] All nodes agree about slots configuration.
  34. >>> Check for open slots...
  35. >>> Check slots coverage...
  36. [OK] All 16384 slots covered.
  37. How many slots do you want to move (from 1 to 16384)?

  输入:

  1. How many slots do you want to move (from 1 to 16384)? 1000 分配多少hash
  2. What is the receiving node ID? c80912f49bbd3787067eb4d622cd06cac3397a13 待分配redisid
  3. Please enter all the source node IDs.
  4. Type 'all' to use all the nodes as source nodes for the hash slots.
  5. Type 'done' once you entered all the source nodes IDs.
  6. Source node #1:all 选择从哪些redis中抽取槽,输入redis的id,all代表全部

  如下:已分配完成

  1. Resharding plan:
  2. Moving slot 5461 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  3. Moving slot 5462 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  4. Moving slot 5463 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  5. Moving slot 5464 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  6. Moving slot 5465 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  7. Moving slot 5466 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  8. Moving slot 5467 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  9. Moving slot 5468 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  10. Moving slot 5469 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  11. Moving slot 5470 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  12. Moving slot 5471 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  13. Moving slot 5472 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  14. Moving slot 5473 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  15. Moving slot 5474 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  16. 。。。

  输入:yes 同意分配

  1. CLUSTER nodes,查看7009已分配的哈希槽
  1. 127.0.0.1:7009> CLUSTER nodes
  2. e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557228755334 3 connected
  3. ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557228755334 1 connected
  4. 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000 master - 0 1557228756346 1 connected 333-5460
  5. c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009 myself,master - 0 0 10 connected 0-332 5461-5794 10923-11255
  6. 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557228756854 1 connected
  7. c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557228756854 3 connected
  8. 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005 slave c80912f49bbd3787067eb4d622cd06cac3397a13 0 1557228757360 10 connected
  9. 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001 master - 0 1557228755839 2 connected 5795-10922
  10. 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557228756346 2 connected
  11. cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002 master - 0 1557228755233 3 connected 11256-16383

动态增加Slave从服务器节点

  将7010、7011加入到集群中,但是并不分配hash槽。

  1. [root@localhost cluster]# redis-trib add-node 127.0.0.1:7010 127.0.0.1:7000
  2. >>> Adding node 127.0.0.1:7010 to cluster 127.0.0.1:7000
  3. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  4. M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
  5. slots:333-5460 (5128 slots) master
  6. 2 additional replica(s)
  7. M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
  8. slots:5795-10922 (5128 slots) master
  9. 1 additional replica(s)
  10. S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
  11. slots: (0 slots) slave
  12. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  13. S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
  14. slots: (0 slots) slave
  15. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  16. S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
  17. slots: (0 slots) slave
  18. replicates c80912f49bbd3787067eb4d622cd06cac3397a13
  19. S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
  20. slots: (0 slots) slave
  21. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  22. S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
  23. slots: (0 slots) slave
  24. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  25. M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
  26. slots:11256-16383 (5128 slots) master
  27. 2 additional replica(s)
  28. M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
  29. slots:0-332,5461-5794,10923-11255 (1000 slots) master
  30. 1 additional replica(s)
  31. S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
  32. slots: (0 slots) slave
  33. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  34. [OK] All nodes agree about slots configuration.
  35. >>> Check for open slots...
  36. >>> Check slots coverage...
  37. [OK] All 16384 slots covered.
  38. >>> Send CLUSTER MEET to node 127.0.0.1:7010 to make it join the cluster.
  39. [OK] New node added correctly.

  加入后,登录到7009端口,为其指定主节点(master)

  1. [root@localhost 7011]# redis-cli -c -h 127.0.0.1 -p 7010
  2. 127.0.0.1:7010> cluster replicate c80912f49bbd3787067eb4d622cd06cac3397a13(主节点7009id)
  3. OK

  7011同理:

  1. [root@localhost cluster]# redis-trib add-node 127.0.0.1:7011 127.0.0.1:7000
  2. >>> Adding node 127.0.0.1:7011 to cluster 127.0.0.1:7000
  3. >>> Performing Cluster Check (using node 127.0.0.1:7000)
  4. M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
  5. slots:333-5460 (5128 slots) master
  6. 2 additional replica(s)
  7. M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
  8. slots:5795-10922 (5128 slots) master
  9. 1 additional replica(s)
  10. S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
  11. slots: (0 slots) slave
  12. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  13. S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
  14. slots: (0 slots) slave
  15. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  16. S: 550255c17853778352ecf97f452c55cf5b267a5b 127.0.0.1:7010
  17. slots: (0 slots) slave
  18. replicates c80912f49bbd3787067eb4d622cd06cac3397a13
  19. S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
  20. slots: (0 slots) slave
  21. replicates c80912f49bbd3787067eb4d622cd06cac3397a13
  22. S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
  23. slots: (0 slots) slave
  24. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  25. S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
  26. slots: (0 slots) slave
  27. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  28. M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
  29. slots:11256-16383 (5128 slots) master
  30. 2 additional replica(s)
  31. M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
  32. slots:0-332,5461-5794,10923-11255 (1000 slots) master
  33. 2 additional replica(s)
  34. S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
  35. slots: (0 slots) slave
  36. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  37. [OK] All nodes agree about slots configuration.
  38. >>> Check for open slots...
  39. >>> Check slots coverage...
  40. [OK] All 16384 slots covered.
  41. >>> Send CLUSTER MEET to node 127.0.0.1:7011 to make it join the cluster.
  42. [OK] New node added correctly.
  43. [root@localhost cluster]#
  1. [root@localhost 7011]# redis-cli -c -h 127.0.0.1 -p 7011
  2. 127.0.0.1:7011> cluster replicate c80912f49bbd3787067eb4d622cd06cac3397a13
  3. OK

  添加完成后,查看集群信息:

  1. 127.0.0.1:7011> cluster nodes
  2. 550255c17853778352ecf97f452c55cf5b267a5b 127.0.0.1:7010 slave c80912f49bbd3787067eb4d622cd06cac3397a13 0 1557232681486 10 connected
  3. c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009 master - 0 1557232680480 10 connected 0-332 5461-5794 10923-11255
  4. 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557232679977 2 connected
  5. ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557232681989 1 connected
  6. 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001 master - 0 1557232681989 2 connected 5795-10922
  7. 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005 slave c80912f49bbd3787067eb4d622cd06cac3397a13 0 1557232681989 10 connected
  8. 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557232679977 1 connected
  9. cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002 master - 0 1557232680983 3 connected 11256-16383
  10. c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557232681486 3 connected
  11. 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000 master - 0 1557232680480 1 connected 333-5460
  12. e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557232680983 3 connected
  13. 472088b1f98e6da24824db7c9ce3373772e17b82 127.0.0.1:7011 myself,slave c80912f49bbd3787067eb4d622cd06cac3397a13 0 0 0 connected

  Cluster集群删除操作

  Cluster集群模式中动态的删除掉7009、7010、7011节点,即删除一个主节点和其附属的两个从节点,精简集群。删除的顺序是先删除Slave从节点,然后在删除Master主节点

1、动态删除Slave从服务器节点

            1.1、删除7010从节点,输入del-node命令,指定删除节点的IP地址和Port端口号,同时还要提供该从节点ID名称。

  1. [root@localhost cluster]# redis-trib del-node 127.0.0.1:7010 550255c17853778352ecf97f452c55cf5b267a5b

  删除成功信息

  1. >>> Removing node 550255c17853778352ecf97f452c55cf5b267a5b from cluster 127.0.0.1:7010
  2. >>> Sending CLUSTER FORGET messages to the cluster...
  3. >>> SHUTDOWN the node.
  4. [root@localhost cluster]#

      1.1、删除7011从节点,输入del-node命令,指定删除节点的IP地址和Port端口号,同时还要提供该从节点ID名称。

  1. [root@localhost cluster]# redis-trib del-node 127.0.0.1:7011 472088b1f98e6da24824db7c9ce3373772e17b82

  删除成功信息

  1. >>> Removing node 472088b1f98e6da24824db7c9ce3373772e17b82 from cluster 127.0.0.1:7011
  2. >>> Sending CLUSTER FORGET messages to the cluster...
  3. >>> SHUTDOWN the node.

查看当前集群节点,发现已经没了7010、7011这两个节点

  1. [root@localhost 7011]# redis-cli -c -h 127.0.0.1 -p 7009
  2. 127.0.0.1:7009> cluster nodes
  3. e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557233568335 3 connected
  4. ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557233567832 1 connected
  5. 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000 master - 0 1557233568838 1 connected 333-5460
  6. c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009 myself,master - 0 0 10 connected 0-332 5461-5794 10923-11255
  7. 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557233569341 1 connected
  8. c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557233569846 3 connected
  9. 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005 slave c80912f49bbd3787067eb4d622cd06cac3397a13 0 1557233568838 10 connected
  10. 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001 master - 0 1557233569341 2 connected 5795-10922
  11. 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557233567832 2 connected
  12. cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002 master - 0 1557233569341 3 connected 11256-16383
  13. 127.0.0.1:7009>

  动态删除Master主服务器节点

  要想删除Master主节点,可能要繁琐一些。因为在Master主节点上有数据槽(slots),为了保证数据的不丢失,必须把这些数据槽迁移到其他Master主节点上,然后在删除主节点。

  不移除hash槽时直接删除:

  1. [root@localhost cluster]# redis-trib del-node 127.0.0.1:7009 c80912f49bbd3787067eb4d622cd06cac3397a13
  2. >>> Removing node c80912f49bbd3787067eb4d622cd06cac3397a13 from cluster 127.0.0.1:7009
  3. [ERR] Node 127.0.0.1:7009 is not empty! Reshard data away and try again. 报错,必须先移出hash


        重新分片,把要删除的Master主节点的数据槽移动到其他Master主节点上,以免数据丢失。

  1. [root@localhost cluster]# redis-trib reshard 127.0.0.1:7009

  分片信息:

  1. >>> Performing Cluster Check (using node 127.0.0.1:7009)
  2. M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
  3. slots:0-332,5461-5794,10923-11255 (1000 slots) master
  4. 1 additional replica(s)
  5. S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
  6. slots: (0 slots) slave
  7. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  8. S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
  9. slots: (0 slots) slave
  10. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  11. M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
  12. slots:333-5460 (5128 slots) master
  13. 2 additional replica(s)
  14. S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
  15. slots: (0 slots) slave
  16. replicates 4381850849cd6bb3cae49494a08277c77bfa7720
  17. S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
  18. slots: (0 slots) slave
  19. replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
  20. S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
  21. slots: (0 slots) slave
  22. replicates c80912f49bbd3787067eb4d622cd06cac3397a13
  23. M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
  24. slots:5795-10922 (5128 slots) master
  25. 1 additional replica(s)
  26. S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
  27. slots: (0 slots) slave
  28. replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
  29. M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
  30. slots:11256-16383 (5128 slots) master
  31. 2 additional replica(s)
  32. [OK] All nodes agree about slots configuration.
  33. >>> Check for open slots...
  34. >>> Check slots coverage...
  35. [OK] All 16384 slots covered.
  36. How many slots do you want to move (from 1 to 16384)?

  移除多少槽如图:创建输入1000,这里也输入1000

  1. How many slots do you want to move (from 1 to 16384)? 1000
  2. What is the receiving node ID? cdf1c9036431e82e125c5fc87b91b425bccdf0dc(接收hash槽的id
  3. Please enter all the source node IDs.
  4. Type 'all' to use all the nodes as source nodes for the hash slots.
  5. Type 'done' once you entered all the source nodes IDs.
  6. Source node #1:c80912f49bbd3787067eb4d622cd06cac3397a13 (移除槽的id这里是7009节点的id)可以一次性移出多个
  7. Source node #2:done(没有其他要移除的hash槽,输入done执行)
  8.  
  9. Ready to move 999 slots.
  10. Source nodes:
  11. M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
  12. slots:0-332,5461-5794,10923-11255 (1000 slots) master
  13. 1 additional replica(s)
  14. Destination node:
  15. M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
  16. slots:11256-16383 (5128 slots) master
  17. 2 additional replica(s)
  18. Resharding plan:
  19. Moving slot 0 from c80912f49bbd3787067eb4d622cd06cac3397a13
  20. Moving slot 1 from c80912f49bbd3787067eb4d622cd06cac3397a13
  21. Moving slot 2 from c80912f49bbd3787067eb4d622cd06cac3397a13
  22. Moving slot 3 from c80912f49bbd3787067eb4d622cd06cac3397a13
  23. Moving slot 4 from c80912f49bbd3787067eb4d622cd06cac3397a13
  24. Moving slot 5 from c80912f49bbd3787067eb4d622cd06cac3397a13
  25. Moving slot 6 from c80912f49bbd3787067eb4d622cd06cac3397a13
    ...  

Moving slot 11253 from c80912f49bbd3787067eb4d622cd06cac3397a13
Moving slot 11254 from c80912f49bbd3787067eb4d622cd06cac3397a13
Do you want to proceed with the proposed reshard plan (yes/no)? yes

  输入:yes,移除hash槽成功

  1. Moving slot 11244 from 127.0.0.1:7009 to 127.0.0.1:7002:
  2. Moving slot 11245 from 127.0.0.1:7009 to 127.0.0.1:7002:
  3. Moving slot 11246 from 127.0.0.1:7009 to 127.0.0.1:7002:
  4. Moving slot 11247 from 127.0.0.1:7009 to 127.0.0.1:7002:
  5. Moving slot 11248 from 127.0.0.1:7009 to 127.0.0.1:7002:
  6. Moving slot 11249 from 127.0.0.1:7009 to 127.0.0.1:7002:
  7. Moving slot 11250 from 127.0.0.1:7009 to 127.0.0.1:7002:
  8. Moving slot 11251 from 127.0.0.1:7009 to 127.0.0.1:7002:
  9. Moving slot 11252 from 127.0.0.1:7009 to 127.0.0.1:7002:
  10. Moving slot 11253 from 127.0.0.1:7009 to 127.0.0.1:7002:
  11. Moving slot 11254 from 127.0.0.1:7009 to 127.0.0.1:7002:
  12. [root@localhost cluster]#

  当前7009主节点已经没有数据槽了,而7002增加了1000个槽

  1. 127.0.0.1:7000> cluster nodes
  2. 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001 master - 0 1557234298666 2 connected 5795-10922
  3. e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557234298666 11 connected
  4. 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557234296650 7 connected
  5. 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005 slave c80912f49bbd3787067eb4d622cd06cac3397a13 0 1557234298666 10 connected
  6. c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557234297155 11 connected
  7. 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557234298162 5 connected
  8. cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002 master - 0 1557234296650 11 connected 0-332 5461-5794 10923-11254 11256-16383
  9. 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000 myself,master - 0 0 1 connected 333-5460
  10. c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009 master - 0 1557234297155 10 connected 11255
  11. ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557234297658 4 connected

  然后,删除节点即可,删除7009主节点,提供要删除节点的IP地址和Port端口,当然还有要删除的节点的ID。

  1. redis-trib del-node 127.0.0.1:7009 c80912f49bbd3787067eb4d622cd06cac3397a13

  删除成功:

  1. >>> Removing node c80912f49bbd3787067eb4d622cd06cac3397a13 from cluster 127.0.0.1:7009
  2. >>> Sending CLUSTER FORGET messages to the cluster...
  3. >>> SHUTDOWN the node.

  查看集群节点:已经没有7009节点了

  1. [root@localhost 7011]# redis-cli -c -h 127.0.0.1 -p 7000
  2. 127.0.0.1:7000> cluster nodes
  3. 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001 master - 0 1557234776145 2 connected 5795-10922
  4. e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557234776647 11 connected
  5. 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557234776145 7 connected
  6. 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557234777151 11 connected
  7. c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557234777151 11 connected
  8. 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557234777655 5 connected
  9. cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002 master - 0 1557234776647 11 connected 0-332 5461-5794 10923-16383
  10. 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000 myself,master - 0 0 1 connected 333-5460
  11. ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557234778159 4 connected

  上面就操作完了,由于主从复制和哨兵模式这两个集群模式由于不能动态扩容,而且主节点之间(有多个主节点的情况)数据完全一样,导致了主节点的容量成了整个集群的瓶颈,如果想扩展集群容量,必须扩展主节点的容量。由于以上的问题,redis在3.0开始Cluster集群模式,这个模式在主节点之间数据是不一样的,数据也可以根据需求自动转向其他节点。这样就可以实现横向动态扩容,新增加的主从节点,用于存储新的数据则可,对以前的节点的数据不会有任何影响,配置也很简单,这才是我们所需要的集群模式。

redis(6)--redis集群之分片机制(redis-cluster)的更多相关文章

  1. 通过 Docker 部署 Redis 6.x 集群

    要点步骤总结: # 这里演示使用同一台主机上 # 创建各节点存储路径 mkdir -p /opt/redis/{7000,7001,7002,7003,7004,7005} # 创建各节点配置文件 c ...

  2. Redis 5.0 集群搭建

    Redis 5.0 集群搭建 单机版的 Redis 搭建 https://www.jianshu.com/p/b68e68bbd725 /usr/local/目录 mkdir redis-cluste ...

  3. redis集群与分片(1)-redis服务器集群、客户端分片

    下面是来自知乎大神的一段说明,个人觉得非常清晰,就收藏了. 为什么集群? 通常,为了提高网站响应速度,总是把热点数据保存在内存中而不是直接从后端数据库中读取.Redis是一个很好的Cache工具.大型 ...

  4. Redis+TwemProxy(nutcracker)集群方案部署记录

    Twemproxy 又称nutcracker ,是一个memcache.Redis协议的轻量级代理,一个用于sharding 的中间件.有了Twemproxy,客户端不直接访问Redis服务器,而是通 ...

  5. Redis+Twemproxy+HAProxy集群(转) 干货

    原文地址:Redis+Twemproxy+HAProxy集群  干货 Redis主从模式 Redis数据库与传统数据库属于并行关系,也就是说传统的关系型数据库保存的是结构化数据,而Redis保存的是一 ...

  6. Redis系列(二):Redis高可用集群

    一.集群模式 Redis集群是一个由多个主从节点组成的高可用集群,它具有复制.高可用和分片等特性 二.集群部署 1.环境 3台主机分别是: 192.168.160.146 192.168.160.15 ...

  7. 7.redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?

    作者:中华石杉 面试题 redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗? 面试官心理分析 在前几年, ...

  8. 超详细,多图文介绍redis集群方式并搭建redis伪集群

    超详细,多图文介绍redis集群方式并搭建redis伪集群 超多图文,对新手友好度极好.敲命令的过程中,难免会敲错,但为了截好一张合适的图,一旦出现一点问题,为了好的演示效果,就要从头开始敲.且看且珍 ...

  9. 三千字介绍Redis主从+哨兵+集群

    一.Redis持久化策略 1.RDB 每隔几分钟或者一段时间会将redis内存中的数据全量的写入到一个文件中去. 优点: 因为他是每隔一段时间的全量备份,代表了每个时间段的数据.所以适合做冷备份. R ...

随机推荐

  1. pat 1124 Raffle for Weibo Followers(20 分)

    1124 Raffle for Weibo Followers(20 分) John got a full mark on PAT. He was so happy that he decided t ...

  2. nyoj 92-图像有用区域 (BFS)

    92-图像有用区域 内存限制:64MB 时间限制:3000ms 特判: No 通过数:4 提交数:12 难度:4 题目描述: “ACKing”同学以前做一个图像处理的项目时,遇到了一个问题,他需要摘取 ...

  3. 【python测试开发栈】带你彻底搞明白python3编码原理

    在之前的文章中,我们介绍过编码格式的发展史:[文章传送门-todo].今天我们通过几个例子,来彻底搞清楚python3中的编码格式原理,这样你之后写python脚本时碰到编码问题,才能有章可循. 我们 ...

  4. django_2:模板

    使用模板变量: 在html文件中,{{title}}即为模板变量, 在view.py文件中,render函数,增加第三个参数,以字典形式给值. def index(req): return rende ...

  5. 【NServiceBus】什么是Saga,Saga能做什么

    前言           Saga单词翻译过来是指尤指古代挪威或冰岛讲述冒险经历和英雄业绩的长篇故事,对,这里强调长篇故事.许多系统都存在长时间运行的业务流程,NServiceBus使用基于事件驱动的 ...

  6. ArrayList和LinkedList的源码学习,理解两者在插入、删除、和查找的性能差异

    List的使用 List的子类 1). ArrayList 数据结构:数组 2). Vector 数据结构:数组 3). LinkedList 数据结构:循环双向链表 ArrayList .Vecto ...

  7. GentOS 7 安装步骤

    附上原作者的博客网址: https://blog.csdn.net/qq_42570879/article/details/82853708 1.CentOS下载CentOS是免费版,推荐在官网上直接 ...

  8. Ubuntu 16.04安装ROS Kinetic详细教程 | Tutorial to Install and Configure ROS Kinetic on Ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/e2780b93/,欢迎阅读! Tutorial to Install and Configure ROS Kinetic on U ...

  9. 如何使用C#调用C++类虚函数(即动态内存调用)

      本文讲解如何使用C#调用只有.h头文件的c++类的虚函数(非实例函数,因为非虚函数不存在于虚函数表,无法通过类对象偏移计算地址,除非用export导出,而gcc默认是全部导出实例函数,这也是为什么 ...

  10. 2019-10-29:渗透测试,基础学习,sqlmap文件读取,写入,dnslog盲注作用,mssql手工注入,笔记

    sqlmap参数--file-read,从数据库服务器中读取文件--file-write,--file-dest,把文件上传到数据库服务器中 dnslog平台的学习和它在盲注中的应用1,判断注入点2, ...