2019-07-04 NoSQL-Day02-Redis Cluster

Redis Cluster 集群

重点知识:

1.槽位分配slot
2.16384个槽位
3.每一个槽都得分配到位,有一个槽没分配,整个集群不可用
4.序号顺序不一定要连续,最重要的是每个节点的槽位数量要大致相同,允许2%的误差
5.6380是启动服务的默认端口,集群通信端口为配置文件里的port加10000,比如6380,通信端口就是16380
tcp        0      0 10.0.0.53:16380         0.0.0.0:*               LISTEN      1467/redis-server 1 
tcp        0      0 10.0.0.53:16381         0.0.0.0:*               LISTEN      1469/redis-server 1 
tcp        0      0 10.0.0.53:6380          0.0.0.0:*               LISTEN      1467/redis-server 1 
tcp        0      0 10.0.0.53:6381          0.0.0.0:*               LISTEN      1469/redis-server 1 
6.故障转移切换全自动,不需要人工干预
7.集群配置文件动态更新,千万千万千万不要手动修改
8.所有的集群配置文件除了IP 不一样,其他都一致
9.代码连接redis集群需要插件驱动支持
10.集群内消息传递是同步的
11.集群内的所有已经发现的节点配置文件是自动更新的
12.hash分配算法是足够随机足够平均足够稳定的

一、集群介绍

分布式方案有两种:

1.客户端分区方案,优点分区逻辑可控,缺点是自己处理数据路由,高可用和故障转移等。

2.代理方案,优点是简化客户端分布式逻辑和升级维护便利,缺点是加重架构部署和性能消耗。

官方提供的 Redis Cluster 集群方案,很好的解决了集群方面的问题

二、数据分布

分布式数据首先要解决把整个数据库集按照分区规则映射到多个节点的问题,即把数据集划分到 多个节点上,每个节点负责整体数据的一个子集,需要关注的是数据分片规则,Redis Cluster 采用 哈希分片规则。 

三、目录规划

# redis 安装目录 
/opt/redis_cluster/redis_{PORT}/{conf,logs,pid} 
# redis 数据目录 
/data/redis_cluster/redis_{PORT}/redis_{PORT}.rdb 
# redis 运维脚本 
/root/scripts/redis_shell.sh 

四、集群拓扑

image.png

五、搭建部署集群

思路:
1)部署一台服务器上的 2 个集群节点
2)发送完成后修改其他主机的 IP 地址
3)使用 ansible 批量部署

实现命令:

db01操作

mkdir -p /opt/redis_cluster/redis_{6380,6381}/{conf,logs,pid} 
mkdir –p /data/redis_cluster/redis_{6380,6381} 

cat >/opt/redis_cluster/redis_6380/conf/redis_6380.conf<<EOF 
bind 10.0.0.51 
port 6380 
daemonize yes 
pidfile "/opt/redis_cluster/redis_6380/pid/redis_6380.pid" 
logfile "/opt/redis_cluster/redis_6380/logs/redis_6380.log" 
dbfilename "redis_6380.rdb" 
dir "/data/redis_cluster/redis_6380/" 
cluster-enabled yes 
cluster-config-file nodes_6380.conf 
cluster-node-timeout 15000 
EOF 

cd /opt/redis_cluster/ 
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  

rsync -avz /opt/redis_cluster/redis_638* db02:/opt/redis_cluster/ 
rsync -avz /opt/redis_cluster/redis_638* db03:/opt/redis_cluster/ 

redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf 
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf 

db02操作

find /opt/redis_cluster/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#52#g" 

mkdir –p /data/redis_cluster/redis_{6380,6381} 

redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf 
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf 

db03操作

find /opt/redis_cluster/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#53#g" 
mkdir –p /data/redis_cluster/redis_{6380,6381} 
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf 
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf 

5.1 手动配置节点发现

当把所有节点都启动后查看进程会有 cluster 的字样

[root@db01 ~]# ps -ef |grep redis
root       1428      1  0 10:16 ?        00:00:00 redis-server 10.0.0.51:6380 [cluster]
root       1430      1  1 10:16 ?        00:00:00 redis-server 10.0.0.51:6381 [cluster]
root       1436   1378  0 10:17 pts/0    00:00:00 grep --color=auto redis

集群模式的 Redis 除了原有的配置文件之外又加了一份集群配置文件。当集群内节点 信息发生变化,如添加节点,节点下线,故障转移等。节点会自动保存集群状态到配置文件.。需要注意的是,Redis 自动维护集群配置文件,不需要手动修改,防止节点重启时产生错乱。

