08 Cluster

一. Cluster介绍背景

1. 问题

1. 并发量:单机redis qps为10w/s, 但是我们可能需要百万级别的并发量
2. 数据量:机器内存16g--256g,如果存500g数据呢?

2. 解决

# 解决:加机器,分布式
redis cluster 在2015年的 3.0 版本加入了,满足分布式的需求

二. 数据分布: 分布式数据库

1. 存在问题

假设全量的数据非常大,500g,单机已经无法满足,我们需要进行分区,分到若干个子集中

2. 分布区方式

分布方式 特点 产品
哈希分布 数据分散度高,建值分布于业务无关,无法顺序访问,支持批量操作 一致性哈希memcache,redis cluster,其他缓存产品
顺序分布 数据分散度易倾斜,建值业务相关,可顺序访问,支持批量操作 BigTable,HBase

1) 顺序分区

# 原理:100个数据分到3个节点上 1--33第一个节点;34--66第二个节点;67--.100第三个节点(很多关系型数据库使用此种方式)

2) 哈希分区: 节点取余分区, 一致性哈希分区, 虚拟槽分区

哈希分区介绍: 节点取余 ,假设3台机器, hash(key)%3, 落到不同节点上

方式一: 节点取余分区

image-20200811120153068

image-20200811120704296

image-20200811120815523

# 介绍
	节点扩容,添加一个节点,存在问题,很多数据需要偏移,总偏移量要大于80%
	推荐翻倍扩容,由3变成6,数据量迁移为50%,比80%降低

# 总结
	客户端分片,通过hash+取余
	节点伸缩,数据节点关系发生变化,导致影响数据迁移过大
	迁移数量和添加节点数量有关:建议翻倍扩容

方式二: 一致性哈希分区

image-20200811121233804

image-20200811121518855

# 介绍
	每个节点负责一部分数据,对key进行hash,得到结果在node1和node2之间,就放到node2中,顺时针查找
	假设添加一个新节点node5,现在只需要迁移一小部分数据,不会影响node3和node4的数据,只会迁移node1和node2的数据
	节点比较多的话合适,假设有1000个节点,加一个只要迁移千分之一的数据

# 总结
	客户端分片:哈希+顺时针(优化取余)
	节点伸缩:只影响临近节点,但是还有数据迁移的情况
	伸缩:保证最小迁移数据和无法保证负载均衡(这样总共5个节点,数据就不均匀了),翻倍扩容可以实现负载均衡

方式三: 虚拟槽分区

image-20200811190745066

# 介绍
	预设虚拟槽:每个槽映射一个数据子集,一般比节点数大
	良好的哈希函数:如CRC16
	服务端管理节点、槽、数据:如redis cluster(槽的范围0–16383)

# 本质
	5个节点,把16384个槽平均分配到每个节点,客户端会把数据发送给任意一个节点,通过CRC16对key进行哈希对16383进行取余,算出当前key属于哪部分槽,属于哪个节点.
	每个节点都会记录是不是负责这部分槽,如果是负责的,进行保存,如果槽不在自己范围内,redis cluster是共享消息的模式,它知道哪个节点负责哪些槽,返回结果,让客户端找对应的节点去存

三. 集群搭建

1. 单机架构

image-20200811191353220

2. 分布式架构

每个节点之间相互通信,都负责读写,客户端去存,如果不是当前节点,会返回应该存到哪个节点

image-20200811191435244

3. Cluster架构

# 构建流程
1. 构建节点
2. meet: 建立联系
3. 指派槽: 分配存储
4. 主从复制实现高可用(提示: 集权涵盖了哨兵机制, 争对故障问题设定了转移机制)

1) meet: 建立联系

image-20200811192029280

# 流程
1. A meet一下C,C回复一下
2. A 再meet一下B ,B回复一下
3. 这样B和C也能相互感知,A,B,C之间就可以相关交互数据,所有节点共享消息

2) 指派槽: 分配存储

image-20200811192334455

# 槽数量: 16384
总共有16384个槽,平均分配到每个节点上

4. 原生安装

1) 第一步: 配置开启节点

配置参考

port ${port}
daemonize yes
dir "/opt/redis/data/"
logfile "${port}.log"

