redis-trib.rb和redis-cli部署redis主從集羣的異同

前言

  • redis-trib.rb是在redis3.x版本時所用的一種部署redis集羣的工具,redis-cli是redis4.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回車即可
在這裏插入圖片描述

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說明

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章