redis cluster

1.集群介绍

redis cluster 是redis的分布式解决方案,在3.0版本正式推出当遇到单机,内存,并发流量等瓶颈时,可以采用cluster架构方案达到负载均衡目的。
redis cluster之前的分布式方案有两种:

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

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

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

2.数据分布

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

 3.目录规划

#redis安装目录
/opt/redis_cluster/redis_{port}/{conf,logs,pid}

#数据目录
/data/redis_cluster/redis_{port}/redis_{port}.rdb

#redis脚本
/root/scripts/redis_shell.sh

4.集群拓扑图

 5.cluster安装部署

###cluster的配置文件,三个节点都做

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 $(hostname -I)
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
cat >/opt/redis_cluster/redis_6381/conf/redis_6381.conf<<EOF
bind $(hostname -I)
port 6381
daemonize yes
pidfile "/opt/redis_cluster/redis_6381/pid/redis_6381.pid"
logfile "/opt/redis_cluster/redis_6381/logs/redis_6381.log"
dbfilename "redis_6381.rdb"
dir "/data/redis_cluster/redis_6381"
cluster-enabled yes
cluster-config-file nodes_6381.conf
cluster-node-timeout 15000
EOF

###启动redis-cluster

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

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

###检查一下是否启动成功

ps -ef |grep redis

netstat -lnp |grep redis

###发现一下各个节点

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.61 6380
redis-cli -h 10.0.0.51 -p 6380 cluster meet 10.0.0.61 6381
redis-cli -h 10.0.0.51 -p 6380 cluster meet 10.0.0.71 6380
redis-cli -h 10.0.0.51 -p 6380 cluster meet 10.0.0.71 6381

###进入redis查看各个节点是否都加上了是否和cat /data/redis_cluster/redis_6380/nodes_6380.conf文件一致

CLUSTER NODES

6.redis- cluster通讯流程

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

1)通讯过程:

1)集群中的每一个节点都会单独开辟一个TPC通道,用于节点之间批次通信,通信端口在基础上加10000.

2)每个节点在固定的周期内通过特定规则选择结构节点发送ping消息

3)接收到ping消息的节点用pong消息作为响应。集群中每个节点通过一定规则挑选要通信的节点,每个节点可能知道全部节点,也可能知道部分节点,
只要这些节点彼此可以互相通信,最终他们会达成一致的状态,当节点出现故障,新节点加入,主节点角色变化等,它们能不断的ping/pong消息,从而达到同步的目的

 

2)通讯消息类型:

Gossip协议职责就是信息交换,信息交换的载体就是节点间批次发送gossip消息

常见gossip消息分布:
ping,pong,meet,fail等 meet消息:用于通知新节点加入,消息发送者通知接受者加入当前集群,meet消息通信正常完成后,接收节点会加入到集群中并进行ping/pong消息交换 ping消息:集群内交换最频繁的消息,集群内每个节点每秒想多个其他节点发送ping消息,用于检测节点是否在线和交换彼此信息。 pong消息:当接收到ping,meet消息时,作为相应消息回复给发送方确认消息正常通信,节点也可以向集群内广播吱声的pong消息来通知整个集群对自身状态进行更新 fail消息:当节点判定集群内另一个节点下线时,会向集群内广播一个fail消息,其他节点收到fail消息之后把对应节点更新为下线状态。

7.手动分配槽位

虽然节点之间已经互相发现了,但是此时的集群还是不可用的状态,因为并有给节点分配槽位,
而且必须是所有的槽位都分配完毕后整个集群才是可用的状态,反之,有一个槽位没有分配那么整个集群还是不可用的
###查看当前的node
CLUSTER NODES
###
CLUSTER INFO查看当前集群详细信息
10.0.0.51:6380> CLUSTER INFO
cluster_state:fail  ------------集群状态
cluster_slots_assigned:0 -------分配了多少槽位
cluster_slots_ok:0 -------------ok的有多少
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
cluster_current_epoch:5
cluster_my_epoch:1
cluster_stats_messages_sent:373
cluster_stats_messages_received:163

