Redis--集群

01,Redis集群-最新版5.x

1.哨兵的不⾜

1.主库写压⼒太⼤
2.资源利⽤率不⾼
3.连接过程繁琐,效率低

2.集群的重要概念

1.Redis集群,⽆论有⼏个节点,⼀共只有16384个槽位
2.所有的槽都必须被正确分配,哪怕有1个槽不正常,整个集群都不可⽤
3.每个节点的槽的顺序不重要,重要的是槽的数量
4.HASH算法⾜够平均,⾜够随机
5.每个槽被分配到数据的概率是⼤致相当的
6.集群的⾼可⽤依赖于主从复制
7.集群节点之间槽位的数量允许在2%的误差范围内
8.集群通讯会使⽤基础端⼝号+10000的端⼝,⾃动创建的,不是配置⽂件配置的,⽣产要注意的是防⽕墙注意要放开此端⼝

3.⽬录规划

主节点 6380
从节点 6381

4.db01的操作

#1.发送SSH认证,⽅便后⾯传输
ssh-keygen
ssh-copy-id 10.0.0.52
ssh-copy-id 10.0.0.53
#2.创建⽬录
pkill redis
mkdir -p /opt/redis_{6380,6381}/{conf,logs,pid}
mkdir -p /data/redis_{6380,6381}
#3.⽣成主节点配置⽂件
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
#4.复制主节点的配置⽂件到从节点并更改端⼝号
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
#5.更改授权为redis
chown -R redis:redis /opt/redis_*
chown -R redis:redis /data/redis_*
#6.⽣成主节点的systemd启动⽂件
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
#7.复制master节点的启动⽂件给slave节点并修改端⼝号
cd /usr/lib/systemd/system/
cp redis-master.service redis-slave.service
sed -i 's#6380#6381#g' redis-slave.service
#8.重载并启动集群节点
systemctl daemon-reload
systemctl start redis-master
systemctl start redis-slave
ps -ef|grep redis
#9.把创建好的⽬录和启动⽂件发送给db02和db03
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的操作

#1.替换db01发送过来的⽂件并修改IP地址
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的操作

#1.替换db01发送过来的⽂件并修改IP地址
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 10.0.0.51 -p 6380 CLUSTER MEET 10.0.0.52 6380
redis-cli -h 10.0.0.51 -p 6380 CLUSTER MEET 10.0.0.53 6380
redis-cli -h 10.0.0.51 -p 6380 CLUSTER MEET 10.0.0.51 6381
redis-cli -h 10.0.0.51 -p 6380 CLUSTER MEET 10.0.0.52 6381
redis-cli -h 10.0.0.51 -p 6380 CLUSTER MEET 10.0.0.53 6381
redis-cli -h 10.0.0.51 -p 6380 CLUSTER NODES

8.集群⼿动分配槽位

①槽位规划
db01:6380 5461 0-5460
db02:6380 5461 5461-10921
db03:6380 5462 10922-16383
②分配槽位
redis-cli -h 10.0.0.51 -p 6380 CLUSTER ADDSLOTS {0..5460}
redis-cli -h 10.0.0.52 -p 6380 CLUSTER ADDSLOTS {5461..10921}
redis-cli -h 10.0.0.53 -p 6380 CLUSTER ADDSLOTS {10922..16383}
③查看集群状态
redis-cli -h 10.0.0.51 -p 6380 CLUSTER NODES
redis-cli -h 10.0.0.51 -p 6380 CLUSTER INFO

9.⼿动分配复制关系

①先获取集群节点信息
redis-cli -h 10.0.0.52 -p 6381 CLUSTER nodes
②过滤删除不必要的信息
6380的ID 10.0.0.51
6380的ID 10.0.0.53
6380的ID 10.0.0.52
③配置复制关系
redis-cli -h 10.0.0.51 -p 6381 CLUSTER REPLICATE db02的6380的ID
redis-cli -h 10.0.0.52 -p 6381 CLUSTER REPLICATE db03的6380的ID
redis-cli -h 10.0.0.53 -p 6381 CLUSTER REPLICATE db01的6380的ID
④检查复制关系
redis-cli -h 10.0.0.51 -p 6381 CLUSTER NODES

02,集群写⼊数据

1.尝试插⼊⼀条数据

[root@db01 ~]# redis-cli -h 10.0.0.51 -p 6380
10.0.0.51:6380> set k1 v1
(error) MOVED 12706 10.0.0.53:6380
[root@db01 ~]# redis-cli -c -h 10.0.0.51 -p 6380
10.0.0.51:6380>
10.0.0.51:6380> set k4 v4
-> Redirected to slot [8455] located at 10.0.0.52:6380
OK
10.0.0.52:6380> keys *
1) "k4"
10.0.0.52:6380> get k4
"v4"

