Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > Redis高可用

Redis高可用的三种实现方式

作者:格林希尔

在实际生产环境中为保证Redis的服务连续性和可靠性,需要设计一个高可用架构,本文就来介绍一下Redis高可用的三种实现方式,主要包括主从复制模式,Redis Sentinel模式和Redis Cluster模式,感兴趣的可以了解一下

一、高可用概述

1.1 高可用概述

在实际生产环境中为保证Redis的服务连续性和可靠性,需要设计一个高可用架构。即当某一台Redis服务器出现故障时其他Redis服务器可以顶上继续提供服务从而保证整个系统的连续性和稳定性。

1.2 Redis高可用方案

主从复制模式

主从复制是最常用的Redis高可用方案之一。主从复制的实现机制是将主节点上的数据复制到从节点,并在复制过程中保持主节点和从节点的实时同步。在主节点出现故障时,可以通过切换从节点为主节点,从而达到高可用的目的。

以下是主从复制模式的实现步骤:

# master.conf
port 6379
bind 127.0.0.1
slaveof 192.168.0.2 6379
# slave.conf
port 6380
bind 127.0.0.1
slaveof 192.168.0.1 6379

Redis Sentinel模式

Redis Sentinel是一种分布式高可用解决方案。它主要通过一组监控进程(Sentinel进程)来监测Redis服务器的状态。

以下是Redis Sentinel模式的实现步骤:

# sentinel.conf
port 26379
sentinel monitor mymaster 192.168.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000 
sentinel parallel-syncs mymaster 1 
sentinel failover-timeout mymaster 180000 

Redis Cluster模式

Redis Cluster是一种分布式高可用架构,它可以分布式存储和处理多个Redis节点。Redis Cluster可以自动对数据进行分片,提高集群的可靠性和性能

以下是Redis Cluster模式的实现步骤:

# redis-a.conf
port 7000
cluster-enabled yes
cluster-config-file node-a.conf
cluster-node-timeout 5000

# redis-b.conf
port 7001
cluster-enabled yes
cluster-config-file node-b.conf
cluster-node-timeout 5000

...

# node-a.conf, node-b.conf, ...
port 7000
port 7001
...

cluster create ip:port ip:port ip:port ...

1.3 常见高可用方案比较

在实际生产环境中,不同的Redis高可用方案都有各自的优缺点。以下是常见Redis高可用方案的比较:

方案名称优点缺点
主从复制模式实现简单,容易部署对于写请求,需要通过复制同步到从节点,可能存在延迟。单一节点出现故障时,数据不能够读写
Redis Sentinel实现较为简单,可以自动故障迁移,可以监测到节点的状态变化Sentinel进程本身也可能存在故障,会导致高可用性降低。只适合小规模的分布式架构
Redis Cluster容错性和可靠性较好,可以自动对数据进行分片,在性能和可靠性之间取得平衡实现对比较复杂,可能需要对Redis的命令进行重新设计。Redis Cluster在部分场景下的扩展性较差,可能会存在节点瓶颈问题

二、高可用实践-集群

2.1 集群概述

Redis集群是一种分布式高可用的架构,可以分布式存储和处理多个Redis节点,提高Redis系统的可靠性和性能。在Redis集群中每个Redis节点都可以接收客户端的读写请求,数据可以分布到多个节点进行存储和处理。当一个节点出现故障时集群会自动将故障节点的数据提供给其他节点,并将故障节点进行自动修复实现了高可用性和可靠性。

Redis集群采用哈希槽的方式进行数据分片,将整个数据集分成多个哈希槽,每个哈希槽分配给不同的节点进行存储,保证了每个节点上的数据量不会过大。同时在Redis集群中每个节点都可以完成其他节点的工作,随时可以代替其他节点进行工作大大提高了集群的可靠性。

2.2 集群配置

2.2.1 IP地址与端口规划

在Redis集群中每个节点都需要有一个自己的IP地址和端口号,同时还需要有一个可供客户端连接集群的公共IP地址和端口号。在IP地址与端口规划时需要根据需要存储的数据量和性能要求进行合理的划分。

举例来说,假设有6台Redis服务器,6个IP地址分别为:192.168.0.1、192.168.0.2、192.168.0.3、192.168.0.4、192.168.0.5、192.168.0.6。为了方便标识,我们将这6台服务器命名为node1、node2、node3、node4、node5、node6。对于集群的公共IP地址与端口号,我们选择192.168.0.100:7000,具体规划如下:

节点名称IP地址端口号
node1192.168.0.17001
node2192.168.0.27002
node3192.168.0.37003
node4192.168.0.47004
node5192.168.0.57005
node6192.168.0.67006

2.2.2 配置文件修改

在每个节点上需要修改Redis的配置文件redis.conf以便让Redis节点能够加入到集群中。

首先将cluster-enabled参数设置为yes,表示启用集群模式
然后需要指定节点对应的端口号和节点的名称
修改前几行配置如下:

# 修改前的配置
port 6379
cluster-enabled no

# 修改后的配置
port 7001
cluster-enabled yes
cluster-node-timeout 15000
cluster-node-timeout 15000
cluster-config-file nodes.conf
cluster-slave-validity-factor 0

还需要在每个节点的配置文件中添加集群模式相关的配置
具体可以参考以下示例代码:

# 集群监听的端口号
port 7001 
# 启用集群模式
cluster-enabled yes 
# 集群节点超时时间
cluster-node-timeout 15000
# 集群配置文件名称
cluster-config-file nodes.conf
# 成为主节点的条件,缺少这一项则无法选举
cluster-replica-validity-factor 0
# 节点模式,可选master或slave
cluster-announce-ip 192.168.0.1
cluster-announce-port 7001
cluster-announce-bus-port 17002

注意:在修改完配置文件后需要重启Redis服务才会让配置文件生效。

2.2.3 集群启动与测试

在所有节点的配置文件修改完毕后需要启动Redis服务并使用集群命令创建Redis集群
在终端中切换到Redis安装目录的src目录下,使用redis-trib.rb脚本创建集群。该脚本位于Redis安装目录的/src目录下,启动参数-p表示公共端口号。

./redis-trib.rb create --replicas 1 192.168.0.1:7001 192.168.0.2:7002 192.168.0.3:7003 192.168.0.4:7004 192.168.0.5:7005 192.168.0.6:7006

在上述命令执行成功后Redis集群就启动成功了
可以使用命令redis-cli -c -p公共端口号连接到Redis集群进行测试

2.3 集群扩展与缩容

当需要对Redis集群进行扩展或缩容时需要进行以下操作:

在Redis集群中数据迁移和重平衡操作是由集群自动完成的无需手工设置。当集群发现数据量不均衡时会自动对数据进行重新分配,并将多余的数据迁移至其他节点中以保证集群的负载均衡。具体操作可以参考Redis官网的相关文档进行操作。

三、高可用实践-主从复制

3.1 原理与应用场景

Redis主从复制是一种基于Redis数据复制的高可用解决方案。在主从复制中可以将一个节点设置为主节点其他节点设置为从节点,主节点负责写入数据并将数据同步到从节点,从而实现数据在多个节点之间进行同步和复制。这种架构可以提高Redis系统的可靠性和容错能力,使得Redis能够适应更为复杂的应用场景和高并发的请求。

应用场景:适用于读写分离、较高QPS、容灾备份等应用场景。

3.2 主从复制配置

3.2.1 配置文件修改

首先需要在配置文件中进行主从复制配置让Redis节点能够加入到主从复制体系中

在Redis主节点的配置文件redis.conf中需要将以下三个参数设置为指定的数值:

# 打开主节点功能
slave-serve-stale-data no 
# 配置好从节点地址和端口
slaveof 需要复制的主节点IP 需要复制的主节点的端口号 
# 只给从节点写入
master-write-enabled yes

在从节点的配置文件redis.conf中需要将以下三个参数设置为指定的数值:

# 打开从节点功能,配置好从节点的地址和端口
slaveof 需要复制的主节点IP 需要复制的主节点端口号 
# 如果主节点不可用,是否继续提供服务 
slave-serve-stale-data yes 

3.2.2 主从配置启动与测试

在Redis主节点的配置文件中完成修改后需要重启Redis服务之后再启动Redis从节点服务

在启动从节点服务之后使用Redis命令行客户端redis-cli来进行连接测试
方法如下:

实践代码如下:

在主节点的redis.conf文件中配置:

# 打开主节点功能
slave-serve-stale-data no 
# 配置好从节点地址和端口
slaveof 192.168.0.1 7000 
# 只给从节点写入
master-write-enabled yes

在从节点的redis.conf文件中配置:

# 打开从节点功能,配置好从节点的地址和端口
slaveof 192.168.0.1 7000 
# 如果主节点不可用,是否继续提供服务 
slave-serve-stale-data yes 

