-
Redis的分布式
RedisCluster是Redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的需求,当遇到单机内存、并发等瓶颈时,可使用此方案来解决这些问题 -
分布式数据库概念
- 分布式数据库把整个数据按分区规则映射到多个节点,即把数据划分到多个节点上,每个节点负责整体数据的一个子集。
- 比如我们库有900条用户数据,有3个redis节点,将900条分成3份,分别存入到3个redis节点
-
分区规则
- 常见的分区规则哈希分区和顺序分区,redis集群使用了哈希分区,顺序分区暂用不到
- RedisCluster采用了哈希分区的“虚拟槽分区”方式(哈希分区分节点取余、一致性哈希分区和虚拟槽分区)
- 虚拟槽分区:RedisCluster采用此分区,所有的键根据哈希函数(CRC16[key]&16383)映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据。Hash() = CRC16[KEY]&16383
-
RedisCluster的缺陷
- 键的批量操作支持有限,比如mset,mget,如果多个键映射在不同的槽,就不支持了 mset name james age 19
- 键事务支持有限,当多个键分布在不同节点时无法使用事务,同一节点是支持事务
- 键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点
- 不支持多数据库,只有0,select 0
- 复制结构只支持单层结构,不支持树型结构
-
集群环境搭建
- 6389为6379的从节点,6390为6380的从节点,6391为6381的从节点
- 分别修改6389、6379、6390、6380、6391、6381配置文件,以6379为例,其他节点和这个配置一致,改端口即可:
port 6379 //节点端口 cluster-enabled yes //开启集群模式 cluster-node-timeout 15000 //节点超时时间 cluster-config-file /user/local/bin/clustercon/data/node-6379.conf //集群内部配置文件
- 分别启动6389、6379、6390、6380、6391、6381节点
./redis-server clusterconf/redis6379.conf & ./redis-server clusterconf/redis6380.conf & ./redis-server clusterconf/redis6381.conf & ./redis-server clusterconf/redis6389.conf & ./redis-server clusterconf/redis6390.conf & ./redis-server clusterconf/redis6391.conf &
- 使用ruby来自动分配槽与主从分配
a, 链接:https://pan.baidu.com/s/1XONZKuhqOin7d9QWGRnNWA 密码:u3b7。从这个链接下载ruby-2.3.1.tar.gz 和 redis-3.3.0.gem b, tar -zxvf ruby-2.3.1.tar.gz c, cd ruby-2.3.1 d, ./configure -prefix=/usr/local/ruby e, make && make install //过程会有点慢,大概5-10分钟 f, 然后gem install -l redis-3.3.0.gem //若没有gem 需要安装yum install gem -y g, 准备好6个节点配置文件redis6379.conf ... 加上 bind 192.168.19.22 h, 注意不要设置requirepass ,不然./redis-trib访问不了,将/usr/local/bin/clusterconf/data的config-file删除 i, 依次启动6个节点:./redis-server clusterconf/redis6379.conf j, 如果之前redis有数据存在,flushall 清空(不需要cluster meet..) k,./redis-trib.rb create --replicas 1 192.168.19.22:6379 192.168.19.22:6380 192.168.19.22:6381 192.168.19.22:6389 192.168.19.22:6390 192.168.19.22:6391
- 集群测试,当停掉6379主节点后,6389变成主节点
- redis集群健康检测,执行:./redis-trib.rb check 192.168.19.22:6379 。如果出现6379的xx槽位被打开了,执行命令依次修复:cluster setslot ** stable;
- 一主多从改如何配置:./redis-trib.rb create --replicas 2 ip:port (3 * 3 * 3)。2代表有两个从节点,第一排三个是主节点,第二,三排三个依次对应前3个的从节点
-
集群节点之间的通信
- 节点之间采用Gossip协议进行通信,Gossip协议就是指节点彼此之间不断通信交换信息
- 当主从角色变化或新增节点,彼此通过Ping/pong进行通信知道全部节点的最新状态并达到集群同步
- Gossip协议的主要职责就是信息交换,信息交换的载体就是节点之间彼此发送的Gossip消息,常用的Gossip消息有Ping消息、pong消息
、meet消息、fail消息
a, meet消息:用于通知新节点加入,消息发送者通知接收者加入到当前集群,meet消息通信完后,接收节点会加入到集群中,并进行
周期性ping,pong交换
b, ping消息:集群内交换最频繁的消息,集群内每个节点每秒向其他节点发Ping消息,用于检测节点是否在线和状态信息,ping消息
发送封装自身节点和其他节点的状态数据
c, pong消息:当接收到ping,meet消息时,作为响应消息返回给发送方,用来确认正常通信,pong消息也封闭了自身状态数据;
d, fail消息:当节点判定集群内的另一节点下线时,会向集群内广播一个fail消息 - 以上的所有消息格式为:消息头、消息体,消息头包含发送节点自身状态数据(比如节点ID、槽映射、节点角色、是否下线等),接收
节点根据消息头可以获取到发送节点的相关数据。 - Gossip协议信息的交换机制具有天然的分布式特性,但ping pong 发送的频率很高
a, 节点定时任务
b, 没秒执行10次,间隔1秒
c, 选择发送节点
(1)每秒选取5个节点,找出最久没通信的那个节点
(2)或找出最后pong回复时间大于cluster_node_time/2的节点
d, 组装消息数据格式
(1)消息头(节点自身信息)
(2)消息体(其他节点信息)
e, 发送ping 消息
-
集群扩容-新增节点操作
- 同目录下新增redis6382.conf、redis6392.conf,并启动两个新redis节点
./redis-server clusterconf/redis6382.conf & ./redis-server clusterconf/redis6392.conf &
- 新增主节点
./redis-trib.rb add-node 192.168.19.22:6382 192.168.19.22:6379 //6379原主节点 6382新主节点
- 添加从节点
a, --slave表示添加的是从节点./redis-trib.rb add-node --slave --master-id 023423409459f2 192.168.19.22:6392 192.168.19.22:6379
b, --master-id 023423409459f2 ,主节点的node id,在这里是前面新添加的6378的nodeid
c, 192.168.19.22:6392 新从节点
d, 192.168.19.22:6379 集群原存在的旧节点 - redis-trib.rb reshard 192.168.19.22:6382 //重新分配solt
- 同目录下新增redis6382.conf、redis6392.conf,并启动两个新redis节点
-
集群减缩-节点下线操作
- 从节点6392删除步骤
./redis-trib.rb del-node 192.168.19.22:6392 234234jljl(节点id)
- 主节点6382删除步骤
a, 槽回收,数据转移:./redis-tribreshard 192.168.19.22:6382
(1) 输入被删除节点之前分配的槽数
(2) 将被删除节点的数据转存到其他主节点
(3) 输入被删除节点ID号
(4) 确定删除,完成
b, 执行删除:./redis-trib.rb del-node 192.168.19.22:6382 24234234dsfa(节点id)
- 从节点6392删除步骤
-
redisCluster集群-路由重定向
- 客户端发送命令到任意节点
- 计算槽找到对应的节点
- 是否指向自身
a, yes 执行命令
b, no 回复Moved给客户端 - 重定向发送键命令到目标节点
-
redisCluster集群-故障转移主观下线
- 节点a定时任务执行发送ping消息给b
- 是否成功
a, no 通信异常断开连接
b, yes 回复ping消息并更新节点b最后通信时间 - 与节点b最后通信时间超时,标记为pfail状态
-
redisCluster集群-故障转移客观下线
- 节点真正的下线,集群内多个节点都认为该节点不可用,达成共识,将它下线,如果下线的节点为主节点,还要对它进行故障转移
a, 接收Ping消息
b, 消息解析,包含其他pfail节点,主节点发消息
c, 维护故障链表
d, 尝试客观下线
e, 计算有效的下线报告数量,是否大于槽点总数一半
(1) no 退出
(2) yes 更新为客观下线,并向集群广播下线节点的fail消息
- 节点真正的下线,集群内多个节点都认为该节点不可用,达成共识,将它下线,如果下线的节点为主节点,还要对它进行故障转移
-
redisCluster集群-故障恢复
故障主节点下线后,如果下线节点的是主节点,则需要在它的从节点中选一个替换它,保证集群的高可用- 资格检查
- 准备选举时间
- 发起选举
- 选举投票
- 替换主节点
网友评论