Redis Cluster

Redis Cluster

​ Redis Cluster 集群分区方案采用去中心化的方式,包括:sharding(分区)、replication(复制)、failover(故障转移)

Redis Cluster部署架构

image-20210118193740357.png

去中心化

​ Redis Cluster 由多个Redis节点组构成,是一个P2P(point to point)无中心节点的集群架构,依靠Gossip协议传播集群

Gossip

Gossip协议是一个通信协议,一种传播消息的方式。

起源于:病毒传播

Gossip协议基本思想:

一个节点周期性(每秒)随机选择一些节点,并把信息传递给这些节点。

这些收到信息的节点接下来会做同样的事情,即把这些信息传递给其他一些随机选择的节点。

信息会周期性的传递给N个目标节点。这个N被称为fanout(扇出)

gossip协议包含多种消息,包括meet、ping、pong、fail、publish等等

命令 说明
meet sender向receiver发出,请求receiver加入sender的集群
ping 节点检测其他节点是否在线
pong receiver收到meet或ping后的回复信息;在failover后,新的Master也会广播pong
fail 节点A判断节点B下线后,A节点广播B的fail信息,其他收到节点会将B节点标记为下线
publish 节点A收到publish命令,节点A执行该命令,并向集群广播publish命令,收到publish 命令的节点都会执行相同的publish命令

通过gossip协议,cluster可以提供集群间状态同步更新、选举自助failover等重要的集群功能。

slot

redis-cluster把所有的物理节点映射到[0-16383]个slot上,基本上采用平均分配和连续分配的方式。

比如上图中有5个节点,这样在 Redis Cluster 创建时,slot槽可按下表分配

节点名称 slot范围
Redis1 0-3270
Redis2 3271-6542
Redis3 6543-9814
Redis4 9815-13087
Redis5 13088-16383

cluster 负责维护节点和slot槽的对应关系 value------>slot-------->节点

当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把
结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点
数量大致均等的将哈希槽映射到不同的节点。

比如:
set name zhangsan
hash("name")采用crc16算法,得到值:1324203551%16384=15903
根据上表15903在13088-16383之间,所以name被存储在Redis5节点。
slot槽必须在节点上连续分配,如果出现不连续的情况,则RedisCluster不能工作。

Redis Cluster 优势

  • 高性能

    Redis Cluster 的性能与单节点部署是同级别的。

    多主节点、负载均衡、读写分离

  • 高可用

    Redis Cluster 支持标准的 主从复制配置来保障高可用和高可靠。

    failover (故障转移)

    Redis Cluster 也实现了一个类似 Raft 的共识方式,来保障整个集群的可用性。

  • 易扩展

    向 Redis Cluster 中添加新节点,或者移除节点,都是透明的,不需要停机。

    水平、垂直方向都非常容易扩展。

    数据分区,海量数据存储

  • 原生

    部署 Redis Cluster 不需要其他的代理或者工具,而且 Redis Cluster 和单机 Redis 几乎完全兼
    容。

Cluster 安装配置

redis版本说明

redis.5.0.5

服务器说明

IP 端口 预定角色
192.168.100.203 7001 master
192.168.100.203 7002 master
192.168.100.203 7003 master
192.168.100.203 7004 master
192.168.100.203 7011 slave
192.168.100.203 7012 slave
192.168.100.203 7013 slave
192.168.100.203 7014 slave
image-20210118173646022

安装redis

tar zxvf redis-5.0.5.tar.gz

cd redis-5.0.5

make install PREFIX=/file/data/redis

配置 redis cluster

cd /file/data/redis

mkdir cluster

cd /file/data/redis/cluster

mkdir 7001 7002 7003 7004 7011 7012 7013 7014

