Redis cluster搭建和redis-trib工具介绍

未来已来2018-09-18 09:15

本文来自网易云社区


作者:乔安然

1. Redis安装启动

  • 安装

    到redis官网下载redis3.0安装包,以linux为例:

    $ wget http://download.redis.io/releases/redis-3.2.3.tar.gz
    $ tar xzf redis-3.2.3.tar.gz
    $ cd redis-3.2.3
    $ make
    $ make install
    
  • 配置

    以3台机器搭建6个节点组成3主3从集群,每台机器上启动两个实例,以10.148.195.90机器为例,两个redis实例端口分别为6379、6380:

    1. 先创建redis相关目录(/etc/redis /usr/local/redis)
      etc: 存放redis配置文件
      usr:存放redis数据文件
      mkdir -p /etc/redis
      mkdir -p /usr/local/redis/6379
      mkdir -p /usr/local/redis/6380
      cp redis.conf /etc/redis/6379.conf
      cp redis.conf /etc/redis/6380.conf
      
    2. 修改配置文件,如修改6379.conf

      port 6379
      #绑定本机ip
      bind 10.148.195.90 127.0.0.1
      #以守护进程运行
      daemonize yes
      #数据文件存放目录
      dir /usr/local/redis/6379
      

      集群相关配置

      #开启集群 (637行左右)
      cluster-enabled yes
      #节点配置文件(645行)
      cluster-config-file 6379.conf
      #节点连接超时时间(毫秒为单位,约651行)
      cluster-node-timeout 5000
      #开启aof持久化
      appendonly yes
      

      参考上面配置修改6380相关配置,其他机器重复上述配置。

    3. 修改启动脚本 拷贝源码包中utils文件夹内的redis_init_script,修改端口配置

      #!/bin/sh
      #
      # Simple Redis init.d script conceived to work on Linux systems
      # as it does use of the /proc filesystem.
      
      REDISPORT=6379
      EXEC=/usr/local/bin/redis-server
      CLIEXEC=/usr/local/bin/redis-cli
      
      PIDFILE=/var/run/redis_${REDISPORT}.pid
      CONF="/etc/redis/${REDISPORT}.conf"
      
      case "$1" in
          start)
              if [ -f $PIDFILE ]
              then
                      echo "$PIDFILE exists, process is already running or crashed"
              else
                      echo "Starting Redis server..."
                      $EXEC $CONF
              fi
              ;;
          stop)
              if [ ! -f $PIDFILE ]
              then
                      echo "$PIDFILE does not exist, process is not running"
              else
                      PID=$(cat $PIDFILE)
                      echo "Stopping ..."
                      $CLIEXEC -p $REDISPORT shutdown
                      while [ -x /proc/${PID} ]
                      do
                          echo "Waiting for Redis to shutdown ..."
                          sleep 1
                      done
                      echo "Redis stopped"
              fi
              ;;
          *)
              echo "Please use start or stop as first argument"
              ;;
      esac
      

      调用脚本将各个redis实例启动

2. 创建集群


使用redis源码中提供的脚步工具创建集群,脚步工具需要安装ruby环境


  • 安装ruby

    以debian系统为例

    apt-get install ruby
    apt-get install rubygem
    gem install redis
    
  • 创建集群 我们使用redis-trib.rb来创建redis cluster集群,进入源码包src目录
    ./redis-trib.rb create --replicas 1 10.180.195.124:6379 10.180.195.124:6380 10.180.195.125:6379 10.180.195.125:6380 10.180.195.126:6379 10.180.195.126:6380
    
    当出现如下表示创建成功。
    >>> Creating cluster  
    Connecting to node 10.180.195.124:6379: OK  
    Connecting to node 10.180.195.124:6380: OK  
    Connecting to node 10.180.195.125:6379: OK  
    Connecting to node 10.180.195.125:6380: OK  
    Connecting to node 10.180.195.126:6379: OK  
    Connecting to node 10.180.195.126:6380: OK  
    >>> Performing hash slots allocation on 6 nodes...
    ...
    


