【缓存与加速技术实践】Redis集群
文章目录
- Redis集群
- Redis 集群的作用
- 高可用性
- 数据分区
- Redis 集群的数据分片
- Redis 集群的主从复制模型
- 自动故障转移机制
- 示例:3 个节点的集群
- 搭建Redis集群模式
- 创建目录结构
- 复制配置文件和可执行文件
- 修改配置文件
- 启动Redis节点
- 启动集群
- 测试集群
- Cluster 集群增加节点动态扩容
Redis集群
Redis 集群(Redis Cluster)是一种分布式存储方案,旨在提供高可用性和数据分区能力。
通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。
Redis 集群的作用
高可用性
Redis 集群通过主从复制和自动故障转移机制来确保高可用性。每个主节点都有一个或多个从节点,这些从节点会复制主节点的数据。当主节点出现故障时,集群中的其他节点会检测到这一点,并自动将一个从节点提升为主节点,以继续提供服务。这类似于 Redis 哨兵(Sentinel)的功能,但集群模式更为集成和高效。
数据分区
数据分区是 Redis 集群的核心功能之一。通过将数据分散到多个节点上,集群突破了单个 Redis 实例的内存限制,从而可以存储更多的数据。此外,每个主节点都可以处理读写请求,这大大提高了集群的吞吐量和响应速度。
Redis 集群的数据分片
Redis 集群引入了哈希槽(Hash Slot)的概念来实现数据分片。集群总共有 16384 个哈希槽,每个节点负责一部分哈希槽。当一个键(Key)需要被存储或检索时,Redis 会计算该键的哈希值,然后对 16384 取模,以确定该键应该存储在哪个哈希槽中。然后,根据哈希槽的分配情况,Redis 可以找到对应的节点,并在该节点上进行存取操作。
Redis 集群的主从复制模型
在 Redis 集群中,每个节点都可以是主节点或从节点。主节点负责处理读写请求,而从节点则复制主节点的数据。这种主从复制模型不仅提高了数据的可用性,还允许在主节点出现故障时进行自动故障转移。
自动故障转移机制
当主节点出现故障时,集群中的其他节点会检测到这一点,并触发自动故障转移过程。
- 故障检测:集群中的节点通过定期发送心跳包来检测其他节点的状态。如果某个主节点长时间没有响应心跳包,那么其他节点会认为该主节点已经出现故障。
- 从节点选举:在检测到主节点故障后,集群会尝试从该主节点的从节点中选举一个新的主节点。选举过程通常基于从节点的复制进度、网络延迟等因素。
- 配置更新:一旦选举出新的主节点,集群会更新其配置信息,并将新的主节点信息广播给集群中的其他节点。
- 数据同步:新的主节点会开始接收和处理来自客户端的写请求,并与其他从节点进行数据同步,以确保数据的一致性。
示例:3 个节点的集群
假设我们有一个由 3 个节点(A、B、C)组成的 Redis 集群,并且每个节点都有一个从节点(A1、B1、C1)。
- 节点 A 包含 0 到 5460 号哈希槽。
- 节点 B 包含 5461 到 10922 号哈希槽。
- 节点 C 包含 10923 到 16383 号哈希槽。
如果节点 B 出现故障,那么集群中的其他节点会检测到这一点,并触发自动故障转移过程。在这个过程中,节点 B1 会被选举为新的主节点,并接管节点 B 的哈希槽和从节点。这样,集群就可以继续提供服务,而不会因为节点 B 的故障而中断。
搭建Redis集群模式
Redis集群通常需要6个节点,包括3个主节点和3个从节点。为了简化操作,这里我们在同一台服务器上通过不同的端口号来模拟这些节点。
创建目录结构
cd /usr/local/redis/
mkdir -p redis-cluster/redis600{1..6}
上述命令将在/usr/local/redis/
目录下创建redis-cluster
文件夹,并在其内创建6个子文件夹,分别用于存放6个Redis节点的配置文件和可执行文件。
复制配置文件和可执行文件
for i in {1..6}
do
cp /opt/redis-7.0.9/redis.conf /usr/local/redis/redis-cluster/redis600$i
cp /opt/redis-7.0.9/src/redis-cli /opt/redis-7.0.9/src/redis-server /usr/local/redis/redis-cluster/redis600$i
done
修改配置文件
对于每个节点的配置文件redis.conf
,进行以下修改(以redis6001
为例)
cd /usr/local/redis/redis-cluster/redis6001
vim redis.conf
修改以下内容:
# 注释掉bind项,默认监听所有网卡
# bind 127.0.0.1
# 关闭保护模式
protected-mode no
# 修改redis监听端口
port 6001
# 设置为守护进程,后台启动
daemonize yes
# 指定 PID 文件
pidfile /usr/local/redis/log/redis_6001.pid
# 指定日志文件
logfile "/usr/local/redis/log/redis_6001.log"
# 指定持久化文件所在目录
dir ./
# 开启AOF
appendonly yes
# 开启群集功能
cluster-enabled yes
# 群集名称文件设置
cluster-config-file nodes-6001.conf
# 群集超时时间设置
cluster-node-timeout 15000
注意:每个节点都要修改port
、pidfile
、logfile
、cluster-config-file
等配置项,以确保它们各自独立。
启动Redis节点
for d in {1..6}
do
cd /usr/local/redis/redis-cluster/redis600$d
./redis-server redis.conf
done
上述命令将启动6个Redis节点。
可以使用ps -ef | grep redis
来检查Redis进程是否已成功启动。
启动集群
redis-cli --cluster create 127.0.0.1:6001 127.0.0.1:6002 127.0.0.1:6003 127.0.0.1:6004 127.0.0.1:6005 127.0.0.1:6006 --cluster-replicas 1
上述命令将6个Redis实例分为3组,每组包含一个主节点和一个从节点。
--replicas 1
表示每个主节点有一个从节点。
在交互过程中,需要输入yes
来确认创建集群。
测试集群
redis-cli -p 6001 -c # 使用-c参数,使节点间可互相跳转
127.0.0.1:6001> cluster slots # 查看节点的哈希槽编号范围
127.0.0.1:6001> set name zhangsan # 设置键值对,观察是否自动跳转至正确的主节点
127.0.0.1:6001> cluster keyslot name # 查看键的槽编号
redis-cli -p 6004 -c # 连接从节点
127.0.0.1:6004> keys * # 验证从节点是否有主节点的数据副本
redis-cli -p 6001 -c cluster nodes # 查看集群节点信息
Cluster 集群增加节点动态扩容
redis 5的集群支持在有负载的情况下增加节点动态扩容。
环境:
已有集群为6个节点127.0.0.1:6001 - 127.0.0.1:6006,3组主从节点。现要增加第4组主从节点127.0.0.1:6007,127.0.0.1:6008
1. 创建一个新的主节点127.0.0.1:6007。命令里需要指定一个已有节点以便于获取集群信息,本例是指定的127.0.0.1:6001
redis-cli -p 6001 --cluster add-node 127.0.0.1:6007 127.0.0.1:6001
或
redis-cli -p 6001
cluster meet 127.0.0.1 6007
cluster meet 127.0.0.1 6008
2. 将127.0.0.1:6008创建为127.0.0.1:6007的从节点。命令里需要指定一个已有节点以便于获取集群信息和主节点的node ID
redis-cli -p 6001 --cluster add-node 127.0.0.1:6008 127.0.0.1:6001 --cluster-slave --cluster-master-id e44678abed249e22482559136bf45280fd3ac281
或
redis-cli -p 6008
cluster replicate e44678abed249e22482559136bf45280fd3ac281
3. 新加入的主节点是没有槽数的,只有初始化集群的时候,才会根据主的数据分配好,如新增的主节点,需要手动分配
redis-cli -p 6007 --cluster reshard 127.0.0.1:6001 --cluster-from e1a033e07f0064e6400825b4ddbcd6680c032d10 --cluster-to e44678abed249e22482559136bf45280fd3ac281 --cluster-slots 1000 --cluster-yes
或
redis-cli -p 6007 --cluster reshard 127.0.0.1:6001
How many slots do you want to move (from 1 to 16384)? 1000 #指定转移槽的数量
What is the receiving node ID? e44678abed249e22482559136bf45280fd3ac281 #指定接收槽数量的主节点node ID
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: e1a033e07f0064e6400825b4ddbcd6680c032d10 #指定分配的主节点node ID
Source node #2: done #输入完毕,开始转移
4. 查看集群状态
redis-cli -p 6001 cluster nodes