1.Redis哨兵
哨兵的作用:
1.解决了主从复制故障需要人为干预的问题
2.提供了自动的高可用解决方案
目录和端口规划:
redis节点:6379
哨兵节点:26379
部署3台Redis单节点并做主从复制
#部署单节点
mkdir /data/soft -p
mkdir /opt/redis_6379/{conf,logs,pid} -p
mkdir /data/redis_6379 -p
cd /data/soft/
wget http://download.redis.io/releases/redis-5.0.8.tar.gz
tar xf redis-5.0.8.tar.gz -C /opt/
cd /opt/
ln -s redis-5.0.8/ /opt/redis
cd redis
make
echo $?
make install
#安装完成后尝试redis+tab键是否命令可以自动补全
cat >/opt/redis_6379/conf/redis_6379.conf<< EOF
daemonize yes
bind 127.0.0.1 10.0.0.51
port 6379
pidfile /opt/redis_6379/pid/redis_6379.pid
logfile /opt/redis_6379/logs/redis_6379.log
save 900 1
save 300 10
save 60 10000
dbfilename redis.rdb
dir /data/redis_6379/
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
EOF
#启动命令
redis-server /opt/redis_6379/conf/redis_6379.conf
#检查
ps -ef|grep redis
netstat -lntup|grep 6379
----------------------------------------------------------------------------------------------------------------
# 从db01拉取文件,此处用到ststemctl 的启动方式,db01上必须已经更改完成
rsync -avz 10.0.0.51:/opt/* /opt/
rsync -avz 10.0.0.51:/usr/lib/systemd/system/redis.service /usr/lib/systemd/system/
mkdir /data/redis_6379 -p
cd /opt/redis
make install
sed -i 's#51#53#g' /opt/redis_6379/conf/redis_6379.conf #如其他机器需要更改ip
useradd redis -M -s /sbin/nologin
chown -R redis:redis /opt/redis*
chown -R redis:redis /data/redis*
systemctl daemon-reload
systemctl start redis
redis-cli
#配置主从复制
# 在对应的db02、db03上启动主从复制
redis-cli -h 10.0.0.52 slaveof 10.0.0.51 6379
redis-cli -h 10.0.0.53 slaveof 10.0.0.51 6379
redis-cli -h 10.0.0.51 info Replication #查看主从详细信息
部署哨兵节点3台机器操作
操作命令:
mkdir -p /data/redis_26379
mkdir -p /opt/redis_26379/{conf,pid,logs}
cat >/opt/redis_26379/conf/redis_26379.conf << EOF
bind $(ifconfig eth0|awk 'NR==2{print $2}')
port 26379
daemonize yes
logfile /opt/redis_26379/logs/redis_26379.log
dir /data/redis_26379
sentinel monitor myredis 10.0.0.51 6379 2
sentinel down-after-milliseconds myredis 500
sentinel parallel-syncs myredis 1
sentinel failover-timeout myredis 18000
EOF
#参数解释:
daemonize yes
#允许后台运行
sentinel monitor mymaster 10.0.0.51 6379 2
#mymaster 主节点别名 主节点 ip 和端口, 判断主节点失败, 两个 sentinel 节点同意
sentinel down-after-milliseconds mymaster 500
#选项指定了 Sentinel 认为服务器已经断线所需的毫秒数。
sentinel parallel-syncs mymaster 1
#向新的主节点发起复制操作的从节点个数, 1 轮询发起复制
sentinel failover-timeout mymaster 18000
#故障转移超时时间
6.编写哨兵system配置文件-3台机器都操作
useradd redis -M -s /sbin/nologin
chown -R redis:redis /data/redis*
chown -R redis:redis /opt/redis*
cat >/usr/lib/systemd/system/redis-sentinel.service<<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-sentinel /opt/redis_26379/conf/redis_26379.conf --supervised systemd
ExecStop=/usr/local/bin/redis-cli -h $(ifconfig eth0|awk 'NR==2{print $2}') -p 26379 shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
7.添加本地hosts(方便连接3台都需做)
vim /etc/hosts
10.0.0.51 db01
10.0.0.52 db02
10.0.0.53 db03
8.启动哨兵
systemctl start redis-sentinel
redis-cli -h db01 -p 26379
9.检查当前主节点信息
redis-cli -h db01 -p 26379 Sentinel get-master-addr-by-name myredis #有本地hosts可以直接输入机器名称
#redis-cli -h 10.0.0.51 -p 26379 Sentinel get-master-addr-by-name myredis #无本地解析写IP
#redis-cli -h db02 -p 26379 Sentinel get-master-addr-by-name myredis
#redis-cli -h db03 -p 26379 Sentinel get-master-addr-by-name myredis
x.哨兵注意事项:
1.哨兵的配置文件是集群自己维护的,会动态更新
2.哨兵之间的信息是共享,每个节点都知道当前集群最新的情况,并且哨兵之间会互相发送心跳信息
3.千万不要自己去编辑修改哨兵的配置文件
2.Redis节点加权来确定优先备选节点
流程说明:
设置其他节点的权重为0
手动发起重新选举
观察所有节点消息是否同步
观察切换结果是否符合预期
#.命令解释:
查询当前权重命令:CONFIG GET slave-priority
设置命令:CONFIG SET slave-priority 0
主动切换:sentinel failover myredis
#.操作命令:
#1.查询谁是哨兵的主节点
redis-cli -h 10.0.0.51 -p 26379 sentinel get-master-addr-by-name myredis
#2.将不想做为主节点的权重调整为0
redis-cli -h 10.0.0.52 -p 6379 CONFIG SET slave-priority 0
redis-cli -h 10.0.0.53 -p 6379 CONFIG SET slave-priority 0
#3.在原本的主节点上使用此条命令,进行主动切换
redis-cli -h 10.0.0.51 -p 26379 sentinel failover myredis
#.验证选举结果:
redis-cli -h 10.0.0.51 -p 26379 Sentinel get-master-addr-by-name myredis
3.部署Redis集群
哨兵的不足:
资源利用率不高
主库压力大
连接过程繁琐集群重要概念:
redis集群,无论有几个节点,一共只有16384个槽
每个节点的槽的顺序不重要,重点是数量
hash算法足够随机,足够平均
每个槽被分配到数据的概率是相当的
所有的槽位都必须分配,哪怕有1个槽位不正常,整个集群都不能用
集群的高可用依赖于主从复制
集群拥有自己的配置文件,动态更新,不要手欠修改
集群通讯会使用基础端口号+10000的端口,这个是自动创建的,不是配置文件配置的
集群槽位分配比例允许误差在%2之间
- 安装部署
目录规划
主节点 6380
从节点 6381
#1.创建秘钥,并且分发给其他的机器
ssh-keygen
ssh-copy-id 10.0.0.52
ssh-copy-id 10.0.0.53
pkill redis
mkdir -p /opt/redis_{6380,6381}/{conf,logs,pid}
mkdir -p /data/redis_{6380,6381}
cat >/opt/redis_6380/conf/redis_6380.conf<<EOF
bind 10.0.0.51
port 6380
daemonize yes
pidfile "/opt/redis_6380/pid/redis_6380.pid"
logfile "/opt/redis_6380/logs/redis_6380.log"
dbfilename "redis_6380.rdb"
dir "/data/redis_6380/"
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
cluster-enabled yes # 开启集群模式
cluster-config-file nodes_6380.conf # 集群配置文件名
cluster-node-timeout 15000 # 集群重连时间
EOF
cd /opt/
cp redis_6380/conf/redis_6380.conf redis_6381/conf/redis_6381.conf
sed -i 's#6380#6381#g' redis_6381/conf/redis_6381.conf
chown -R redis:redis /opt/redis_*
chown -R redis:redis /data/redis_*
cat >/usr/lib/systemd/system/redis-master.service<<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-server /opt/redis_6380/conf/redis_6380.conf --supervised systemd
ExecStop=/usr/local/bin/redis-cli -h $(ifconfig eth0|awk 'NR==2{print $2}') -p 6380 shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
cd /usr/lib/systemd/system/
cp redis-master.service redis-slave.service
sed -i 's#6380#6381#g' redis-slave.service
systemctl daemon-reload
systemctl start redis-master
systemctl start redis-slave
ps -ef|grep redis
rsync -avz /opt/redis_638* 10.0.0.52:/opt/
rsync -avz /opt/redis_638* 10.0.0.53:/opt/
rsync -avz /usr/lib/systemd/system/redis-*.service 10.0.0.52:/usr/lib/systemd/system/
rsync -avz /usr/lib/systemd/system/redis-*.service 10.0.0.53:/usr/lib/systemd/system/
-----------------------------------------------------------------------------------------------------
#5.db02的操作
pkill redis
find /opt/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#52#g"
cd /usr/lib/systemd/system/
sed -i 's#51#52#g' redis-*.service
mkdir –p /data/redis_{6380,6381}
chown -R redis:redis /opt/redis_*
chown -R redis:redis /data/redis_*
systemctl daemon-reload
systemctl start redis-master
systemctl start redis-slave
ps -ef|grep redis
-----------------------------------------------------------------------------------------------------
#6.db03的操作
pkill redis
find /opt/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#53#g"
cd /usr/lib/systemd/system/
sed -i 's#51#53#g' redis-*.service
mkdir –p /data/redis_{6380,6381}
chown -R redis:redis /opt/redis_*
chown -R redis:redis /data/redis_*
systemctl daemon-reload
systemctl start redis-master
systemctl start redis-slave
ps -ef|grep redis
-----------------------------------------------------------------------------------------------------
#7.集群手动发现节点
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.52 6380
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.53 6380
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.51 6381
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.52 6381
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.53 6381
redis-cli -h db01 -p 6380 CLUSTER NODES
#8.集群手动分配槽位
1.槽位规划
db01:6380 5461 0-5460
db02:6380 5461 5461-10921
db03:6380 5462 10922-16383
2.分配槽位
redis-cli -h db01 -p 6380 CLUSTER ADDSLOTS {0..5460}
redis-cli -h db02 -p 6380 CLUSTER ADDSLOTS {5461..10921}
redis-cli -h db03 -p 6380 CLUSTER ADDSLOTS {10922..16383}
3.查看集群状态
redis-cli -h db01 -p 6380 CLUSTER NODES
redis-cli -h db01 -p 6380 CLUSTER INFO
#9.手动部署复制关系
0.先获取集群节点信息
redis-cli -h db01 -p 6380 CLUSTER NODES
1.先删除所有6381的内容和不需要内容
6380的ID 10.0.0.51
6380的ID 10.0.0.53
6380的ID 10.0.0.52
db01:6380> flushall
OK
2.画图
3.确定复制关系
[root@db01 ~]# redis-cli -h db01 -p 6380 CLUSTER NODES
f1ea3fcf2dc9a3601611d048718d322ba98cc27d 10.0.0.51:6380@16380 myself,master - 0 1588991574000 1 connected 0-5460
8647c756fdc2ce809cf3a701bf8d5642e2b457bf 10.0.0.52:6380@16380 master - 0 1588991575245 3 connected 5461-10921
eae47d192474d6cb0d3c08e20c4d89e032840aae 10.0.0.53:6381@16381 master - 0 1588991573204 6 connected
c8bc2b94232325bc5451cef10e2d1cc532ebf957 10.0.0.53:6380@16380 master - 0 1588991574225 2 connected 10922-16383
419cf823c2418b65aa5d7de7becab3f8d4f142ef 10.0.0.52:6381@16381 master - 0 1588991571000 4 connected
8b4fe1da9a6d678ee4e2bbf31ab98a3d73aefc54 10.0.0.51:6381@16381 master - 0 1588991576263 5 connected
[root@db01 ~]# redis-cli -h db01 -p 6381 CLUSTER REPLICATE 8647c756fdc2ce809cf3a701bf8d5642e2b457bf
OK
[root@db01 ~]# redis-cli -h db02 -p 6381 CLUSTER REPLICATE c8bc2b94232325bc5451cef10e2d1cc532ebf957
OK
[root@db01 ~]# redis-cli -h db03 -p 6381 CLUSTER REPLICATE f1ea3fcf2dc9a3601611d048718d322ba98cc27d
OK
[root@db01 ~]# redis-cli -h db01 -p 6380 CLUSTER NODES
f1ea3fcf2dc9a3601611d048718d322ba98cc27d 10.0.0.51:6380@16380 myself,master - 0 1588991661000 1 connected 0-5460
8647c756fdc2ce809cf3a701bf8d5642e2b457bf 10.0.0.52:6380@16380 master - 0 1588991661979 3 connected 5461-10921
eae47d192474d6cb0d3c08e20c4d89e032840aae 10.0.0.53:6381@16381 slave f1ea3fcf2dc9a3601611d048718d322ba98cc27d 0 1588991662992 6 connected
c8bc2b94232325bc5451cef10e2d1cc532ebf957 10.0.0.53:6380@16380 master - 0 1588991660000 2 connected 10922-16383
419cf823c2418b65aa5d7de7becab3f8d4f142ef 10.0.0.52:6381@16381 slave c8bc2b94232325bc5451cef10e2d1cc532ebf957 0 1588991661000 4 connected
8b4fe1da9a6d678ee4e2bbf31ab98a3d73aefc54 10.0.0.51:6381@16381 slave 8647c756fdc2ce809cf3a701bf8d5642e2b457bf 0 1588991659000 5 connected
4.检查复制关系
redis-cli -h db01 -p 6380 CLUSTER NODES
#10.集群插入数据
1.尝试插入一条数据发现报错
10.0.0.51:6380> set k1 v1
(error) MOVED 12706 10.0.0.53:6380
#2.目前的现象
在db01的6380节点插入数据提示报错
报错内容提示应该移动到db03的6380上
在db03的6380上执行相同的插入命令可以插入成功
在db01的6380节点插入数据有时候可以,有时候不行
使用-c参数后,可以正常插入命令,并且节点切换到了提示的对应节点上
redis-cli -c -h 10.0.0.52 -p 6380
#3.问题原因
因为集群模式有ASK路由规则,加入-c参数后,会自动跳转到目标节点处理
并且最后由目标节点返回信息
4.使用工具自动部署redis集群
#1.恢复集群初始化(单节点,无互相发现)(从节点无法清除数据,需先执行初始化集群再清除。下面命令可执行2次)
redis-cli -h db01 -p 6380 flushall
redis-cli -h db02 -p 6380 flushall
redis-cli -h db03 -p 6380 flushall
redis-cli -h db01 -p 6381 flushall
redis-cli -h db02 -p 6381 flushall
redis-cli -h db03 -p 6381 flushall
redis-cli -h db01 -p 6380 cluster reset
redis-cli -h db02 -p 6380 cluster reset
redis-cli -h db03 -p 6380 cluster reset
redis-cli -h db01 -p 6381 cluster reset
redis-cli -h db02 -p 6381 cluster reset
redis-cli -h db03 -p 6381 cluster reset
redis-cli -h db03 -p 6381 cluster nodes #查看状态
#2.使用工具初始化(主节点在前3。从节点后3)(cluster-replicas 1:每一个主节点会有一个从节点)
redis-cli --cluster create 10.0.0.51:6380 10.0.0.52:6380 10.0.0.53:6380 10.0.0.51:6381 10.0.0.52:6381 10.0.0.53:6381 --cluster-replicas 1
yes
#3.检查集群
redis-cli --cluster info 10.0.0.51 6380
redis-cli -h db01 -p 6380 cluster nodes
5.使用工具扩容和缩容
扩容和缩容不需要停库
扩容和缩容过程中读取和写入数据不受影响
集群无论是缩容还是扩容,槽位始终是16384个。需根据实际的节点数据。足够平均分配
#创建新节点
mkdir -p /opt/redis_{6390,6391}/{conf,logs,pid}
mkdir -p /data/redis_{6390,6391}
cd /opt/
cp redis_6380/conf/redis_6380.conf redis_6390/conf/redis_6390.conf
cp redis_6380/conf/redis_6380.conf redis_6391/conf/redis_6391.conf
sed -i 's#6380#6390#g' redis_6390/conf/redis_6390.conf
sed -i 's#6380#6391#g' redis_6391/conf/redis_6391.conf
redis-server /opt/redis_6390/conf/redis_6390.conf
redis-server /opt/redis_6391/conf/redis_6391.conf
ps -ef|grep redis
redis-cli -c -h db01 -p 6380 cluster meet 10.0.0.51 6390
redis-cli -c -h db01 -p 6380 cluster meet 10.0.0.51 6391
redis-cli -c -h db01 -p 6380 cluster nodes
---------------------------------------------------------------------------------
#扩容
#1.重新分配槽位
redis-cli --cluster reshard 10.0.0.51:6380
#2.第一次交互:每个节点分配多少个槽位
How many slots do you want to move (from 1 to 16384)? 4096
#3.第二次交互:接受节点的ID是什么
What is the receiving node ID? 6390的ID
#4.第三次交互:哪些节点需要导出
Source node #1: all
#5.第四次交互:确认是否执行
Do you want to proceed with the proposed reshard plan (yes/no)? yes
--------------------------------------------------------------------------------------
#缩容
#使用工具缩容
#查看集群id命令
[root@db01 /opt]# redis-cli --cluster check 10.0.0.51:6380
#重新分配槽位
redis-cli --cluster reshard 10.0.0.51:6380
#1.第一次交互:需要迁移多少个槽位
How many slots do you want to move (from 1 to 16384)? 1365
#2.第二次交互:接受节点的ID是什么
What is the receiving node ID? db01的6380的ID
#3.第三次交互:哪些节点需要导出
Source node #1: db01的6390的ID
Source node #2: done
#4.第四次交互:确认
Do you want to proceed with the proposed reshard plan (yes/no)? yes
#5.重复上面的操作,直到6390所有的槽位都被分配出去了。db02 6380 db03 6380
#6.检查集群状态,确认6390没有槽位了
redis-cli --cluster info 10.0.0.51:6380
#7.使用工具删除节点了
[root@db01 /opt]# redis-cli --cluster check 10.0.0.51:6380 #查看集群节点id
redis-cli --cluster del-node 10.0.0.51:6390 6390的ID
redis-cli --cluster del-node 10.0.0.51:6391 6391的ID
6.验证集群高可用
故障的主库修复后启动会变成备胎吗?
实验结论:
主库挂了,从库会自动接替主库的角色,集群恢复正常会受超时时间控制
老得主库修复上线后,会自动变成从库,同步新的主库主动发起集群角色切换命令:
db01:6380> CLUSTER FAILOVER
7.数据迁移
新版本直接使用工具迁移
#将单节点的数据迁移至集群实验
#不加copy参数相当于mv,老数据迁移成功就删掉了
redis-cli --cluster import 10.0.0.51:6380 --cluster-from 10.0.0.51:6379
#添加copy参数相当于cp,老数据迁移成功后会保留
redis-cli --cluster import 10.0.0.51:6380 --cluster-copy --cluster-from 10.0.0.51:6379
#添加replace参数会覆盖掉同名的数据,对新集群新增加的数据不受影响
redis-cli --cluster import 10.0.0.51:6380 --cluster-copy --cluster-replace --cluster-from 10.0.0.51:6379
------------------------------------------------------------------------------------------------------------------------------
#边写边导实验:
#同时开2个终端,一个写入key,一个执行导入命令
for i in {1..1000};do redis-cli set k_${i} v_${i};sleep 0.2;echo ${i};done
redis-cli --cluster import 10.0.0.51:6380 --cluster-copy --cluster-replace --cluster-from 10.0.0.51:6379
#得出结论:只会导入当你执行导入命令那一刻时,当前被导入节点的所有数据,类似于快照,对于后面再写入的数据不会更新
8.分析key的大小
#使用自带工具分析
redis-cli --bigkeys
---------------------------------------------
#使用第三方工具分析
1.安装命令 yum install python-pip gcc python-devel -y
cd /opt/
git clone https://github.com/sripathikrishnan/redis-rdb-tools
cd redis-rdb-tools
pip install python-lzf
python setup.py install
-------------------------------------------------------------------------------------
#2.生成测试数据
redis-cli -h db01 -p 6379 set txt $(cat txt.txt)
#3.执行bgsave生成rdb文件
redis-cli -h db01 -p 6379 BGSAVE
#4.使用工具分析
cd /data/redis_6379/
rdb -c memory redis_6379.rdb -f redis_6379.rdb.csv
#5.过滤分析
awk -F"," '{print $4,$3}' redis_6379.rdb.csv |sort -r
#6.将结果整理汇报给领导,询问开发这个key是否可以删除
9.redis的内存管理
#1.设置最大内存限制
config set maxmemory 2G
#2.内存回收机制
生产上一定要限制redis的内存使用大小。
当达到内存使用限制之后redis会出发对应的控制策略
#redis支持6种策略:
1.noevicition 默认策略,不会删除任务数据,拒绝所有写入操作并返回客户端错误信息,此时只响应读操作
2.volatile-lru 根据LRU算法删除设置了超时属性的key,指导腾出足够空间为止,如果没有可删除的key,则退回到noevicition策略
3.allkeys-lru 根据LRU算法删除key,不管数据有没有设置超时属性
4.allkeys-random 随机删除所有key
5.volatile-random 随机删除过期key
5.volatile-ttl 根据key的ttl,删除最近要过期的key
#3.生产上redis限制多大内存
先空出来系统一半内存
48G 一共
24G 系统
24G redis
redis先给8G内存 满了之后,分析结果告诉老大和开发,让他们排查一下是否所有的key都是必须的
redis再给到12G内存 满了之后,分析结果告诉老大和开发,让他们排查一下是否所有的key都是必须的
redis再给到16G内存 满了之后,分析结果告诉老大和开发,让他们排查一下是否所有的key都是必须的
等到24G都用完了之后,汇报领导,要考虑买内存了。
等到35G的时候,就要考虑是加内存,还是扩容机器。
#优化相关
禁用swap
内存
SSD
redis-cli --scan --pattern 'k*'
故障案例1:
背景:某日接到任务,需要部署redis集群
结果:结果不小心无脑复制粘贴,把所有的槽都分配给了1个节点,还没发现,然后就交付使用了,过了1天才发现问题。
而此时,已经有不少数据写入了,如何在不丢失数据的情况下解决这个问题?
前.提:数据不能丢,最好不中断业务
#1. 实验现象:
[root@db01 ~]# redis-cli --cluster info 10.0.0.51 6380
10.0.0.51:6380 (ccaa5dcb...) -> 1000 keys | 16384 slots | 3 slaves.
10.0.0.53:6380 (a69e46ea...) -> 0 keys | 0 slots | 0 slaves.
10.0.0.52:6380 (b2719c41...) -> 0 keys | 0 slots | 0 slaves.
[OK] 1000 keys in 3 masters.
0.06 keys per slot on average.
---------------------------------------------------------------------------------------------------------------------
#解决方案一:
#0.重新制作一个测试集群,槽位分布和线上出错的一样
#1.将线上环境里的aof导出来
redis-cli -c -h db01 -p 6380
db01:6380> BGREWRITEAOF #生成aof文件
cp redis.aof redis.aof-1000.bak
#2.恢复到测试的集群里
#3.收集所有的key
#4.编写脚本遍历所有的key获取值(参数-c:连接集群结点时使用,此选项可防止moved和ask异常。)
cat >get_key.sh<<EOF
#!/bin/bash
for key in $(cat keys_all.txt)
do
value=$(redis-cli -c -h 10.0.0.51 -p 6380 get ${key})
echo redis-cli -c -h 10.0.0.51 -p 6380 set ${key} ${value} >> backup_all_key.txt
done
EOF
#5.按照正常槽位分配去重新初始化集群
redis-cli -h db01 -p 6380 FLUSHALL
redis-cli -h db02 -p 6380 FLUSHALL
redis-cli -h db03 -p 6380 FLUSHALL
redis-cli -h db01 -p 6380 CLUSTER RESET
redis-cli -h db02 -p 6380 CLUSTER RESET
redis-cli -h db03 -p 6380 CLUSTER RESET
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.52 6380
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.53 6380
redis-cli -h db01 -p 6380 CLUSTER NODES
redis-cli -h db01 -p 6380 CLUSTER ADDSLOTS {0..5460}
redis-cli -h db02 -p 6380 CLUSTER ADDSLOTS {5461..10921}
redis-cli -h db03 -p 6380 CLUSTER ADDSLOTS {10922..16383}
redis-cli --cluster info 10.0.0.51 6380
#6.执行导入脚本
bash backup_all_key.txt
#7.检查是否导入成功
redis-cli --cluster info 10.0.0.51 6380
#8.测试环境没问题之后再去生产环境操作
----------------------------------------------------------------------------------------------------------------------------
#解决方案二: 流水线 pipline
#前提条件:
#1.了解aof格式
#2.了解新版本redis默认是开启混合模式的
(Redis 5.0 版本默认是开启状态,这里需关闭。写入配置文件)
混合持久化:
aof-use-rdb-preamble no
#3.需要修改为普通的aof格式并重启
#4.恢复时使用-c参数无效,需要在每一个节点都执行
命令:(每个节点会写入正确的槽位,无法写入的会报错,正常现象)
redis-cli -c -h 10.0.0.51 -p 6380 --pipe < redis.aof
redis-cli -c -h 10.0.0.52 -p 6380 --pipe < redis.aof
redis-cli -c -h 10.0.0.53 -p 6380 --pipe < redis.aof
-------------------------------------------------------------------------------------------------------------------------
#解决方案三: 使用redis-cli工具
#1.重新分配槽位
redis-cli --cluster reshard 10.0.0.51:6380
#2.第一次交互:输入迁出的槽的数量
How many slots do you want to move (from 1 to 16384)? 5461
#3.第二次交互:输入接受的ID
What is the receiving node ID? db02的6380的ID
#4.第三次交互:输入发送者的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: db01的6390的ID
Source node #2: done
#5.第四次交互:YES!
#重复上面的操作,知道所有的节点槽位都分配正确
案例2:
这是在有槽位的情况下 如果 公司先用的是哨兵然后在改集群
思路:
1.搭建好Redis集群并互相发现
2.把所有的key都分配到db01上
3.把哨兵里的数据AOF持久化,并拷贝到db01上,启动集群节点
4.重新分配槽位迁移到其他2个节点
故障案例3:
迁移数据时人为中断了,导致槽的状态不对
[11213-<-a69e46ea7560684a7061ddb6dc3f854a1ef3dbd4] 51节点
[11213->-ccaa5dcb0f0320332100594d629122b2702660d5] 53节点
#方案一:
#使用工具修复:
redis-cli --cluster fix 10.0.0.51:6380
#方案二:
手动修复:(<slot>:填写故障的槽位数:如上面的11213)
10.0.0.51:6389> CLUSTER SETSLOT <slot> STABLE