zoukankan      html  css  js  c++  java
  • redis(6)--redis集群之分片机制(redis-cluster)

    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..创建存放多个实例的目录

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

    2.修改配置文件

    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

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

      

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

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

    3.启动9个redis实例

    cd /data/cluster/7000
    redis-server redis.conf
    cd /data/cluster/7001
    redis-server redis.conf
    cd /data/cluster/7002
    redis-server redis.conf
    cd /data/cluster/7003
    redis-server redis.conf
    cd /data/cluster/7004
    redis-server redis.conf
    cd /data/cluster/7005
    redis-server redis.conf
    cd /data/cluster/7006
    redis-server redis.conf
    cd /data/cluster/7007
    redis-server redis.conf
    cd /data/cluster/7008
    redis-server redis.conf
    

      查看进程否存在

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

      

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

    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

    gem install -l redis-3.0.0.gem  

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

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

    创建集群:

    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 就会将这份配置应用到集群当中:

    >>> Creating cluster
    >>> Performing hash slots allocation on 9 nodes...
    Using 3 masters:
    127.0.0.1:7000
    127.0.0.1:7001
    127.0.0.1:7002
    Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
    Adding replica 127.0.0.1:7004 to 127.0.0.1:7000
    Adding replica 127.0.0.1:7005 to 127.0.0.1:7001
    Adding replica 127.0.0.1:7006 to 127.0.0.1:7001
    Adding replica 127.0.0.1:7007 to 127.0.0.1:7002
    Adding replica 127.0.0.1:7008 to 127.0.0.1:7002
    M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
    slots:0-5460 (5461 slots) master
    M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
    slots:5461-10922 (5462 slots) master
    M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
    slots:10923-16383 (5461 slots) master
    S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
    replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
    replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
    replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
    replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
    replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
    replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    Can I set the above configuration? (type 'yes' to accept):
    

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

    Can I set the above configuration? (type 'yes' to accept): yes
    >>> Nodes configuration updated
    >>> Assign a different config epoch to each node
    >>> Sending CLUSTER MEET messages to join the cluster
    Waiting for the cluster to join....
    >>> Performing Cluster Check (using node 127.0.0.1:7000)
    M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
       slots:0-5460 (5461 slots) master
       2 additional replica(s)
    M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
       slots:5461-10922 (5462 slots) master
       2 additional replica(s)
    S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
       slots: (0 slots) slave
       replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
       slots: (0 slots) slave
       replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
       slots:10923-16383 (5461 slots) master
       2 additional replica(s)
    S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [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"

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

    复制代码
    [root@localhost 7008]#  redis-trib help
    Usage: redis-trib <command> <options> <arguments ...>
    
      set-timeout     host:port milliseconds
      add-node        new_host:new_port existing_host:existing_port
                      --master-id <arg>
                      --slave
      fix             host:port
      help            (show this help)
      del-node        host:port node_id
      import          host:port
                      --from <arg>
      check           host:port
      call            host:port command arg arg .. arg
      create          host1:port1 ... hostN:portN
                      --replicas <arg>
      reshard         host:port
                      --yes
                      --to <arg>
                      --from <arg>
                      --slots <arg>
    
    For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
    [root@localhost 7008]# 
    复制代码

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

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

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

    故障转移测试:

    127.0.0.1:7001> KEYS *
    1) "name"
    127.0.0.1:7001> get name
    "lf"
    127.0.0.1:7001> 

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

    复制代码
    [root@localhost 7008]#  ps -ef | grep 7000
    root      4168     1  0 11:49 ?        00:00:03 redis-server *:7000 [cluster]
    root      4385  4361  0 12:39 pts/3    00:00:00 grep 7000
    [root@localhost 7008]#  kill 4168
    [root@localhost 7008]#  ps -ef | grep 7000
    root      4387  4361  0 12:39 pts/3    00:00:00 grep 7000
    [root@localhost 7008]# redis-cli -c -p 7001
    127.0.0.1:7001> get name
    "lf"
    127.0.0.1:7001> 
    复制代码

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

    复制代码
    [root@localhost 7008]# redis-cli -c -p 7001 cluster nodes
    2d03b862083ee1b1785dba5db2987739cf3a80eb 127.0.0.1:7001 myself,master - 0 0 2 connected 5461-10922
    0456869a2c2359c3e06e065a09de86df2e3135ac 127.0.0.1:7002 master - 0 1428295271619 3 connected 10923-16383
    37b251500385929d5c54a005809377681b95ca90 127.0.0.1:7003 master - 0 1428295270603 7 connected 0-5460
    e2e2e692c40fc34f700762d1fe3a8df94816a062 127.0.0.1:7004 slave 2d03b862083ee1b1785dba5db2987739cf3a80eb 0 1428295272642 5 connected
    2774f156af482b4f76a5c0bda8ec561a8a1719c2 127.0.0.1:7000 master,fail - 1428295159553 1428295157205 1 disconnected
    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脚本文件来完成的

    [root@localhost cluster]# redis-trib
    

      

    Cluster集群增加操作

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

      节点信息

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

      连接集群:

    redis-cli -c -h 127.0.0.1 -p 7000
    

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

    127.0.0.1:7000> CLUSTER nodes
    91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001 master - 0 1557226729070 2 connected 5461-10922
    e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557226729070 8 connected
    5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557226730087 7 connected
    30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557226729578 6 connected
    c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557226730087 9 connected
    90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557226730598 5 connected
    cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002 master - 0 1557226730598 3 connected 10923-16383
    4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
    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实例,并查看效果。

     启动实例

    cd /data/cluster/7009
    redis-server redis.conf
    cd /data/cluster/7010
    redis-server redis.conf
    cd /data/cluster/7011
    redis-server redis.conf
    

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

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

      登录到7009的端口:

    redis-cli -c -h 127.0.0.1 -p 7009
    

      查看当前节点信息:

    127.0.0.1:7009> info replication
    # Replication
    role:master
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    

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

    127.0.0.1:7009> quit
    [root@localhost 7011]# redis-cli -c -h 127.0.0.1 -p 7010
    127.0.0.1:7010> info replication
    # Replication
    role:master
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    127.0.0.1:7010> quit
    [root@localhost 7011]# redis-cli -c -h 127.0.0.1 -p 7011
    127.0.0.1:7011> info replication
    # Replication
    role:master
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    127.0.0.1:7011> 
    

      将7009主节点加入到Cluster集群

    redis-trib add-node 127.0.0.1 7009 127.0.0.1 7000
    

      添加后的信息:

    [root@localhost 7011]# redis-trib add-node 127.0.0.1 7009 127.0.0.1 7000
    [ERR] Wrong number of arguments for specified sub command
    [root@localhost 7011]# cd cd /data/cluster/
    -bash: cd: cd: No such file or directory
    [root@localhost 7011]# cd /data/cluster/
    [root@localhost cluster]# redis-trib add-node 127.0.0.1 7009 127.0.0.1 7000
    [ERR] Wrong number of arguments for specified sub command
    [root@localhost cluster]# redis-trib add-node 127.0.0.1:7009 127.0.0.1:7000
    >>> Adding node 127.0.0.1:7009 to cluster 127.0.0.1:7000
    >>> Performing Cluster Check (using node 127.0.0.1:7000)
    M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
       slots:0-5460 (5461 slots) master
       2 additional replica(s)
    M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
       slots:5461-10922 (5462 slots) master
       2 additional replica(s)
    S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
       slots: (0 slots) slave
       replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
       slots: (0 slots) slave
       replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
       slots:10923-16383 (5461 slots) master
       2 additional replica(s)
    S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    >>> Send CLUSTER MEET to node 127.0.0.1:7009 to make it join the cluster.
    [OK] New node added correctly.
    [root@localhost cluster]# 
    

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

      查看当前节点数:

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

      cluster nodes验证:

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

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

    redis-trib reshard 127.0.0.1:7000
    

      分配信息:

    [root@localhost cluster]# redis-trib reshard 127.0.0.1:7000
    >>> Performing Cluster Check (using node 127.0.0.1:7000)
    M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
       slots:0-5460 (5461 slots) master
       2 additional replica(s)
    M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
       slots:5461-10922 (5462 slots) master
       2 additional replica(s)
    S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
       slots: (0 slots) slave
       replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
       slots: (0 slots) slave
       replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
       slots:10923-16383 (5461 slots) master
       2 additional replica(s)
    M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
       slots: (0 slots) master
       0 additional replica(s)
    S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    How many slots do you want to move (from 1 to 16384)? 
    

      输入:

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

      如下:已分配完成

    Resharding plan:
        Moving slot 5461 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5462 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5463 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5464 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5465 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5466 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5467 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5468 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5469 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5470 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5471 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5472 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5473 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
        Moving slot 5474 from 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    。。。
    

      输入:yes 同意分配

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

    动态增加Slave从服务器节点

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

    [root@localhost cluster]# redis-trib add-node 127.0.0.1:7010 127.0.0.1:7000
    >>> Adding node 127.0.0.1:7010 to cluster 127.0.0.1:7000
    >>> Performing Cluster Check (using node 127.0.0.1:7000)
    M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
       slots:333-5460 (5128 slots) master
       2 additional replica(s)
    M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
       slots:5795-10922 (5128 slots) master
       1 additional replica(s)
    S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
       slots: (0 slots) slave
       replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
       slots: (0 slots) slave
       replicates c80912f49bbd3787067eb4d622cd06cac3397a13
    S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
       slots:11256-16383 (5128 slots) master
       2 additional replica(s)
    M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
       slots:0-332,5461-5794,10923-11255 (1000 slots) master
       1 additional replica(s)
    S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    >>> Send CLUSTER MEET to node 127.0.0.1:7010 to make it join the cluster.
    [OK] New node added correctly.
    

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

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

      7011同理:

    [root@localhost cluster]# redis-trib add-node 127.0.0.1:7011 127.0.0.1:7000
    >>> Adding node 127.0.0.1:7011 to cluster 127.0.0.1:7000
    >>> Performing Cluster Check (using node 127.0.0.1:7000)
    M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
       slots:333-5460 (5128 slots) master
       2 additional replica(s)
    M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
       slots:5795-10922 (5128 slots) master
       1 additional replica(s)
    S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
       slots: (0 slots) slave
       replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    S: 550255c17853778352ecf97f452c55cf5b267a5b 127.0.0.1:7010
       slots: (0 slots) slave
       replicates c80912f49bbd3787067eb4d622cd06cac3397a13
    S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
       slots: (0 slots) slave
       replicates c80912f49bbd3787067eb4d622cd06cac3397a13
    S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
       slots:11256-16383 (5128 slots) master
       2 additional replica(s)
    M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
       slots:0-332,5461-5794,10923-11255 (1000 slots) master
       2 additional replica(s)
    S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    >>> Send CLUSTER MEET to node 127.0.0.1:7011 to make it join the cluster.
    [OK] New node added correctly.
    [root@localhost cluster]# 
    [root@localhost 7011]# redis-cli -c -h 127.0.0.1 -p 7011
    127.0.0.1:7011> cluster replicate c80912f49bbd3787067eb4d622cd06cac3397a13
    OK
    

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

    127.0.0.1:7011> cluster nodes
    550255c17853778352ecf97f452c55cf5b267a5b 127.0.0.1:7010 slave c80912f49bbd3787067eb4d622cd06cac3397a13 0 1557232681486 10 connected
    c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009 master - 0 1557232680480 10 connected 0-332 5461-5794 10923-11255
    5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006 slave 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 0 1557232679977 2 connected
    ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557232681989 1 connected
    91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001 master - 0 1557232681989 2 connected 5795-10922
    30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005 slave c80912f49bbd3787067eb4d622cd06cac3397a13 0 1557232681989 10 connected
    90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004 slave 4381850849cd6bb3cae49494a08277c77bfa7720 0 1557232679977 1 connected
    cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002 master - 0 1557232680983 3 connected 11256-16383
    c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557232681486 3 connected
    4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000 master - 0 1557232680480 1 connected 333-5460
    e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007 slave cdf1c9036431e82e125c5fc87b91b425bccdf0dc 0 1557232680983 3 connected
    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名称。

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

      删除成功信息

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

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

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

      删除成功信息

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

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

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

      动态删除Master主服务器节点

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

      不移除hash槽时直接删除:

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


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

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

      分片信息:

    >>> Performing Cluster Check (using node 127.0.0.1:7009)
    M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
       slots:0-332,5461-5794,10923-11255 (1000 slots) master
       1 additional replica(s)
    S: e3c0e70a3546bad0e5e8fb9ec97fdb7ef15259ce 127.0.0.1:7007
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: ffaa09343e8852e670c4b217a7f9d9400c04fa18 127.0.0.1:7003
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    M: 4381850849cd6bb3cae49494a08277c77bfa7720 127.0.0.1:7000
       slots:333-5460 (5128 slots) master
       2 additional replica(s)
    S: 90658556651144ed4f46c4a4b52bc0f1b4a9b84f 127.0.0.1:7004
       slots: (0 slots) slave
       replicates 4381850849cd6bb3cae49494a08277c77bfa7720
    S: c6218645bea714109b2c11a412ea995f671e14b1 127.0.0.1:7008
       slots: (0 slots) slave
       replicates cdf1c9036431e82e125c5fc87b91b425bccdf0dc
    S: 30d747404f9da8d6b2ad49788b5238205a23c1f3 127.0.0.1:7005
       slots: (0 slots) slave
       replicates c80912f49bbd3787067eb4d622cd06cac3397a13
    M: 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba 127.0.0.1:7001
       slots:5795-10922 (5128 slots) master
       1 additional replica(s)
    S: 5fa3a168bf8315252e2da49aa626e9d723660645 127.0.0.1:7006
       slots: (0 slots) slave
       replicates 91fd3b872ccb9ca1c975badbbadb92f8cdb6aeba
    M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
       slots:11256-16383 (5128 slots) master
       2 additional replica(s)
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    How many slots do you want to move (from 1 to 16384)? 
    

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

    How many slots do you want to move (from 1 to 16384)? 1000
    What is the receiving node ID? cdf1c9036431e82e125c5fc87b91b425bccdf0dc(接收hash槽的id)
    Please enter all the source node IDs.
      Type 'all' to use all the nodes as source nodes for the hash slots.
      Type 'done' once you entered all the source nodes IDs.
    Source node #1:c80912f49bbd3787067eb4d622cd06cac3397a13 (移除槽的id这里是7009节点的id)可以一次性移出多个
    Source node #2:done(没有其他要移除的hash槽,输入done执行)
    
    Ready to move 999 slots.
      Source nodes:
        M: c80912f49bbd3787067eb4d622cd06cac3397a13 127.0.0.1:7009
       slots:0-332,5461-5794,10923-11255 (1000 slots) master
       1 additional replica(s)
      Destination node:
        M: cdf1c9036431e82e125c5fc87b91b425bccdf0dc 127.0.0.1:7002
       slots:11256-16383 (5128 slots) master
       2 additional replica(s)
      Resharding plan:
        Moving slot 0 from c80912f49bbd3787067eb4d622cd06cac3397a13
        Moving slot 1 from c80912f49bbd3787067eb4d622cd06cac3397a13
        Moving slot 2 from c80912f49bbd3787067eb4d622cd06cac3397a13
        Moving slot 3 from c80912f49bbd3787067eb4d622cd06cac3397a13
        Moving slot 4 from c80912f49bbd3787067eb4d622cd06cac3397a13
        Moving slot 5 from c80912f49bbd3787067eb4d622cd06cac3397a13
        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槽成功

    Moving slot 11244 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11245 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11246 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11247 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11248 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11249 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11250 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11251 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11252 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11253 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    Moving slot 11254 from 127.0.0.1:7009 to 127.0.0.1:7002: 
    [root@localhost cluster]# 
    

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

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

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

    redis-trib del-node 127.0.0.1:7009 c80912f49bbd3787067eb4d622cd06cac3397a13
    

      删除成功:

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

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

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

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

  • 相关阅读:
    FireFox 火狐浏览器 新标签页的常用网站恢复默认设置
    有关BT下载的Tracker
    优化分页展示
    导航条
    Bootstrap栅格系统
    分页器
    浅谈深拷贝和浅拷贝
    浅谈==和===
    浅谈typeof 和instanceof
    浅谈JavaScript中的this
  • 原文地址:https://www.cnblogs.com/flgb/p/10810269.html
Copyright © 2011-2022 走看看