前面说了,我们虽然有6个节点,但是真正负责数据写入的只有3个节点,其他3个节点只是作为主节点的从节点,也就是说只需要分配其中的三个节点的槽位就OK了

分配槽位的方法:分配槽位需要在每个节点上配置,此时有两种方法执行

1.分别登录到每个主节点的客户端来执行命令

2.在其中一台机器上用redis客户端远程登录到其他机器的主节点上执行命令

每个节点执行命令:

[root*db01~]# redis-cli -h 10.0.0.51 -p 6380 cluster addslots {0..5461}

[root*db01~]# redis-cli -h 10.0.0.61 -p 6380 cluster addslots {5462..10922}

[root*db01~]# redis-cli -h 10.0.0.71 -p 6380 cluster addslots {10923..16383}

 此时分配完了槽位可以进行插入数据了,但是有的数据插入不进去列如:

解决方法:在连接redis时加上-c的参数,自动获取目标节点信息写入信息读取信息

redis-cli -c -h 10.0.0.51 -p 6380

 8.测试:顺序插入1000条数据,测试它够不够平均够不够随机

for i in {1..1000};do redis-cli -c -h 10.0.0.51 -p 6380 set 58NB_${i} 58V5_${i};done
redis-cli -c -h 10.0.0.51 -p 6380
keys *
DBSIZE

 9.重做集群

1.关闭所有节点
2.删除所有数据
3.启动所有节点
4.重新发现节点
5.分配槽位

10.cluster高可用

1)查看节点信息,并保存
[root*db01~]# redis-cli -c -h 10.0.0.51 -p 6380 cluster nodes
bb8b592e098fda892fd85cb43fecebd4ea634185 10.0.0.51:6380 myself,master - 0 0 1 connected 0-5461
14bfc83d04275a316101e78a23ac17ca287c2855 10.0.0.61:6380 master - 0 1608645533231 5 connected 5462-10922
73e2a32100ac736d5fcdcb524e11a1333e638360 10.0.0.71:6380 master - 0 1608645532221 2 connected 10923-16383
cd9d6825e186f0d8685da2341233f53fc55eb1e4 10.0.0.51:6381 master - 0 1608645531213 3 connected
ff72f41275668d8b2e1b3592bddfe5e0a92cb1fd 10.0.0.61:6381 master - 0 1608645534237 0 connected
8fc3fbcb152babcc58fe42b4456b617ab3e1bd41 10.0.0.71:6381 master - 0 1608645535243 4 connected
2)去掉没有的信息从库信息
redis-cli -c -h 10.0.0.51 -p 6380 cluster nodes |grep -v "6381" |awk '{print $1,$2}'
3)在文本里面理清楚关系进行主从复制
redis-cli -c -h 10.0.0.51 -p 6381 cluster replicate 14bfc83d04275a316101e78a23ac17ca287c2855
redis-cli -c -h 10.0.0.61 -p 6381 cluster replicate 73e2a32100ac736d5fcdcb524e11a1333e638360
redis-cli -c -h 10.0.0.71 -p 6381 cluster replicate bb8b592e098fda892fd85cb43fecebd4ea634185

11.如果集群当中有一个master节点down了,当你在启动这个节点时会发现它已经变为slave节点了,此时需要执行一下命令将其变回master节点,注意:需要在当前从节点执行,在需要变回主节点的从节点执行

CLUSTER FAILOVER

12.redis-cluster总结

1.槽位分配slot
2.16384个槽位
3.每一个槽位都得分配到位,有一个槽位没有分配,整个集群不可用
4.序号顺序不一定要连续,最重要的是每个节点的槽位数量要大致相同,允许2%的误差
5.集群通讯端口为了配置文件里的port加10000,比如6380,通讯端口就是16380
6.故障转移切换全自动,不需要人工干预
7.代码链接redis集群需要插件驱动支持
8.集群内消息传递是同步的
9.集群内的所有已经发现的节点配置文件是自动更新的
10.hash分配算法是足够随机和足够平均足够稳定

 

posted @ 2020-12-18 18:51  鄧萌  阅读(129)  评论(0)    收藏  举报