# master auth  集群搭建时,主的密码
# 开启cluster
cluster-enabled yes  

# 故障转移,超时时间 15s
cluster-node-timeout 15000 

# 给cluster节点增加一个自己的配置文件
cluster-config-file nodes-${port}.conf  

# 只要集群中有一个故障了,整个就不对外提供服务了,这个实际不合理,假设有50个节点,一个节点故障了,所有不提供服务了;,需要设置成no
cluster-require-full-coverage yes  

配置节点: 3主 3从

# 配置: 7000
vim /opt/redis/conf/redis-7000.conf

port 7000
daemonize yes
dir "/opt/redis/data/"
logfile "7000.log"
dbfilename "dump-7000.rdb"
bind 0.0.0.0
cluster-enabled yes  
cluster-node-timeout 15000 
cluster-config-file nodes-7000.conf 
cluster-require-full-coverage yes  

# 快速生成其他配置
sed 's/7000/7001/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7001.conf
sed 's/7000/7002/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7002.conf
sed 's/7000/7003/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7003.conf
sed 's/7000/7004/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7004.conf
sed 's/7000/7005/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7005.conf


# 查看配置情况
cat /opt/redis/conf/redis-7000.conf
cat /opt/redis/conf/redis-7001.conf
cat /opt/redis/conf/redis-7002.conf
cat /opt/redis/conf/redis-7003.conf
cat /opt/redis/conf/redis-7004.conf
cat /opt/redis/conf/redis-7005.conf


# 开启6个节点
redis-server /opt/redis/conf/redis-7000.conf
redis-server /opt/redis/conf/redis-7001.conf
redis-server /opt/redis/conf/redis-7002.conf
redis-server /opt/redis/conf/redis-7003.conf
redis-server /opt/redis/conf/redis-7004.conf
redis-server /opt/redis/conf/redis-7005.conf

# 查看开启情况
ps aux | grep redis

2) 第二步: meet(相互通信)

redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 7001
redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 7002
redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 7003
redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 7004
redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 7005

# 查看握手情况: 使用任意一个都可以正常查看
redis-cli -p 7000 cluster nodes 
redis-cli -p 7001 cluster nodes
redis-cli -p 7002 cluster nodes
redis-cli -p 7003 cluster nodes
redis-cli -p 7004 cluster nodes
redis-cli -p 7005 cluster nodes

3) 第三步: 指派槽

# 构建分槽脚本命令
vim /opt/redis/addslots.sh

#!/bin/bash
start=$1
end=$2
port=$3
for slot in `seq ${start} ${end}`
do
	echo "slot:${slot}"
  redis-cli -p ${port} cluster addslots ${slot}
done


# 分槽7000分0~5641, 7001分5641~10922, 7002分10923~16383槽
bash /opt/redis/addslots.sh 0 5641 7000
bash /opt/redis/addslots.sh 5641 10922 7001
bash /opt/redis/addslots.sh 10923 16383 7002

4) 第四步: 主从

# 让7003复制7000, 让7004复制7001, 让7005复制7002 -> cluster replicate node-id
'''
redis-cli -h 127.0.0.1 -p 7003 cluster replicate 7000的哈希数值
redis-cli -h 127.0.0.1 -p 7004 cluster replicate 7001的哈希数值
redis-cli -h 127.0.0.1 -p 7005 cluster replicate 7002的哈希数值
'''
[root@yang conf]# redis-cli -p 7000 cluster nodes  # 查看所有的哈希数值
49dbc9fa19d2d2c9213a9ede58bdbb0699d7eaa2 127.0.0.1:7001@17001 master - 0 1599390111809 4 connected 5642-10922
09db8ef6b2db7be4cc60e7678c833b88d71a72e3 127.0.0.1:7000@17000 myself,master - 0 1599390108000 1 connected 1-5641
8e30f03f70399c9903ddbc95ef777ebf53b18135 127.0.0.1:7005@17005 master - 0 1599390110000 3 connected
30bc6da613725ebe55a0691c52e3a6a7696b9914 127.0.0.1:7004@17004 master - 0 1599390110000 5 connected
ec2671ec4a19236f8a72d8a249ed462f4678dbe4 127.0.0.1:7003@17003 master - 0 1599390108742 0 connected
663cb0af8c3548b64c9ebf29ca2407efaa8f0813 127.0.0.1:7002@17002 master - 0 1599390110783 2 connected 10923-16383

    
# 配置主从
redis-cli -h 127.0.0.1 -p 7003 cluster replicate 09db8ef6b2db7be4cc60e7678c833b88d71a72e3
redis-cli -h 127.0.0.1 -p 7004 cluster replicate 49dbc9fa19d2d2c9213a9ede58bdbb0699d7eaa2
redis-cli -h 127.0.0.1 -p 7005 cluster replicate 663cb0af8c3548b64c9ebf29ca2407efaa8f0813