cp -r /file/data/redis/bin /file/data/redis/cluster/7001
cp -r /file/data/redis/bin /file/data/redis/cluster/7002
cp -r /file/data/redis/bin /file/data/redis/cluster/7003
cp -r /file/data/redis/bin /file/data/redis/cluster/7004
cp -r /file/data/redis/bin /file/data/redis/cluster/7011
cp -r /file/data/redis/bin /file/data/redis/cluster/7012
cp -r /file/data/redis/bin /file/data/redis/cluster/7013
cp -r /file/data/redis/bin /file/data/redis/cluster/7014


cp -r /file/data/redis/redis-5.0.5/redis.conf /file/data/redis/cluster/7001/redis.conf
cp -r /file/data/redis/redis-5.0.5/redis.conf /file/data/redis/cluster/7002/redis.conf
cp -r /file/data/redis/redis-5.0.5/redis.conf /file/data/redis/cluster/7003/redis.conf
cp -r /file/data/redis/redis-5.0.5/redis.conf /file/data/redis/cluster/7004/redis.conf
cp -r /file/data/redis/redis-5.0.5/redis.conf /file/data/redis/cluster/7011/redis.conf
cp -r /file/data/redis/redis-5.0.5/redis.conf /file/data/redis/cluster/7012/redis.conf
cp -r /file/data/redis/redis-5.0.5/redis.conf /file/data/redis/cluster/7013/redis.conf
cp -r /file/data/redis/redis-5.0.5/redis.conf /file/data/redis/cluster/7014/redis.conf
7001 配置
#bind 127.0.0.1
protected-mode no
port 7001
daemonize yes
cluster-enabled yes
7002 配置
#bind 127.0.0.1
protected-mode no
port 7002
daemonize yes
cluster-enabled yes
7003 配置
#bind 127.0.0.1
protected-mode no
port 7003
daemonize yes
cluster-enabled yes
7011 配置
#bind 127.0.0.1
protected-mode no
port 7011
daemonize yes
cluster-enabled yes
7012 配置
#bind 127.0.0.1
protected-mode no
port 7012
daemonize yes
cluster-enabled yes
7013 配置
#bind 127.0.0.1
protected-mode no
port 7013
daemonize yes
cluster-enabled yes

启动

启动 7001、7002、7003、7011、7012、7013

配置启动脚本

#!/bin/bash
cd /file/data/redis/cluster/7001
./bin/redis-server redis-7001.conf

cd /file/data/redis/cluster/7002
./bin/redis-server redis-7002.conf

cd /file/data/redis/cluster/7003
./bin/redis-server redis-7003.conf

cd /file/data/redis/cluster/7011
./bin/redis-server redis-7011.conf

cd /file/data/redis/cluster/7012
./bin/redis-server redis-7012.conf

cd /file/data/redis/cluster/7013
./bin/redis-server redis-7013.conf
image-20210118181549956.png
初始化 redis cluster

三主三从

./bin/redis-cli -p 7001

./bin/redis-cli --cluster create 192.168.100.203:7001 192.168.100.203:7002 192.168.100.203:7003 192.168.100.203:7011 192.168.100.203:7012 192.168.100.203:7013 --cluster-replicas 1
image-20210118181743476.png
验证

客户端连接集群

-c 以集群方式连接

./bin/redis-cli -p 7001 -c
image-20210118182435295.png
image-20210118182818343.png
扩容

扩容节点数据必须为空

7004 配置
#bind 127.0.0.1
protected-mode no
port 7004
daemonize yes
cluster-enabled yes
7014 配置
#bind 127.0.0.1
protected-mode no
port 7014
daemonize yes
cluster-enabled yes

启动 7004、7014

cd /file/data/redis/cluster/7004
./bin/redis-server redis-7004.conf

cd /file/data/redis/cluster/7014
./bin/redis-server redis-7014.conf

将 7004、7014 添加到集群

./bin/redis-cli --cluster add-node 192.168.100.203:7004 192.168.100.203:7001
image-20210118185339319.png
分配slot
./bin/redis-cli --cluster reshard 192.168.100.203:7004
image-20210118191414783.png
image-20210118191553426.png
7004 添加从节点 7014
./bin/redis-cli --cluster add-node 从节点IP:端口 主节点IP:端口 --cluster-slave --cluster-master-id 主节点id
./bin/redis-cli --cluster add-node 192.168.100.203:7014 192.168.100.203:7004 --cluster-slave --cluster-master-id fe69a0e71604ad65b8da24d415c50000c1bffec7
image-20210118191937400.png
image-20210118192025919.png
缩容

