redis-trib.rb和redis-cli部署redis主从集群的异同

目录

  • 前言
  • 1 redis-trib.rb创建集群
    • 1.1 创建redis集群
    • 1.2 增加集群Master/Slave实例
    • 1.3 删除redis集群节点
    • 1.4 查看集群状态
    • 1.5 修复集群
    • 1.6 踩的坑
  • 2 redis-cli创建redis5.0.8主从集群
    • 2.1 redis5.0.8压缩包
    • 2.2 服务器初始化脚本 node-env-init.sh
    • 2.3 快速创建实例脚本 creat-instance.sh
    • 2.4 创建集群
  • 参考文章

前言

  • redis-trib.rb是在redis3.x版本时所用的一种部署redis集群的工具,redis-cliredis4.x及更高版本所支持创建集群的工具,在redis3.x版本时redis-cli只是一个客户端连接管理工具。
  • redis-cliredis-trib.rb多了一个可以认证集群密码的功能,后者创建的集群不能对有密码的集群节点进行很好的管理,所以后来官方直接废弃了这个工具。
  • redis-trib.rb创建集群之前需要配置ruby环境,新版本的redis-cli可以直接创建集群环境而不用配置ruby环境。

1 redis-trib.rb创建集群

1.1 创建redis集群

修改redis配置文件开启集群功能

vim /opt/redis/conf/6379/redis.conf
cluster-enabled yes //开启集群 把注释去掉即可
cluster-config-file nodes_6379.conf //集群的配置文件
  • 1、需要注意的是如果创建一主一备的redis集群则至少需要6个实例
    192.168.0.100:6379 192.168.0.100:6380 192.168.0.100:6381 创建一组集群
/opt/redis/bin/redis-trib.rb create 192.168.0.100:6379 192.168.0.100:6380 192.168.0.100:6381
  • 2、若需要创建一主一备的集群需注意,如果对集群中实例主备顺序没有要求则可在下边代码中随意写实例的顺序(默认情况下前三台会被识别为Master,后三台实例会成为Slave),若对顺序有要求则最好先创建Master集群,然后依次添加Slave实例,
/opt/redis/bin/redis-trib.rb create --replicas 1 192.168.0.100:6379 192.168.0.100:6380 192.168.0.100:6381 192.168.0.100:6382 192.168.0.100:6383 192.168.0.100:6384

1.2 增加集群Master/Slave实例

(1)如果添加的是主节点,只需指定源节点和目标节点的地址即可(6382为新加节点)

/opt/redis/bin/redis-trib.rb add-node 192.168.0.100:6382 192.168.0.100:6379

(2)若增加slave节点,需要指定slave

/opt/redis/bin/redis-trib.rb add-node --slave --master-id 9cdc025b45b66fef0d4656252ecde58e005c2ae1 192.168.0.100:6382 192.168.0.100:6379

1.3 删除redis集群节点

  • 删除节点首先要查看此节点id
/opt/redis/bin/redis-trib.rb check 192.168.0.100:6379
  • 若该实例为Slave,则可以指定ip:port id直接删除
/opt/redis/bin/redis-trib.rb del-node 192.168.0.100:6379 9cdc025b45b66fef0d4656252ecde58e005c2ae1

若该实例为master,则需要先reshard迁移master的slot,然后删除,需要注意的是被迁移的实例也需要是master才可以。具体迁移步骤可参考后边介绍的redis-cli迁移slot方法。之后就可以正常del-node删除节点操作。

1.4 查看集群状态

  • 只需要随便找个集群节点就可以检查集群中所有节点的状态
/opt/redis/bin/redis-trib.rb check 192.168.0.100:6379
  • 查看集群信息
/opt/redis/bin/redis-trib.rb info 192.168.0.100:6379

1.5 修复集群

  • 若某一集群节点出现问题,则可尝试如下操作
/opt/redis/bin/redis-trib.rb fix 192.168.0.100:6379
  • 目前fix命令能修复两种异常:
    • 1、节点中存在处于迁移中(importing或migrating状态)的slot。
    • 2、节点中存在未分配的slot。
    • 其它异常不能通过fix命令修复

1.6 踩的坑

1、由于redis-trib.rb不支持使用密码的集群模式,故还需要修改redis-trib.rb脚本来使其支持带密码的集群部署,具体修改方法如下。