# 查看配置情况
'''
现在7000, 7001, 7002是主, 7003, 7004, 7005为从
其中7003是7000的从, 7004是70001的从, 7005是7002的从
'''
[root@yang conf]# redis-cli -p 7000 cluster nodes 
49dbc9fa19d2d2c9213a9ede58bdbb0699d7eaa2 127.0.0.1:7001@17001 master - 0 1599390229351 4 connected 5642-10922
09db8ef6b2db7be4cc60e7678c833b88d71a72e3 127.0.0.1:7000@17000 myself,master - 0 1599390227000 1 connected 1-5641
8e30f03f70399c9903ddbc95ef777ebf53b18135 127.0.0.1:7005@17005 slave 663cb0af8c3548b64c9ebf29ca2407efaa8f0813 0 1599390226000 3 connected
30bc6da613725ebe55a0691c52e3a6a7696b9914 127.0.0.1:7004@17004 slave 49dbc9fa19d2d2c9213a9ede58bdbb0699d7eaa2 0 1599390227297 5 connected
ec2671ec4a19236f8a72d8a249ed462f4678dbe4 127.0.0.1:7003@17003 slave 09db8ef6b2db7be4cc60e7678c833b88d71a72e3 0 1599390228326 1 connected
663cb0af8c3548b64c9ebf29ca2407efaa8f0813 127.0.0.1:7002@17002 master - 0 1599390228000 2 connected 10923-16383

5) 查看命令

redis-cli -p 7000 cluster info

redis-cli -p 7000 cluster nodes

# 查看槽的信息
redis-cli -p 7000 cluster slots 


(error) CLUSTERDOWN The cluster is down

5. 官方工具安装: 基于Ruby脚本

下载编译安装ruby

# wget下载
wget https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.gz
    
# tar解压
tar -xf ruby-2.7.1.tar.gz

# 进入解压完毕以后的ruby-2.7.1目录
cd ruby-2.7.1

# 指定程序的安装目录到/usr/local/下以ruby命名
./configure --prefix=/usr/local/ruby

# 编译并安装
make && make install

cd /usr/local/ruby
cp bin/ruby /usr/local/bin  # ruby类似于python3
cp bin/gem /usr/local/bin   # gem类似于pip

# 检查版本
ruby -v

配置节点: 3主 3从

# 配置: 7000
vim /opt/redis/conf/redis-7000.conf

port 7000
daemonize yes
dir "/opt/redis/data/"
logfile "7000.log"
dbfilename "dump-7000.rdb"
bind 0.0.0.0
cluster-enabled yes  
cluster-node-timeout 15000 
cluster-config-file nodes-7000.conf 
cluster-require-full-coverage yes  

# 快速生成其他配置
sed 's/7000/7001/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7001.conf
sed 's/7000/7002/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7002.conf
sed 's/7000/7003/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7003.conf
sed 's/7000/7004/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7004.conf
sed 's/7000/7005/g' /opt/redis/conf/redis-7000.conf > /opt/redis/conf/redis-7005.conf


# 查看配置情况
cat /opt/redis/conf/redis-7000.conf
cat /opt/redis/conf/redis-7001.conf
cat /opt/redis/conf/redis-7002.conf
cat /opt/redis/conf/redis-7003.conf
cat /opt/redis/conf/redis-7004.conf
cat /opt/redis/conf/redis-7005.conf