接下来过如下命令启动Redis服务并测试主从复制是否成功:

如果返回值是bar则说明主从复制已经成功配置

3.3 主从架构搭建最佳实践

为了确保Redis主从架构的高可用性和稳定性,建议需要遵循以下最佳实践:

四、高可用实践-哨兵

4.1 哨兵原理

哨兵是一个专门用于监控和管理Redis集群的组件,主要功能是在集群中检查Redis主节点和从节点是否正常运行,以及在主节点发生故障时自动将从节点升级为新的主节点从而实现Redis高可用性的保障。

在Redis集群中可以通过运行多个Redis实例来实现数据在多个节点之间的复制和负载均衡。但如果Redis主节点发生故障那么整个集群将失去在该节点上进行的写操作从而导致数据的不一致和服务的中断。

为了解决这个问题可以使用Redis哨兵进行集群管理和监控。当主节点发生故障时哨兵可以自动检测到该节点的故障并通过协商机制将新的主节点选出从而保障Redis集群的高可用性和稳定性。

4.2 哨兵配置

Redis哨兵的配置一般包括两个方面:即配置文件修改和哨兵启动与测试

4.2.1 配置文件修改

在Redis哨兵的配置文件redis-sentinel.conf中修改以下参数,以便进行哨兵的配置和管理:

例如,我们需要配置一个监听端口号为26379的哨兵节点监控主节点IP为192.168.0.1,端口号为7000的节点。我们可以在redis-sentinel.conf中加入如下配置:

port 26379
sentinel monitor mymaster 192.168.0.1 7000 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000

注:sentinel parallel-syncs这个参数是在哨兵执行failover时需要同步的从节点数量,默认值为1

4.2.2 哨兵启动与测试

当哨兵节点的配置文件修改完成后可以通过以下命令启动Redis哨兵:

redis-sentinel /path/to/redis-sentinel.conf

启动后使用如下命令检查当前哨兵节点的状态信息:

redis-cli -p 26379 SENTINEL slaves mymaster

该命令可以返回当前Redis主节点和从节点的信息,以及哨兵节点名称、状态、IP地址和端口号等信息。

五、Redis高可用常见问题与解决方案

5.1 脑裂问题

5.1.1 原理分析

脑裂问题指的是 Redis 集群中由于网络故障等原因,某个节点与其他节点失去了联系导致多个互相隔离的子集群产生。如果每个子集群都选出一个主节点进行写操作就会导致数据不一致性和服务中断。

5.1.2 解决方案

要解决脑裂问题,可以采用以下措施来保障 Redis 集群的高可用性:

下面是示例代码使用Sentinel来监控Redis集群,并在出现网络故障时正确处理脑裂问题

// Sentinel配置信息,用于监控Redis集群
Set<String> sentinels = new HashSet<>();
sentinels.add("127.0.0.1:26379");
sentinels.add("127.0.0.1:26380");

// Sentinel Pool 配置信息
JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster", sentinels);

// 获取RedisSentinel的Jedis连接实例
try (Jedis jedis = sentinelPool.getResource()) {
    // 对 Redis 主节点进行写入操作
    jedis.set("key", "value");
} catch (JedisException e) {
    // 进行异常处理
    e.printStackTrace();
} finally {
    // 归还JedisSentinelPool资源
    sentinelPool.close();
}

在代码中使用Sentinel监控Redis集群,通过JedisSentinelPool提供的getResource()方法来获得RedisSentinel的 Jedis连接实例。这种方式可以确保数据的一致性和高可用性并在出现网络故障时进行正确处理

5.2 数据一致性问题

5.2.1 原理分析

Redis集群中的数据复制是通过主节点将数据同步到从节点来完成的。当主节点发生故障时从节点需要接替主节点的职责,此时需要通过数据同步来保证数据的一致性。但由于Redis异步写入机制可能会存在主从节点数据不一致的情况。

5.2.2 解决方案

为了解决数据一致性问题,可以采用以下方案:

5.3 故障恢复问题

5.3.1 原理分析

在Redis集群中当主节点故障时需要通过Redis哨兵选出新的主节点,并让从节点升级为新的主节点。此过程称为故障恢复。

故障恢复需要保证数据的一致性和不可丢失性。因此在故障恢复期间需要遵循以下原则:

5.3.2 解决方案

为了解决故障恢复问题,可以采用以下方案:

到此这篇关于Redis高可用的三种实现方式的文章就介绍到这了,更多相关Redis高可用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文