找到如下这一行:

vim /opt/redis/bin/redis-trib.rb

@r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60)

修改为:

@r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60, :password => "123456")

2、如果迁移slot报错 [ERR] Calling MIGRATE ERR Syntax error, try CLIENT (LIST | KILL | GETNAME | SETNAME | PAUSE | REPLY)
如果集群是不带密码的,那么可以参考如下配置来迁移slot

Redis - 解决reshard 出现的bug

如果是带密码的集群,在修改完redis-trib.rb文件增加密码之后,有可能不会报这个错误,若是报错,那就除非升级redis版本至4.0+,这是官方的bug,可参考

Bug Redis-trib.rb : migrate slot including key using “ move_slot”

3、增加Master节点,分配slot的时候最好计算好要给多少,比如6台Master,新加一台Master的话,那么slot分配 16384/7 于等于2340,Source node #1:指定all回车即可
redis-trib.rb和redis-cli部署redis主从集群的异同_第1张图片

2 redis-cli创建redis5.0.8主从集群

2.1 redis5.0.8压缩包

redis5.0.8版本压缩包,解压即可用,把安装包放在 /opt 目录下即可

链接: https://pan.baidu.com/s/1WWIG7hW-7z-bVrC55ylTGg
提取码: pezg

目录结构:

[root@master01 redis]# tree
.
├── bin
│   ├── redis-benchmark
│   ├── redis-check-aof
│   ├── redis-check-rdb
│   ├── redis-cli
│   ├── redis-migrate-tool
│   ├── redis-sentinel -> redis-server
│   └── redis-server
├── conf
│   ├── 6379
│   │   ├── db
│   │   │   └── nodes-6379.conf
│   │   ├── log
│   │   │   └── redis_6379.log
│   │   └── redis.conf
│   └── 7000_template  // 模板文件,之后的实例通过此模板创建而来
│       ├── db
│       │   └── nodes-7000.conf
│       ├── log
│       │   └── redis_7000.log
│       └── redis.conf
└── scripts
    ├── creat-instance.sh  // 创建新实例
    └── node-env-init.sh   // 配置系统环境

说明:
此配置文件稍微修改了一些内容,若不需要可注释

  • 开启了集群管理功能
  • 修改了redis实例最大内存maxmemory 1GB

2.2 服务器初始化脚本 node-env-init.sh

[root@master01 scripts]# cat node-env-init.sh 
#!/bin/sh

# 配置TCP/IP最大文件描述符
echo '*     -       nofile          65535' >> /etc/security/limits.conf

# 配置内核参数
cat >>/etc/sysctl.conf<<EOF
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
EOF

# 生效配置
sysctl -p

# 关闭THP
echo never > /sys/kernel/mm/transparent_hugepage/enabled

2.3 快速创建实例脚本 creat-instance.sh

快速创建实例的示例:

[root@SS009224Redis scripts]# ls
creat-instance.sh  node-env-init.sh
[root@SS009224Redis scripts]# bash creat-instance.sh 
请输入创建实例的端口:8000
创建8000实例成功, 退出程序......
[root@SS009224Redis scripts]# cd ../conf/
[root@SS009224Redis conf]# ls
6379  6382  7000_template  8000

脚本内容如下

[root@master01 scripts]# cat creat-instance.sh
#!/bin/bash
# **********************************************************
# * Author        : RSQ
# * Email         : [email protected]
# * Last modified : 2020-04-28
# * Filename      : creat-instance.sh
# * Description   : 
# * *******************************************************


CONF_PATH=/opt/redis/conf
DB_FILE=dump.rdb
IP_ADDR=`ifconfig eth0 | awk 'NR==2{print $2}'`

# 判断模板文件是否存在,否则退出程序
[ -d !$CONF_PATH/7000_template/ ] && {
    echo "模板文件不存在, 退出程序......"
    exit 1
}