# 开启6个节点
redis-server /opt/redis/conf/redis-7000.conf
redis-server /opt/redis/conf/redis-7001.conf
redis-server /opt/redis/conf/redis-7002.conf
redis-server /opt/redis/conf/redis-7003.conf
redis-server /opt/redis/conf/redis-7004.conf
redis-server /opt/redis/conf/redis-7005.conf

# 查看开启情况
ps aux | grep redis

使用ruby脚本执行redis-cli --cluster create创建集群, 它会做三件事:

1.meet

2.自动配置槽

3.自动构建主从复制

提示: cluster-node-timeout 15000 配置表明集权本身就集成了Sentinel机制, 处理了原master故障时从而选举slave作为新的master等机制

# 注意:原来是通过redis-trib.rb进行配置但是它弃用了,需要使用redis-cli进行配置. 如果使用会抛出异常:
'''
WARNING: redis-trib.rb is not longer available!
You should use redis-cli instead.

All commands and features belonging to redis-trib.rb have been moved
to redis-cli.
In order to use them you should call redis-cli with the --cluster
option followed by the subcommand name, arguments and options.

Use the following syntax:
redis-cli --cluster SUBCOMMAND [ARGUMENTS] [OPTIONS]

Example:
redis-cli --cluster fix 127.0.0.1:7000

To get help about all subcommands, type:
redis-cli --cluster help



警告:redis-trib。rb不再可用!
您应该使用redis-cli。
属于redisk -trib的所有命令和特性。rb已被移到redis-cli。
为了使用它们,您应该使用——cluster选项调用redi -cli,后面跟着子命令名、参数和选项。
使用以下语法:redis-cli——集群子命令[ARGUMENTS] [OPTIONS]
示例:redis-cli——集群修复127.0.0.1:7000
要获得关于所有子命令的帮助,请键入:redis-cli——集群帮助  
'''
cd /opt/soft/redis/src
./redis-trib.rb 


# 现在使用: redis-cli --cluster create创建集群
'''
# 它会做三件事
1. meet
2. 自动配置槽
3. 自动构建主从复制
'''
redis-cli --cluster create --cluster-replicas 1 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

如果出现wget unable to resolve host address ‘cache.ruby-lang.org’错误参考: 解决域名地址问题

四. 集群伸缩

1. 伸缩原理

# 加入节点,删除节点:槽和数据在节点之间的移动

image-20200811235039641

2. 集群扩容

# 作用:为它迁移槽和数据实现扩容  作为从节点负责故障转移

#1  准备新节点
-集群模式
-配置和其他节点统一
-启动后是孤儿节点
sed 's/7000/7006/g' redis-7000.conf > redis-7006.conf
sed 's/7000/7007/g' redis-7000.conf > redis-7007.conf
redis-server conf/redis-7006.conf
redis-server conf/redis-7007.conf
# 孤立状态re
redis-cli -p 7006 cluster nodes
#2  加入集群
### 方式一
在7000上执行
redis-cli -p 7000 cluster meet 127.0.0.1 7006
redis-cli -p 7000 cluster meet 127.0.0.1 7007
### 方式二
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000
# 查看配置
cluster nodes
# 把7007做为7006的从
redis-cli -p 7007 cluster replicate 7006的id
#3  迁移槽和数据
  # 槽迁移计划
  # 迁移数据
  # 添加从节点
  
 # 我们不操作原生,直接使用redis-trip
redis-cli --cluster reshard 127.0.0.1:7000 
#打印当前集群状态
# 希望迁移多少个槽:4096
# 希望那个id是接收的:7006的id
# 传入source id :all
# yes

# 查看
redis-cli -p 7000 cluster nodes
redis-cli -p 7000 cluster slots
## 其他:
-如果想给7000再加一个从节点怎么弄?
# 启动起7006,meet一下,让7006复制7000
redis-cli -p 7000 cluster meet 127.0.0.1 7006
redis-cli -p 7006 cluster replicate e03fb9a259cd314e9a23e17573d07c477d3242f7

3. 集群缩容

# 下线迁槽(把7006的1366个槽迁移到7000上)
redis-cli --cluster reshard --cluster-from 7006的id --cluster-to 7000的id --cluster-slots 1366 127.0.0.1:7000
yes