节点发现使用命令:CLUSTER MEET {IP} {PORT} 

提示:在集群内任意一台机器执行此命令就可以 

[root@db01 ~]# sh redis_shell.sh login 6380 
10.0.0.51:6380> CLUSTER MEET 10.0.0.51 6381 
OK 
10.0.0.51:6380> CLUSTER MEET 10.0.0.52 6380 
OK 
10.0.0.51:6380> CLUSTER MEET 10.0.0.53 6380 
OK 
10.0.0.51:6380> CLUSTER MEET 10.0.0.52 6381 
OK 
10.0.0.51:6380> CLUSTER MEET 10.0.0.53 6381 
OK

10.0.0.51:6380> CLUSTER NODES 
d03cb38d612802aead8f727b1726a3359c241818 10.0.0.51:6380 myself,master - 0 0 4 connected 
67c8128df00b2fa304a41bafbadac25a654f196d 10.0.0.51:6381 master - 0 1562059947079 1 connected 
a23ec7d444791a0b258ac454ef15cb4d6ab5abd2 10.0.0.53:6381 master - 0 1562059948087 5 connected 
e57807d4d35daaaca05f4a9705e844eab15c7ce8 10.0.0.52:6381 master - 0 1562059949098 0 connected 
aa9da67a594dfb357195f12ca4c44001804ee470 10.0.0.53:6380 master - 0 1562059945063 3 connected 
5cb6895305520e6a0aa4198a6ea5f2c087530b41 10.0.0.52:6380 master - 0 1562059950108 2 connected
 

节点都发现完毕后我们再次查看集群配置文件 可以看到,发现到的节点的 ID 也被写入到了集群的配置文件里(我这里已经做完了节点关系的高可用)

[root@db01 ~]# cat /data/redis_cluster/redis_6380/nodes_6380.conf 
821dd9352ff687cb2ecb869f4c2d370be7b724aa 10.0.0.51:6380 myself,master - 0 0 1 connected 0-5460
0d68871005f8faa57a73d67aa7ea23e7bddd3929 10.0.0.52:6381 slave 8af54cf5c75ded90575d37db8790925f50f2f4ec 0 1562233343851 5 connected
298d4807103496195ab665441971650432aecac5 10.0.0.51:6381 slave a948345a916def81b17aca5b6603cbd02c293325 0 1562233337810 4 connected
2f6c6e8f43a41367ea6311b766ce8e9088489361 10.0.0.53:6381 slave 821dd9352ff687cb2ecb869f4c2d370be7b724aa 0 1562233344827 6 connected
8af54cf5c75ded90575d37db8790925f50f2f4ec 10.0.0.53:6380 master - 0 1562233340832 3 connected 10923-16383
a948345a916def81b17aca5b6603cbd02c293325 10.0.0.52:6380 master - 0 1562233341839 2 connected 5461-10922
vars currentEpoch 6 lastVoteEpoch 0
5.2 Redis Cluster 通讯流程

在分布式存储中需要提供维护节点元数据信息的机制,所谓元数据是指:节点负责哪些数据,是否 出现故障灯状态信息,redis 集群采用 Gossip(流言)协议,Gossip 协议工作原理就是节点彼此不断 交换信息,一段时间后所有的节点都会知道集群完整信息,这种方式类似流言传播。

 通信过程: 
1)集群中的每一个节点都会单独开辟一个 Tcp 通道,用于节点之间彼此通信,通信端口在基础端口上加 10000. 
2)每个节点在固定周期内通过特定规则选择结构节点发送 ping 消息 
3)接收到 ping 消息的节点用 pong 消息作为响应。集群中每个节点通过一定规则挑选要通信的节点,每个节点
可能知道全部节点,也可能仅知道部分节点,只要这些节点彼此可以正常通信,最终他们会打成一致的状态,当
节点出现故障,新节点加入,主从角色变化等,它能够给不断的 ping/pong 消息,从而达到同步目的。 
通讯消息类型: Gossip
 
Gossip 协议职责就是信息交换,信息交换的载体就是节点间彼此发送 Gossip 消息。 
常见 Gossip 消息分为:ping、 pong、 meet、 fail 等

meet 

meet 消息:用于通知新节点加入,消息发送者通知接受者加入到当前集群,meet 消息通信正常完成后,接收节
点会加入到集群中并进行 ping、 pong 消息交换 

ping 

ping 消息:集群内交换最频繁的消息,集群内每个节点每秒想多个其他节点发送 ping 消息,用于检测节点是否
在线和交换彼此信息。 

pong 