2.⽬前的现象

1.在db01的6380上插⼊数据提示错误
2.报错提示应该移动到db03的6380上
3.根据提示在db03的6380上执⾏相同的命令可以写⼊成功
4.db01的6380有的数据可以写⼊,有的不⾏
5.使⽤-c参数后,可以正常写⼊命令,并且由⽬标节点返回信息

3.问题原因

因为集群模式有ASK规则,加⼊-c参数后,会⾃动跳转到⽬标节点处理并由⽬标节点返回信息。

4.ASK路由流程图

图片.png

03,验证集群hash算法是否⾜够随机⾜够平均

1.写⼊测试命令

for i in {1..1000};do redis-cli -c -h 10.0.0.51 -p 6380 set k_${i}
v_${i} && echo "${i} is ok";done

2.验证⾜够平均

[root@db01 ~]# redis-cli -c -h 10.0.0.51 -p 6380 DBSIZE
(integer) 339
[root@db01 ~]# redis-cli -c -h 10.0.0.52 -p 6380 DBSIZE
(integer) 326
[root@db01 ~]# redis-cli -c -h 10.0.0.53 -p 6380 DBSIZE
(integer) 335

3.验证⾜够随机

redis-cli -c -h 10.0.0.51 -p 6380 keys \* > keys.txt
cat keys.txt |awk -F "_" '{print $2}'|sort -rn

4.允许节点的槽个数误差在2%以内的依据

[root@db01 ~]# redis-cli --cluster rebalance 10.0.0.51:6380
>>> Performing Cluster Check (using node 10.0.0.51:6380)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** No rebalancing needed! All nodes are within the 2.00% threshold.

5.检查集群健康状态

[root@db01 ~]# redis-cli --cluster info 10.0.0.51:6380
10.0.0.51:6380 (f765d849...) -> 3343 keys | 5461 slots | 1 slaves.
10.0.0.52:6380 (5ff2b711...) -> 3314 keys | 5461 slots | 1 slaves.
10.0.0.53:6380 (de167d13...) -> 3343 keys | 5462 slots | 1 slaves.
[OK] 10000 keys in 3 masters.
0.61 keys per slot on average.

04,使⽤⼯具⾃动部署redis集群-通⽤ruby法

1.安装依赖-只要在db01上操作

yum install -y rubygems
gem sources -a http://mirrors.aliyun.com/rubygems/
gem sources --remove http://rubygems.org/
gem install redis -v 3.3.3

2.还原集群环境

redis-cli -c -h 10.0.0.51 -p 6380 flushall
redis-cli -c -h 10.0.0.52 -p 6380 flushall
redis-cli -c -h 10.0.0.53 -p 6380 flushall
redis-cli -h 10.0.0.51 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.51 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6381 CLUSTER RESET

3.快速部署Redis集群

cd /opt/redis_cluster/redis/src
./redis-trib.rb create --replicas 1 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

05,使⽤⼯具⾃动部署redis集群-⾼科技版

1.还原集群状态

redis-cli -c -h 10.0.0.51 -p 6380 flushall
redis-cli -c -h 10.0.0.52 -p 6380 flushall
redis-cli -c -h 10.0.0.53 -p 6380 flushall
redis-cli -h 10.0.0.51 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.51 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6381 CLUSTER RESET

2.快速部署Redis集群

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

3.检查集群

redis-cli --cluster info 10.0.0.51:6380

06,使⽤⼯具扩容

图片.png

1.需要考虑的问题

1.迁移时槽的数据会不会迁过去
2.迁移过程集群读写受影响吗
3.需要限速吗
4.如何确保迁移后的完整性

2.如何设计实验验证迁移过程是否受影响

1.迁移过程中,⼀个窗⼝读数据,⼀个窗⼝写数据
2.观察是否会中断

3.创建新节点

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 10.0.0.51 -p 6380 cluster meet 10.0.0.51 6390
redis-cli -c -h 10.0.0.51 -p 6380 cluster meet 10.0.0.51 6391
redis-cli -c -h 10.0.0.51 -p 6380 cluster nodes

4.扩容步骤

#重新分配槽位
redis-cli --cluster reshard 10.0.0.51:6380
#第⼀次交互:每个节点最终分配多少个槽
How many slots do you want to move (from 1 to 16384)? 4096
#第⼆次交互:接受节点的ID
What is the receiving node ID? 6390的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:all
#第四次交互:确认信息
Do you want to proceed with the proposed reshard plan (yes/no)? yes