redis-cli --cluster reshard --cluster-from 7006的id --cluster-to 7001的id --cluster-slots 1366 127.0.0.1:7001
yes
redis-cli --cluster reshard --cluster-from 7006的id --cluster-to 7002的id --cluster-slots 1365 127.0.0.1:7002
yes
# 忘记节点,关闭节点
redis-cli --cluster del-node 127.0.0.1:7000 要下线的7007id  # 先下从,再下主,因为先下主会触发故障转移
redis-cli --cluster del-node 127.0.0.1:7000 要下线的7006id 
# 

# 关掉其中一个主,另一个从立马变成主顶上, 重启停止的主,发现变成了从

五. 客户端连接

redis-cli -c -p 7000  # -c表示集群模式
set hello world  # ok
cluster keyslot php
# 9244
set php sb # 不命中,会返回7001,自动跳转到7001上  不加-c,只会返回错误,不会去执行7001上保存


# rediscluster
# pip3 install redis-py-cluster
from rediscluster import RedisCluster
startup_nodes = [{"host":"127.0.0.1", "port": "7000"},{"host":"127.0.0.1", "port": "7001"},{"host":"127.0.0.1", "port": "7002"}]
# rc = RedisCluster(startup_nodes=startup_nodes,decode_responses=True)
rc = RedisCluster(startup_nodes=startup_nodes)
rc.set("foo", "bar")
print(rc.get("foo"))

六. 集群原理

move重定向

image-20200812003219180

槽命中

cluster keyslot hello 可以计算出槽的值

image-20200812003318203

槽不命中:moved异常

image-20200812003446448

七. 补充

1. 5.0以后集群搭建

Redis Cluster 在5.0之后取消了ruby脚本 redis-trib.rb的支持(手动命令行添加集群的方式不变),集合到redis-cli里,避免了再安装ruby的相关环境。直接使用redis-clit的参数–cluster 来取代

redis-cli --cluster help
Cluster Manager Commands:
  create         host1:port1 ... hostN:portN   # 创建集群
                 --cluster-replicas <arg>      # 从节点个数
  check          host:port                     # 检查集群
                 --cluster-search-multiple-owners #检查是否有槽同时被分配给了多个节点
  info           host:port                     # 查看集群状态
  fix            host:port                     # 修复集群
                 --cluster-search-multiple-owners # 修复槽的重复分配问题
  reshard        host:port                     # 指定集群的任意一节点进行迁移slot,重新分slots
                 --cluster-from <arg>          # 需要从哪些源节点上迁移slot,可从多个源节点完成迁移,以逗号隔开,传递的是节点的node id,还可以直接传递--from all,这样源节点就是集群的所有节点,不传递该参数的话,则会在迁移过程中提示用户输入
                 --cluster-to <arg>            # slot需要迁移的目的节点的node id,目的节点只能填写一个,不传递该参数的话,则会在迁移过程中提示用户输入
                 --cluster-slots <arg>         # 需要迁移的slot数量,不传递该参数的话,则会在迁移过程中提示用户输入。
                 --cluster-yes                 # 指定迁移时的确认输入
                 --cluster-timeout <arg>       # 设置migrate命令的超时时间
                 --cluster-pipeline <arg>      # 定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10
                 --cluster-replace             # 是否直接replace到目标节点
  rebalance      host:port                                      # 指定集群的任意一节点进行平衡集群节点slot数量 
                 --cluster-weight <node1=w1...nodeN=wN>         # 指定集群节点的权重
                 --cluster-use-empty-masters                    # 设置可以让没有分配slot的主节点参与,默认不允许
                 --cluster-timeout <arg>                        # 设置migrate命令的超时时间
                 --cluster-simulate                             # 模拟rebalance操作,不会真正执行迁移操作
                 --cluster-pipeline <arg>                       # 定义cluster getkeysinslot命令一次取出的key数量,默认值为10
                 --cluster-threshold <arg>                      # 迁移的slot阈值超过threshold,执行rebalance操作
                 --cluster-replace                              # 是否直接replace到目标节点
  add-node       new_host:new_port existing_host:existing_port  # 添加节点,把新节点加入到指定的集群,默认添加主节点
                 --cluster-slave                                # 新节点作为从节点,默认随机一个主节点
                 --cluster-master-id <arg>                      # 给新节点指定主节点
  del-node       host:port node_id                              # 删除给定的一个节点,成功后关闭该节点服务
  call           host:port command arg arg .. arg               # 在集群的所有节点执行相关命令
  set-timeout    host:port milliseconds                         # 设置cluster-node-timeout
  import         host:port                                      # 将外部redis数据导入集群
                 --cluster-from <arg>                           # 将指定实例的数据导入到集群
                 --cluster-copy                                 # migrate时指定copy
                 --cluster-replace                              # migrate时指定replace
  help           

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

