前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis cluster

Redis cluster

原创
作者头像
DB之路
修改2021-03-12 10:25:54
7170
修改2021-03-12 10:25:54
举报
文章被收录于专栏:数据库PG数据库PG

1.1 Redis集群

Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。

Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下,这些命令将降低 Redis 集群的性能, 并导致不可预测的行为。

Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。将数据自动切分(split)到多个节点的能力。

当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。

1.2 Redis 集群数据共享

Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。

节点 A 负责处理 0 号至 5500 号哈希槽。

节点 B 负责处理 5501 号至 11000 号哈希槽。

节点 C 负责处理 11001 号至 16384 号哈希槽。

槽的计算公式

集群使用公式 CRC16(key) & 16383 计算键 key属于哪个槽。

1.3 集群运行机制

所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.

节点的fail是通过集群中超过半数的master节点检测失效时才失效。

客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->key

为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下, 仍然可以正常运作, Redis 集群对节点使用了主从复制功能: 集群中的每个节点都有 1 个至 N 个复制品(replica), 其中一个复制品为主节点(master), 而其余的 N-1 个复制品为从节点(slave)。

在之前列举的节点 A 、B 、C 的例子中, 如果节点 B 下线了, 那么集群将无法正常运行, 因为集群找不到节点来处理 5501 号至 11000 号的哈希

槽。

假如在创建集群的时候(或者至少在节点 B 下线之前), 我们为主节点 B添加了从节点 B1 , 那么当主节点 B 下线的时候, 集群就会将 B1 设置为新的主节点, 并让它代替下线的主节点 B , 继续处理 5501 号至 11000 号的哈希槽, 这样集群就不会因为主节点 B 的下线而无法正常运作了。

不过如果节点 B 和 B1 都下线的话, Redis 集群还是会停止运作。

集群的复制特性重用了 SLAVEOF 命令的代码,所以集群节点的复制行为和SLAVEOF 命令的复制行为完全相同。

1.4 集群的故障转移

1. 在集群里面,节点会对其他节点进行下线检测。

2. 当一个主节点下线时,集群里面的其他主节点负责对下线主节点进行故障移。

3. 换句话说,集群的节点集成了下线检测和故障转移等类似 Sentinel 的功能。

4. 因为 Sentinel 是一个独立运行的监控程序,而集群的下线检测和故障转移等功能是集成在节点里面的,它们的运行模式非常地不同,所以尽管这两者的功能很相似,但集群的实现没有重用 Sentinel 的代码。

在集群里面执行命令的两种情况

命令发送到了正确的节点:

命令要处理的键所在的槽正好是由接收命令的节点负责,那么该节点执行命令,就像单机 Redis 服务器一样。

槽位说明:

7000: 槽 0~5000

7001:槽 5001~10000

7002:槽 10001~16383

键 date 位于 2022 槽,该槽由节点 7000 负责,命令会直接执行。

命令发送到了错误的节点

接收到命令的节点并非处理键所在槽的节点,那么节点将向客户端返回一个转向(redirection)错误,告知客户端应该到哪个节点去执行这个命令,客户端会根据错误提示的信息,重新向正确的节点发送命令。

键 date 位于 2022 槽,该槽由节点 7000 负责,但错误发送到了7001节点,7001向客户返回转向错误。

客户端根据转向错误的指引,转向到节点7000,并重新发送命令

1.5 关于转向错误

在集群中的节点会互相告知对方,自己负责处理哪些槽。

集群中的每个节点都会记录 16384 个槽分别由哪个节点负责,从而形成一个“槽表”(slot table)。

节点在接收到命令请求时,会通过槽表检查键所在的槽是否由本节点处理:

✍ 如果是的话,那么节点直接执行命令;

✍ 如果不是的话,那么节点就从槽表里面提取出正确节点的地址信息,然后返回转向错误。

1.6 配置集群

前期准备

# EPEL源安装ruby支持

yum install ruby rubygems -y

使用国内源

gem source -a http://mirrors.aliyun.com/rubygems/ -remove https://rubygems.org/

# gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/

# 安装redis支持

gem install redis -v 3.3.3

gem sources -l

配置文件

Redis 集群由多个运行在集群模式(cluster mode)下的 Redis 实例组成, 实例的集群模式需要通过配置来开启, 开启集群模式的实例将可以使用集群特有的功能和命令。

以下是一个包含了最少选项的集群配置文件示例:

port 7000

cluster-enabled yes

cluster-config-file nodes.conf

cluster-node-timeout 5000

appendonly yes

创建程序目录

cd /application/redis

mkdir 7000 7001 7002 7003 7004 7005

拷贝应用

for i in 0 1 2 3 4 5

do

cp /usr/local/redis/src/redis-server ./700$i

done

创建配置文件

for i in 7000 7001 7002 7003 7004 7005

do

echo "port $i

cluster-enabled yes

cluster-config-file nodes.conf

cluster-node-timeout 5000

appendonly yes" > $i/redis.conf

done

启动redis集群

for i in 7000 7001 7002 7003 7004 7005

do

cd $i

./redis-server ./redis.conf &

cd ../

done

创建集群

cd /usr/local/redis/src/

./redis-trib.rb --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

给定 redis-trib.rb 程序的命令是 create , 这表示我们希望创建一个新的集群。

选项 --replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。

1.7 集群管理

写数据,查看集群状态

redis-cli -c -p 7000

set foo bar

get foo

重新分片实践

cd /usr/local/redis/src/

./redis-trib.rb reshard 127.0.0.1:7000

集群状态

redis-cli -p 7000 cluster nodes | grep master

故障转移

redis-cli -p 7002 debug segfault

查看状态

redis-cli -p 7000 cluster nodes | grep master

增加新的节点

./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

删除一个节点

redis-trib del-node ip:port '<node-id>'

删除master节点之前首先要使用reshard移除master的全部slot,然后再删除当前节点

添加一个从节点

./redis-trib.rb add-node --slave --master-id $[nodeid] 127.0.0.1:7008 127.0.0.1:7000

1.8 状态说明

集群最近一次向节点发送 PING 命令之后, 过去了多长时间还没接到回复。

节点最近一次返回 PONG 回复的时间。

节点的配置节点(configuration epoch):详细信息请参考Redis 集群规范 。

本节点的网络连接情况:例如 connected 。

节点目前包含的槽:例如 127.0.0.1:7001 目前包含号码为 5960 至 10921 的哈希槽。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档