5.验证命令

写命令

for i in {1..1000};do redis-cli -c -h 10.0.0.51 -p 6380 set k_${i} v_${i} && echo ${i} is ok;sleep 0.5;done

读命令

for i in {1..1000};do redis-cli -c -h 10.0.0.51 -p 6380 get k_${i};sleep 0.5;done

07,使⽤⼯具收缩

图片.png

1.缩容命令

#重新分配槽
redis-cli --cluster reshard 10.0.0.51:6380
#第⼀次交互:需要迁移多少个槽
How many slots do you want to move (from 1 to 16384)? 1365
#第三次交互:接受节点ID是多少
What is the receiving node ID? db01的6380的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: 6390的ID
Source node #2: done
#第四次交互:确认信息
Do you want to proceed with the proposed reshard plan (yes/no)? yes
重复上述操作,知道6390所有的槽都被分配完毕

2.检查命令

redis-cli --cluster info 10.0.0.51:6380

3.归⼀再分配法

归⼀

把要缩容节点的数据都扔到其中⼀个节点

分配

然后利⽤集群重新负载均衡命令重新分配
redis-cli --cluster rebalance 10.0.0.51:6380

08,模拟故障转移

1.关闭主节点,测试集群是否依然可⽤

10.0.0.51:6381> CLUSTER NODES
f765d849975ddfda7029d16be717ddffcc4c4bc7 10.0.0.51:6380@16380 slave
2a55b4454e33b3c5a953264c9d69a58a56ab1a85 0 1587000834939 20 connected
5ff2b711ff5b377bf06ce5ef878b3a7aaf881a98 10.0.0.52:6380@16380 slave
7d1328883b4a162d2728f8719fffc53d5fb3d801 0 1587000838082 22 connected
de167d131d45eedcb9b56ef0021ae110d6e55d46 10.0.0.53:6380@16380 slave
aef2cbf60bc3109ba76253d52d691e2dba7bd3e5 0 1587000837000 21 connected
aef2cbf60bc3109ba76253d52d691e2dba7bd3e5 10.0.0.51:6381@16381
myself,master - 0 1587000837000 21 connected 10923-16383
2a55b4454e33b3c5a953264c9d69a58a56ab1a85 10.0.0.52:6381@16381 master - 0
1587000837000 20 connected 0-5460
7d1328883b4a162d2728f8719fffc53d5fb3d801 10.0.0.53:6381@16381 master - 0
1587000837070 22 connected 5461-10922

2.主动发起故障转移

redis-cli -c -h 10.0.0.51 -p 6380 CLUSTER FAILOVER
redis-cli -c -h 10.0.0.52 -p 6380 CLUSTER FAILOVER
redis-cli -c -h 10.0.0.53 -p 6380 CLUSTER FAILOVER

09,迁移过程意外中断如何修复

1.模拟场景:迁移时⼈为中断,导致槽的状态不对

[5754->-f765d849975ddfda7029d16be717ddffcc4c4bc7]

2.⼿动修复

redis-cli -c -h 10.0.0.52 -p 6380 CLUSTER SETSLOT 5754 STABLE

3.使⽤⼯具修复-⽣产建议使⽤⼯具修复

redis-cli --cluster fix 10.0.0.51:6380

10,RedisCluster常⽤命令整理

1.集群(cluster)

CLUSTER INFO 打印集群的信息
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
节点(node)
CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群
的⼀份⼦。
CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。
CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。
CLUSTER SAVECONFIG 将节点的配置⽂件保存到硬盘⾥⾯。

2.槽(slot)

CLUSTER ADDSLOTS <slot> [slot ...] 将⼀个或多个槽(slot)指派(assign)给当前
节点。
CLUSTER DELSLOTS <slot> [slot ...] 移除⼀个或多个槽对当前节点的指派。
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成⼀个没有指派任何槽的节
点。
CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,
如果槽已经指派给另⼀个节点,那么先让另⼀个节点删除该槽>,然后再进⾏指派。
CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id
指定的节点中。
CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导⼊槽
slot 到本节点。
CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导⼊(import)或者迁移
(migrate)

3.键 (key)

CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot ⽬前包含的键值对数量。
CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,362评论 6 544
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,577评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,486评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,852评论 1 317
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,600评论 6 412
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,944评论 1 328
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,944评论 3 447
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,108评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,652评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,385评论 3 358
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,616评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,111评论 5 364
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,798评论 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,205评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,537评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,334评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,570评论 2 379

推荐阅读更多精彩内容