① 创建集群主节点

redis-cli --cluster create 192.168.163.132:6379 192.168.163.132:6380 192.168.163.132:6381

② 创建集群主从节点

/redis-cli --cluster create 192.168.163.132:6379 192.168.163.132:6380 192.168.163.132:6381 192.168.163.132:6382 192.168.163.132:6383 192.168.163.132:6384 --cluster-replicas 1

说明:–cluster-replicas 参数为数字,1表示每个主节点需要1个从节点。

通过该方式创建的带有从节点的机器不能够自己手动指定主节点,所以如果需要指定的话,需要自己手动指定,先使用①或③创建好主节点后,再通过④来处理。

③ 添加集群主节点

redis-cli --cluster add-node 192.168.163.132:6382 192.168.163.132:6379

说明:为一个指定集群添加节点,需要先连到该集群的任意一个节点IP(192.168.163.132:6379),再把新节点加入。该2个参数的顺序有要求:新加入的节点放前

④ 添加集群从节点

redis-cli --cluster add-node 192.168.163.132:6382 192.168.163.132:6379 --cluster-slave --cluster-master-id 117457eab5071954faab5e81c3170600d5192270

说明:把6382节点加入到6379节点的集群中,并且当做node_id为 117457eab5071954faab5e81c3170600d5192270 的从节点。如果不指定 –cluster-master-id 会随机分配到任意一个主节点。

⑤ 删除节点

redis-cli --cluster del-node 192.168.163.132:6384 f6a6957421b80409106cb36be3c7ba41f3b603ff

说明:指定IP、端口和node_id 来删除一个节点,从节点可以直接删除,主节点不能直接删除,删除之后,该节点会被shutdown。

注意:当被删除掉的节点重新起来之后不能自动加入集群,但其和主的复制还是正常的,也可以通过该节点看到集群信息(通过其他正常节点已经看不到该被del-node节点的信息)。

如果想要再次加入集群,则需要先在该节点执行cluster reset,再用add-node进行添加,进行增量同步复制。

到此,目前整个集群的状态如下:

192.168.163.132:6379> cluster nodes
815da8448f5d5a304df0353ca10d8f9b77016b28 192.168.163.132:6380@16380 master - 0 1569748297177 2 connected 5461-10922
0c21b6cee354594a23f4d5abf0d01b48bdc96d55 192.168.163.132:6383@16383 slave 56005b9413cbf225783906307a2631109e753f8f 0 1569748295000 4 connected
3a1d04983ab6c4ae853f9602dd922d4ebadc4dbf 192.168.163.132:6382@16382 slave 815da8448f5d5a304df0353ca10d8f9b77016b28 0 1569748295000 5 connected
117457eab5071954faab5e81c3170600d5192270 192.168.163.132:6379@16379 myself,master - 0 1569748297000 1 connected 0-5460
56005b9413cbf225783906307a2631109e753f8f 192.168.163.132:6381@16381 master - 0 1569748295000 3 connected 10923-16383
f6a6957421b80409106cb36be3c7ba41f3b603ff 192.168.163.132:6384@16384 slave 117457eab5071954faab5e81c3170600d5192270 0 1569748298185 6 connected

⑥ 检查集群

redis-cli --cluster check 192.168.163.132:6384 --cluster-search-multiple-owners

说明:任意连接一个集群节点,进行集群状态检查

⑦ 集群信息查看

redis-cli --cluster info 192.168.163.132:6384

说明:检查key、slots、从节点个数的分配情况