while true
do
    read -p "请输入创建实例的端口:" Port
    if [ $Port -gt 1024 ] && [ $Port -le 10000 ]
    then
        /usr/bin/cp -R $CONF_PATH/7000_template/ $CONF_PATH/$Port
	[ $? != 0 ] && {
	    echo "拷贝新实例${Port}错误, 退出程序......"
  	    /usr/bin/rm -rf $CONF_PATH/$Port/
	    break
	}
	
	# 替换模板文件端口为新实例端口
  	/usr/bin/sed -i "s/7000/$Port/g" $CONF_PATH/$Port/redis.conf
	[ $? != 0 ] && {
	    echo "替换模板端口错误, 删除创建的新实例${Port}, 退出程序......"
  	    /usr/bin/rm -rf $CONF_PATH/$Port/
	    break
	}

	# 清空老文件配置
	[ -f $CONF_PATH/$Port/db/$DB_FILE ] && {
	    /usr/bin/rm -f $CONF_PATH/$Port/db/$DB_FILE
	}

	# 修改模板集群配置文件并清空文件内容
	/usr/bin/mv $CONF_PATH/$Port/db/nodes-7000.conf $CONF_PATH/$Port/db/nodes-${Port}.conf
	> $CONF_PATH/$Port/db/nodes-${Port}.conf
	[ $? != 0 ] && {
	    echo "清空集群配置文件有误, 删除创建的新实例${Port}, 退出程序......"
  	    /usr/bin/rm -rf $CONF_PATH/$Port/
	    break
	}

	# 修改模板日志文件并清空文件内容
	/usr/bin/mv $CONF_PATH/$Port/log/redis_7000.log $CONF_PATH/$Port/log/redis_${Port}.log
	> $CONF_PATH/$Port/log/redis_${Port}.log
	[ $? != 0 ] && {
	    echo "清空日志文件有误, 删除创建的新实例${Port}, 退出程序......"
  	    /usr/bin/rm -rf $CONF_PATH/$Port/
	    break
	}

	# 替换IP地址
	/usr/bin/sed -i "s/10.0.0.200/${IP_ADDR}/g" $CONF_PATH/$Port/redis.conf
	[ $? != 0 ] && {
            echo "替换IP地址错误, 删除创建的新实例${Port}, 退出程序......"
            /usr/bin/rm -rf $CONF_PATH/$Port/
            break
        }

	echo "创建${Port}实例成功, 退出程序......"
	break
    else 
        echo "输入的端口错误, 端口范围(1024-10000]"
    fi
done

2.4 创建集群

redis-cliredis-trib.rb创建集群的方法几乎一样,只不过在创建集群的时候需要指定 --cluster这个选项,对于有密码的redis集群,可以指定 -a选项来管理redis集群,可使用/opt/redis/bin/redis-cli --cluster help来查看具体选项,具体参数解释可参考文章底部参考文章(5)。

  • (1)在创建集群时候指定replicas数量,如果数量为1,那么每个Master都会分配一个Slave,但是这样操作是不能指定哪个Master跟哪个Slave绑定的。
/opt/redis/bin/redis-cli --cluster create --cluster-replicas 1 172.28.0.224:6380 172.28.0.225:6380 172.31.0.226:6380 172.31.0.227:6380 172.31.0.224:6380 172.31.0.225:6380 172.28.0.226:6380 172.28.0.227:6380 -a '123456'
  • (2)创建4Master,4Slave的集群,先创建4个Master的全Master集群,在添加Slave实例
/opt/redis/bin/redis-cli --cluster create 172.28.0.224:6380 172.28.0.225:6380 172.31.0.226:6380 172.31.0.227:6380 -a '123456'
  • (3)添加Slave实例
# 依次添加4个Slave即可,下边是添加一个Slave的命名
/opt/redis/bin/redis-cli --cluster add-node 172.31.0.224:6380 172.28.0.224:6380 --cluster-slave --cluster-master-id 9000a261858463dea8c607acc3104485aff9d5bc -a '123456'
  • (4)查看集群状态(随意指定一台节点即可查看集群所有节点状态)
/opt/redis/bin/redis-cli --cluster check 172.28.0.224:6380 -a '123456'
  • (5)迁移Slot跟之前redis-trib.rb是相同的操作

参考文章

(1)Redis使用redis-trib.rb创建带密码的集群问题总结
(2)redis-trib.rb命令详解
(3)迁移slot报错
(4)redis-trib.rb reshard报错
(5)Redis 5.0 redis-cli --cluster help说明

你可能感兴趣的:(Redis)