3. redis-trib.rb工具使用


  • 添加节点

    添加节点就是添加新的空节点再迁移一部分数据到新节点,分成两种:

    1. 添加主节点 命令:
      ./redis-trib.rub add-node 10.180.195.127:6379 10.180.195.126:6379
      
      第一个参数是新添加的主节点,第二个参数是集群的任一节点地址。 添加完成后可以使用集群命令cluster node 查看所有节点
      10.180.195.124:6379> cluster nodes
      989cbf176d760c5a492d2f182a1e3b7c79d73ab3 10.180.195.125:6379 slave 1e17db47902c9467b46fc47f45eaf0989ed6d290 0 1472191974216 12 connected
      4e8c3b8a02406a3afaf606d345b8c117b0f01fed :0 slave,fail,noaddr 989cbf176d760c5a492d2f182a1e3b7c79d73ab3 1471928835942 1471928834839 8 disconnected
      4548f5da38cc93ed7888d946b5db11ee8d7ee128 10.180.195.125:6380 slave 0b2bfc904c4062badcd6e497254abc1eea3ce161 0 1472191973715 7 connected
      f0be5c45cee9a0cd536f57033b752f72304c8f36 10.180.195.126:6379 master - 0 1472191973214 10 connected 0-5459
      0b2bfc904c4062badcd6e497254abc1eea3ce161 10.180.195.124:6379 myself,master - 0 0 7 connected 10923-16383
      3d0cda529093b3d7eb808b1e7999a48c34cc4b47 10.180.195.126:6380 slave f0be5c45cee9a0cd536f57033b752f72304c8f36 0 1472191974718 10 connected
      1e17db47902c9467b46fc47f45eaf0989ed6d290 10.180.195.124:6380 master - 0 1472191973715 12 connected 5460-10922
      38ef0b431ad5f31cb8d726085e99e308d35a2d2d :0 slave,fail,noaddr 0b2bf c904c4062badcd6e497254abc1eea3ce161 1471923300646 1471923300146 8 disconnected
      10.180.195.124:6379>
      
      添加完成后新增节点还是空的,需要使用redis-trib.rb迁移一部分哈希桶到新节点,从而成为真正的主节点。hash slots迁移参见下文reshard过程。
    2. 添加从节点 添加从节点和添加主节点类似,只需要加上--slave项即可
      ./redis-trib.rb add-node --slave 10.180.195.127:6380 10.180.195.126:6379
      
      由于没有指定主节点,集群会在主节点中任一选择一个作为这个从节点的主节点。 当然你也可以使用--master-id指定主节点,如下命令:
      ./redis-trib.rb add-node --slave --master-id f0be5c45cee9a0cd536f57033b752f72304c8f36 10.180.195.127:6380 10.180.195.126:6379
      
      除此以外,也可以使用redis-cli连到新节点执行CLUSTER REPLICATE命令,指定其主节点
      10.180.195.127:6380>  cluster replicate f0be5c45cee9a0cd536f57033b752f72304c8f36
      
  • 移除节点

    命令:

    ./redis-trib del-node 127.0.0.1:700 `<node-id>`
    

    说明: 第一个参数是指集群里任一节点ip:port 第二个参数是指想要移除节点的ID

    移除master节点也是如此,不过移除master节点内容必须为空。如果master不为空需要将节点上的数据reshard迁移到其他master,然后再移除。 还有移除master可选的做法就是通过在master的slaves上手动执行failover,将其slave转成新的master移除旧的master。显然这种做法不能减少集群里master的数量,这种做法也需要reshard。 del-node只能移除正常状态的节点,如果节点异常宕机,需要在其他节点执行cluster forget移除异常的节点。

  • reshard

    reshard就是将hash slots重新分配的过程 命令:

    ./redis-trib reshard 10.180.195.126:6379
    

    之后会提示

    1.要迁移多少hash slot
    2.要迁入的目标节点id
    3.迁出的源节点id,支持多个,输入done表示结束
    4.输入yes确认
    

    之后redis集群将会完成迁移动作。 你也可以自动化reshard:

    ./redis-trib.rb reshard --from all --to f0be5c45cee9a0cd536f57033b752f72304c8f36 --slots 5460 --yes 10.180.195.126:6379
    

    上面的命令就是从所有的主节点迁移5460个hash slot到id为f0be5c45cee9a0cd536f57033b752f72304c8f36的节点上面。

  • rebalance

    rebalance是根据用户给各个master节点分配的权重值来重新平衡slot的分布。 命令:

     ./redis-trib rebalance  --weight be34bea4=10 --threshold 10 --use-empty-masters --timeout xx 10.180.195.126:6379
    

    参数说明:

    • --weight : 节点的权重值,如果为多个节点分配权值需要多个。如果不带weight则默认每个master节点的权重值为1,平均分配
    • --thredhold : 节点需要迁移的slot阈值超过thredhold才会执行rebalance操作,默认阈值为2,即2%的slot值需要迁移才进行。阈值计算算法:(100-(100.0*expected/n.slots.length)).abs
    • --use-empty-masters : 是否考虑没有slot分布的master节点,携带该参数空slot的master节点也参与rebalance操作
    • timeout : migrate操作的超时时间,默认值60000(ms)
    • --simulate :模拟操作,并不会实际执行slot迁移
    • --pipeline : 定义一次取key的数量,默认值10
  • check

    检查集群状态,返回集群中各个节点角色和slot分布 命令:

    ./redis-trib check 10.180.195.126:6379
    

    无参数

         >>> Performing Cluster Check (using node 10.18.192.187:6381)
       M: 969022a64ea95923b096cf875b4d691d095056b9 10.18.192.187:6381
          slots:0-4095 (4096 slots) master
          1 additional replica(s)
       S: 039f8f407069d55a5ceafa328f452fbe6bbf4068 10.18.192.187:6380
          slots: (0 slots) slave
          replicates 573be4056609ea078764c086d21d269338b6e928
       S: b6864de095e8329d51de07b607f67c0020d69958 10.18.192.191:6381
          slots: (0 slots) slave
          replicates 969022a64ea95923b096cf875b4d691d095056b9
       M: 573be4056609ea078764c086d21d269338b6e928 10.18.192.191:6380
          slots:8192-12287 (4096 slots) master
          1 additional replica(s)
       S: 4c6f2091d2bfe79fa958baef744becacdde15385 10.18.192.190:6381
          slots: (0 slots) slave
          replicates 02bdcbbb199648785437447586918cfd3af30b7c
       M: 0670859e85830c01000c9ba7ce365249e24dcc73 10.18.192.186:6380
          slots:4096-8191 (4096 slots) master
          1 additional replica(s)
       M: 02bdcbbb199648785437447586918cfd3af30b7c 10.18.192.186:6381
          slots:12288-16383 (4096 slots) master
          1 additional replica(s)
       S: 067dedcef3caf0e3c67eb657352dedd07f14eb64 10.18.192.190:6380
          slots: (0 slots) slave
          replicates 0670859e85830c01000c9ba7ce365249e24dcc73
       [OK] All nodes agree about slots configuration.
       >>> Check for open slots...
       >>> Check slots coverage...
       [OK] All 16384 slots covered.
    
  • info

    查看集群的信息,显示master节点的key数量,slot值,以前slave节点数 命令:

    ./redis-trib info 10.18.192.187:6380
    

    无参数

      10.18.192.187:6381 (969022a6...) -> 0 keys | 4096 slots | 1 slaves.
      10.18.192.191:6380 (573be405...) -> 0 keys | 4096 slots | 1 slaves.
      10.18.192.186:6380 (0670859e...) -> 0 keys | 4096 slots | 1 slaves.
      10.18.192.186:6381 (02bdcbbb...) -> 0 keys | 4096 slots | 1 slaves.
      [OK] 0 keys in 4 masters.
      0.00 keys per slot on average.
    
  • fix

    修复集群,fix首先加载集群信息和check流程一样,check只检查不修复。fix修复两种异常:

    1. 针对打开的slot,即处于迁移状态migrating和importing
    2. slot没有完全分配异常

    命令:

    ./redis-trib fix 10.18.192.187:6380
    
  • call

    在集群各个节点执行命令,返回各个节点执行结果

    ./redis-trib call 10.18.192.187:6380 get key
    
  • import

    将外部集群数据导入,只支持集群之前的导入,不支持redis单节点 命令:

     ./redis-trib import --from 10.18.192.193:6380 10.18.192.187:6380
    

    参数说明:

    • --from 源地址,必须是集群地址
    • --copy 迁移使用复制模式,不移除源实例上的 key
    • --replace 替换目标实例上已存在的 key

      执行流程:

      1、加载集群信息,check_cluster方法检查集群是否健康。

      2、连接redis源节点,如果源节点必须是集群模式,则提示错误。

      3、通过scan命令遍历外部节点,一次获取1000条数据。

      4、遍历这些key,计算出key对应的slot。

      5、执行migrate命令,源节点是外部节点,目的节点是集群slot对应的节点,如果设置了--copy参数,则传递copy参数,如果设置了--replace,则传递replace参数。

      6、不停执行scan命令,直到遍历完全部的key。

      7、至此完成整个迁移流程

  • 升级Redis集群内节点

    升级slave节点非常容易,只需要将节点关闭升级完成后重新启动即可。如果有客户端从slave节点读取,该slave节点不可用时会重新连到其他slave节点。

    升级master有点复杂,建议的步骤如下:

    1. 使用CLUSTER FAILOVER 触发手动failover机制将master换成其它slave节点
    2. 等待master变成slave
    3. 最后按照slave升级步骤进行
    4. 如果你想将升级后的节点重新变成master,再次触发手动fialover将其重新转变成master节点。

集群相关命令

命令 参数 说明
cluster addslot slot-id 节点分配slot
cluster countkeysinslot slot-id 计算slot上的key数量
cluster delslot slot-id 删除节点上分配的slot
cluster failover [force] or [takover] 手动failover
cluster forget node-id 遗忘节点id,60s内有效
cluster getkeysinslot slot-id count 获取指定slot上key的内容,返回指定的条数
cluster info 获取集群信息
cluster meet ip port 将指定redis加入当前节点所在的集群
cluster nodes 查看集群内所有节点
cluster reset hard or soft 重置节点,对已有key分布的master无效
cluster replicate node-id 重新设置slave的master节点
cluster saveconfig 强制将node信息保存在nodes.conf文件中
cluster set-config-epoch num 设置节点的epoch,只对空节点或节点当前epoch为0生效
cluster setslot slot importing node-id 设置slot状态(importing,migrating,stable)、将slot绑定到其他node-id
cluster slaves node-id 复制指定的nodeid主节点
cluster slots  集群中slots分布情况

本文来自网易云社区,经作者乔安然授权发布

网易云免费体验馆0成本体验20+款云产品!

更多网易研发、产品、运营经验分享请访问网易云社区