/redis-cli --cluster info 192.168.163.132:6384
192.168.163.132:6380 (815da844...) -> 0 keys | 5462 slots | 1 slaves.
192.168.163.132:6381 (56005b94...) -> 0 keys | 5461 slots | 1 slaves.
192.168.163.132:6379 (117457ea...) -> 2 keys | 5461 slots | 1 slaves.
[OK] 2 keys in 3 masters.
0.00 keys per slot on average.

⑧ 修复集群

redis-cli --cluster fix 192.168.163.132:6384 --cluster-search-multiple-owners

说明:修复集群和槽的重复分配问题

⑨ 设置集群的超时时间

redis-cli --cluster set-timeout 192.168.163.132:6382 10000

说明:连接到集群的任意一节点来设置集群的超时时间参数cluster-node-timeout

redis-cli --cluster set-timeout 192.168.163.132:6382 10000
>>> Reconfiguring node timeout in every cluster node...
*** New timeout set for 192.168.163.132:6382
*** New timeout set for 192.168.163.132:6384
*** New timeout set for 192.168.163.132:6383
*** New timeout set for 192.168.163.132:6379
*** New timeout set for 192.168.163.132:6381
*** New timeout set for 192.168.163.132:6380
>>> New node timeout set. 6 OK, 0 ERR.

⑩ 集群中执行相关命令

redis-cli --cluster call 192.168.163.132:6381 config set requirepass cc
redis-cli -a cc --cluster call 192.168.163.132:6381 config set masterauth cc
redis-cli -a cc --cluster call 192.168.163.132:6381 config rewrite

说明:连接到集群的任意一节点来对整个集群的所有节点进行设置。

redis-cli --cluster call 192.168.163.132:6381 config set cluster-node-timeout 12000
>>> Calling config set cluster-node-timeout 12000
192.168.163.132:6381: OK
192.168.163.132:6383: OK
192.168.163.132:6379: OK
192.168.163.132:6384: OK
192.168.163.132:6382: OK
192.168.163.132:6380: OK
...
...

到此,相关集群的基本操作已经介绍完,现在说明集群迁移的相关操作。

2. 迁移相关

在线迁移slot :在线把集群的一些slot从集群原来slot节点迁移到新的节点,即可以完成集群的在线横向扩容和缩容。有2种方式进行迁移

一是根据提示来进行操作:

直接连接到集群的任意一节点
redis-cli -a cc --cluster reshard 192.168.163.132:6379

信息如下:

二是根据参数进行操作:

redis-cli -a cc --cluster reshard 192.168.163.132:6379 --cluster-from 117457eab5071954faab5e81c3170600d5192270 --cluster-to 815da8448f5d5a304df0353ca10d8f9b77016b28 --cluster-slots 10 --cluster-yes --cluster-timeout 5000 --cluster-pipeline 10 --cluster-replace

说明:连接到集群的任意一节点来对指定节点指定数量的slot进行迁移到指定的节点。

② 平衡(rebalance)slot

1)平衡集群中各个节点的slot数量

redis-cli -a cc --cluster rebalance 192.168.163.132:6379

2)根据集群中各个节点设置的权重等平衡slot数量(不执行,只模拟)

redis-cli -a cc --cluster rebalance --cluster-weight 117457eab5071954faab5e81c3170600d5192270=5 815da8448f5d5a304df0353ca10d8f9b77016b28=4 56005b9413cbf225783906307a2631109e753f8f=3 --cluster-simulate 192.168.163.132:6379

③ 导入集群

redis-cli --cluster import 192.168.163.132:6379 --cluster-from 192.168.163.132:9021 --cluster-replace

说明:外部Redis实例(9021)导入到集群中的任意一节点。

注意:测试下来发现参数–cluster-replace没有用,如果集群中已经包含了某个key,在导入的时候会失败,不会覆盖,只有清空集群key才能导入。

*** Importing 97847 keys from DB 0
Migrating 9223372011174675807 to 192.168.163.132:6381: Source 192.168.163.132:9021 replied with error:
ERR Target instance replied with error: BUSYKEY Target key name already exists

并且发现如果集群设置了密码,也会导入失败,需要设置集群密码为空才能进行导入(call)。通过monitor(9021)的时候发现,在migrate的时候需要密码进行auth认证。

posted @ 2020-09-06 20:44  给你加马桶唱疏通  阅读(173)  评论(0编辑  收藏  举报