Pong 消息:当接收到 ping,meet 消息时,作为相应消息回复给发送方确认消息正常通信,节点也可以向集群内
广播自身的 pong 消息来通知整个集群对自身状态进行更新。 

fail 
fail 消息:当节点判定集群内另一个节点下线时,会向集群内广播一个 fail 消息,其他节点收到 fail 消息之
后把对应节点更新为下线状态。 

5.3 Redis Cluster 手动分配槽位

分配槽位的方法:
分配槽位需要在每个主节点上来配置,此时有 2 种方法执行:
1.分别登录到每个主节点的客户端来执行命令
2.在其中一台机器上用 redis 客户端远程登录到其他机器的主节点上执行命令

每个节点执行命令:
[root@db01 ~]# redis-cli -h db01 -p 6380 cluster addslots {0..5461}
OK
[root@db01 ~]# redis-cli -h db02 -p 6380 cluster addslots {5462..10922}
OK
[root@db01 ~]# redis-cli -h db03 -p 6380 cluster addslots {10923..16383}
OK

分配完所有槽位之后我们再查看一下集群的节点状态和集群状态 可以看到三个节点都分配了槽位,而且集群的状态是 OK 的(我这里已经做完了节点关系的高可用)

[root@db01 ~]# sh /server/scripts/redis_shell.sh login 6380
10.0.0.51:6380> CLUSTER NODES
821dd9352ff687cb2ecb869f4c2d370be7b724aa 10.0.0.51:6380 myself,master - 0 0 1 connected 0-5460
0d68871005f8faa57a73d67aa7ea23e7bddd3929 10.0.0.52:6381 slave 8af54cf5c75ded90575d37db8790925f50f2f4ec 0 1562241394582 5 connected
298d4807103496195ab665441971650432aecac5 10.0.0.51:6381 slave a948345a916def81b17aca5b6603cbd02c293325 0 1562241396598 4 connected
2f6c6e8f43a41367ea6311b766ce8e9088489361 10.0.0.53:6381 slave 821dd9352ff687cb2ecb869f4c2d370be7b724aa 0 1562241391564 6 connected
8af54cf5c75ded90575d37db8790925f50f2f4ec 10.0.0.53:6380 master - 0 1562241390557 3 connected 10923-16383
a948345a916def81b17aca5b6603cbd02c293325 10.0.0.52:6380 master - 0 1562241395591 2 connected 5461-10922
10.0.0.51:6380> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_sent:18650
cluster_stats_messages_received:18650

5.4 手动配置集群高可用

虽然这时候集群是可用的了,但是整个集群只要有一台机器坏掉了,那么整个集群都是不可用的. 所以这时候需要用到其他三个节点分别作为现在三个主节点的从节点,以应对集群主节点故障时可以 进行自动切换以保证集群持续可用.
注意:
1.不要让复制节点复制本机器的主节点, 因为如果那样的话机器挂了集群还是不可用状态, 所以复制 节点要复制其他服务器的主节点.
2.使用 redis-trid 工具自动分配的时候会出现复制节点和主节点在同一台机器上的情况,需要注意

image.png
5.5 使用工具搭建部署 Redis Cluster

手动搭建集群便于理解集群创建的流程和细节,不过手动搭建集群需要很多步骤,当集群节点众多 时,必然会加大搭建集群的复杂度和运维成本,因此官方提供了 redis-trib.rb 的工具方便我们快速搭 建集群。
redis-trib.rb 是采用 Ruby 实现的 redis 集群管理工具,内部通过 Cluster 相关命令帮我们简化集群 创建、检查、槽迁移和均衡等常见运维操作,使用前要安装 ruby 依赖环境

安装命令:

yum makecache fast 
yum install rubygems 
gem sources --remove https://rubygems.org/ 
gem sources -a http://mirrors.aliyun.com/rubygems/ 
gem update –system 
gem install redis -v 3.3.5
#我们可以停掉所有的节点,然后清空数据,恢复成一个全新的集群,所有机器执行命令 
pkill redis 
rm -rf /data/redis_cluster/redis_6380/* 
rm -rf /data/redis_cluster/redis_6381/* 

#全部清空之后启动所有的节点,所有机器执行 
sh redis_shell.sh start 6380 
sh redis_shell.sh start 6381 

#db01 执行创建集群命令 
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

#检查集群完整性 
./redis-trib.rb check 10.0.0.51:6380 

5.6 Redis 集群常用命令
集群(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 将节点的配置文件保存到硬盘里面。  

槽(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)。  

键 (key) 

CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
 
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。CLUSTER GETKEYSINSLOT <slot> 
<count> 返回 count 个 slot 槽中的键。 


总结:

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容