只能删除数据为空的节点

./bin/redis-cli --cluster del-node 删除节点IP:端口 节点id
./bin/redis-cli --cluster del-node 192.168.127.128:7008 fe69a0e71604ad65b8da24d415c50000c1bffec7
容灾(failover)
故障转移

集群中的每个节点都会定期地(每秒)向集群中的其他节点发送PIN

如果在一定时间内(cluster-node-timeout),发送ping的节点A没有收到某节点B的pong回应,则A将B
标识为pfail。

A在后续发送ping时,会带上B的pfail信息, 通知给其他节点。

如果B被标记为pfail的个数大于集群主节点个数的一半(N/2 + 1)时,B会被标记为fail,A向整个集群
广播,该节点已经下线

其他节点收到广播,标记B为fail。

从节点选举

采用 raft 协议

每个从节点,都根据自己对master复制数据的offset,来设置一个选举时间,offset越大(复制数
据越多)的从节点,选举时间越靠前,优先进行选举。

slave 通过向其他master发送FAILVOER_AUTH_REQUEST 消息发起竞选,

master 收到后回复FAILOVER_AUTH_ACK 消息告知是否同意。

slave 发送FAILOVER_AUTH_REQUEST 前会将currentEpoch 自增,并将最新的Epoch 带入到

FAILOVER_AUTH_REQUEST 消息中,如果自己未投过票,则回复同意,否则回复拒绝。

所有的Master开始slave选举投票,给要进行选举的slave进行投票,如果大部分master node(N/2 +
1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成master。

RedisCluster失效的判定

1、集群中半数以上的主节点都宕机(无法投票)

2、宕机的主节点的从节点也宕机了(slot槽分配不连续)

变更通知

当slave 收到过半的master 同意时,会成为新的master。此时会以最新的Epoch 通过PONG 消息广播
自己成为master,让Cluster 的其他节点尽快的更新拓扑结构(node.conf)。

主从切换

自动切换

就是上面讲的从节点选举

手动切换

人工故障切换是预期的操作,而非发生了真正的故障,目的是以一种安全的方式(数据无丢失)将当前
master节点和其中一个slave节点(执行cluster-failover的节点)交换角色

1、向从节点发送cluster failover 命令(slaveof no one)
2、从节点告知其主节点要进行手动切换(CLUSTERMSG_TYPE_MFSTART)
3、主节点会阻塞所有客户端命令的执行(10s)
4、从节点从主节点的ping包中获得主节点的复制偏移量
5、从节点复制达到偏移量,发起选举、统计选票、赢得选举、升级为主节点并更新配置
6、切换完成后,原主节点向所有客户端发送moved指令重定向到新的主节点

以上是在主节点在线情况下。

如果主节点下线了,则采用cluster failover force或cluster failover takeover 进行强制切换。

副本漂移

我们知道在一主一从的情况下,如果主从同时挂了,那整个集群就挂了。
为了避免这种情况我们可以做一主多从,但这样成本就增加了。
Redis提供了一种方法叫副本漂移,这种方法既能提高集群的可靠性又不用增加太多的从机。


image-20210118195433521.png

Master1宕机,则Slaver11提升为新的Master1
集群检测到新的Master1是单点的(无从机)
集群从拥有最多的从机的节点组(Master3)中,选择节点名称字母顺序最小的从机(Slaver31)漂移
到单点的主从节点组(Master1)。

具体流程如下(以上图为例):
1、将Slaver31的从机记录从Master3中删除
2、将Slaver31的的主机改为Master1
3、在Master1中添加Slaver31为从节点
4、将Slaver31的复制源改为Master1
5、通过ping包将信息同步到集群的其他节点

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