Redis三种集群模式:主从模式、哨兵模式和Cluster模式
Redis三种集群模式:主从模式、哨兵模式和Cluster模式
1、背景及介绍
Redis 支持三种不同的集群模式:主从模式、哨兵模式和Cluster模式,各具特色,应对不同的应用场景。
初始阶段,Redis 采用主从模式进行集群构建。在此模式中,主节点(master)负责数据写入,而从节点(slave)则用于数据读取和备份。若主节点发生故障,需人工介入,将某个从节点提升为新的主节点。但这种模式在故障恢复上效率较低,无法实现高度自动化。
为了提升系统的高可用性,Redis 推出了哨兵模式。在此模式下,通过一个哨兵集群来监控主从节点的健康状态。一旦主节点故障被侦测到,系统会自动选举出一个从节点,晋升为新的主节点,从而实现故障恢复的自动化,提高系统的稳定性和可靠性。
然而,哨兵模式仍然存在一定的局限性,例如内存容量和写入性能都受限于单个节点。为了克服这些限制,Redis 在 3.x 版本后推出了Cluster模式。这一模式通过数据分片(sharding)和多节点水平扩展,有效提高了内存利用率和写入性能,适用于更大规模和更高要求的数据处理场景。总体来说,Cluster模式为Redis集群的性能和扩展性提供了重要的支撑。
特性/配置 | Redis 主从复制 | Redis 哨兵 | Redis 集群 |
---|---|---|---|
主要目的 | 数据备份与读写分离 | 高可用性和故障自动切换 | 高并发和数据分散处理 |
架构 | 一个主节点和多个从节点 | 监控主从结构并自动切换 | 多个主节点,数据分片 |
数据复制 | 主节点到从节点 | 监控并管理主从复制 | 每个主节点管理自己的数据集 |
故障转移机制 | 手动或哨兵自动切换 | 自动故障转移 | 自动处理节点故障 |
可伸缩性 | 有限,依赖主节点 | 为主从结构增加高可用性 | 高,因为数据分布式处理 |
使用场景 | 数据备份和读扩展 | 关键应用的高可用性 | 大规模应用的高性能需求 |
设置复杂度 | 相对简单 | 中等,需配置哨兵 | 复杂,需规划数据分区 |
2、 Redis 主从复制
2.1、主从复制特点
Redis的主从复制架构通过定义主库(master)和从库(slave)的角色,实现了数据的高效同步和备份,具备以下几个显著特点:
- 主库的读写能力:主库(master)是数据操作的中心。它处理所有的写请求,并且也能处理读请求。任何在主库上执行的数据修改操作,都会实时且自动地同步到所有从库(slave)。
- 单向数据流:数据同步流程是单向的,即数据仅从主库流向从库。这种单向流动保证了数据同步的一致性和可靠性。
- 从库的只读特性:从库通常被配置为只读模式,用于接收并存储从主库传来的数据。这种设计主要用于分担读取负载,从而提升整个系统的读取性能。
- 主从关系的配置:一个主库可以对应多个从库,形成一对多的关系,有利于数据冗余备份和读取负载的分散。反之,一个从库仅对应一个主库,以维护数据同步的一致性。
- 从库的容错能力:若某个从库故障,其对系统其他部分的影响极小。即使在从库宕机的情况下,其他从库仍可提供读服务,主库也能继续正常的读写操作。故障的从库在恢复后,能自动从主库同步缺失数据。
- 主库故障的影响:主库故障可能导致Redis暂停处理新的写请求,但已连接的从库可继续提供读服务。主库恢复后,Redis将重新提供完整的读写服务。
- 应对主库故障的机制:在当前主库故障时,系统不会自动在从库中选举新的主库。这需要借助额外的高可用性解决方案,例如Redis Sentinel或Redis Cluster,来管理主库的选举和故障转移。
Redis的主从复制架构有效地提供了高可用性、数据冗余以及读写分离的功能,确保了在保持高性能的同时,数据安全和一致性得到保障。
2.2、Redis主从复制原理
在本文档中,我们将重点介绍Redis版本2.8及其后续版本的主从复制机制。
无是哪种场景,Redis 的主从复制机制均采用异步复制,也称为乐观复制,因此不能完全保证主从数据的一致性。
不论在什么场景下,Redis的主从复制机制都采用了所谓的“异步复制”或“乐观复制”。这种复制方式意味着不能完全保证主库和从库数据的实时一致性。
Redis的主从复制机制可以根据不同的运行场景和条件采取不同的实现方式。以下是一些主要场景及其对应的复制实现和说明:
- 第一次启动:在从库第一次连接到主库时,将采用
psync
复制方式进行全量复制。这意味着从库会从头开始复制主库中的全部数据。 - 正常运行期间:在正常运行状态下,从库通过读取主库的缓冲区来进行增量复制。这个过程涉及复制主库上发生的新的数据变更。
- 从库第二次启动(主库缓冲区未溢出) :当从库重新启动且主库的缓冲区未溢出时,将通过读取主库的缓冲区进行部分复制。这种方式能够快速同步中断期间发生的数据变更,而不会对主库造成重大影响。
- Redis 2.8及以上版本的从库第二次启动(针对主库) :当从库第二次启动且系统版本为Redis 2.8或以上时,将采用
psync
复制进行全量复制。这种情况通常发生在主库的缓冲区数据无法满足从库需要同步的数据量时。
通过上述不同的复制策略,Redis能够在保证数据备份和减少系统负载的同时,灵活应对各种运行场景。尽管异步复制机制可能导致主从数据存在短暂的不一致,但这种设计在绝大多数应用场景中已被证明是既高效又可靠的。
PS:异步复制是Redis的复制方式,而psync
是实现这种复制方式的具体命令。乐观复制或乐观并发控制则是另一种与Redis的异步复制机制不同的数据库事务处理概念。不少博客或说明介绍异步复制和乐观复制是同一个概念。
2.3 PSYNC 工作原理
PSYNC 命令是Redis中用于从节点与主节点之间数据同步的关键命令。它的工作原理包括以下几个步骤:
2.3.1、启动或重连判断:
-
当从节点(Slave)启动或者与主节点(Master)的连接断开后重连时,从节点需要确定是否曾经同步过。
-
如果从节点没有保存任何主节点的运行 ID(runnid),它将视为第一次连接道主节点。
2.3.2、第一次同步处理:
- 在第一次同步的情况下,从节点会发送
PSYNC -1
命令给主节点,请求进行全量数据同步。 - 全量同步是指主节点将其所有数据完整地复制一份给从节点。
2.3.3、断线重连处理:
- 对于之前已经同步过的从节点,它会发送
PSYNC runid offset
命令,其中runid
是主节点的唯一标识符,offset
是从节点上次同步数据的偏移量。
2.3.4、主节点响应
- 主节点接收到
PSYNC
命令后,会检查runid
是否匹配,以及offset
是否在复制积压缓冲区的范围内。 - 如果匹配且
offset
有效,主节点将回复CONTINUE
,并发送自从节点上次断开连接以来的所有写命令。
2.3.5、全量同步触发条件:
- 如果
runid
不匹配,或offset
超出了积压缓冲区的范围,主节点将通知从节点执行全量同步,回复FULLRESYNC runid offset
。
2.3.6、复制积压缓冲区的作用:
- 主节点会在处理写命令的同时,将这些命令存入复制积压队列,同时记录队列中存放命令的全局
offset
。 - 当从节点断线重连,且条件允许时,它可以通过
offset
从积压队列中进行增量复制,而不是全量复制。
2.3.7、数据一致性保障
PSYNC
机制允许从节点在网络不稳定或其他意外断开连接的情况下,能够以增量方式重新同步数据,保持主从节点数据的一致性。
PS:判断是否进行全量同步,需要考虑两个关键因素:首先,确认这是否是第一次进行数据同步;其次,检查缓存区是否已经达到或超过其容量上限。只有在是第一次同步,或者缓存区已溢出的情况下,才会执行全量同步。
2.4、Redis 主从模式环境搭建
在Redis的主从架构中,主节点的数据更新会自动被复制到从节点,确保数据的一致性。这种设置既是一种数据备份策略——从节点存储了主节点的数据备份,也提高了数据安全性。此外,通过主从架构实现读写分离,主节点负责处理写请求,而读请求可以分散到一个或多个从节点,这样既提高了系统的处理能力,又优化了资源的利用。
2.4.1、redis配置
2.4.1.1、主库配置
# 设置Redis监听的IP地址和端口号,默认监听所有IP地址和6379端口
bind 0.0.0.0
# 启用保护模式,允许远程访问
protected-mode no
# 指定Redis监听的端口号
port 6380
# 增加Redis的最大内存限制,以容纳更多数据
#maxmemory 16GB 增加内存限制,根据您的服务器实际内存调整
maxmemory 30720mb
# 设置在达到最大内存后的处理策略为LRU算法
maxmemory-policy allkeys-lru
# 配置TCP连接的最大等待队列长度 增加此值以处理更多的等待连接
tcp-backlog 2048
# 配置客户端连接超时时间
timeout 0
# 配置TCP keepalive参数 减少此值以更快检测和断开空闲连接
tcp-keepalive 60
# 配置日志级别根据需要调整
loglevel notice
# 配置数据存储目录
dir E:\redis\data
# 根据磁盘性能调整持久化选项
save 900 1
save 300 10
save 60 10000
# 关闭对后台任务的通知
notify-keyspace-events ""
# 配置最大客户端连接数 确保您的操作系统支持这么多文件描述符
maxclients 1000000
# 启用或修改AOF持久性设置
# 根据磁盘性能和数据持久性需求调整
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# 配置Lua脚本执行时间限制
# 调整阈值
lua-time-limit 5000
# 调整慢查询日志配置
slowlog-log-slower-than 10000
slowlog-max-len 128
# 配置事件通知
notify-keyspace-events ""
# 调整数据结构的配置以优化内存使用
hash-max-ziplist-entries 1024
hash-max-ziplist-value 128
set-max-intset-entries 1024
list-max-ziplist-size -2
zset-max-ziplist-entries 128
zset-max-ziplist-value 128
# 配置HyperLogLog数据结构的最大内存使用
hll-sparse-max-bytes 3000
#replicaof 10.41.170.130 6380
# 修改为以守护进程模式后台运行
daemonize yes
# 修改pid文件名,以守护进程运行的时候,会产生pid文件,默认位置为 /run/redis.pid
# 因为这里在同一台机器上运行多个实例,所以需要指定
pidfile E:\redis\redis-cluster\redis_100.pid
# 修改日志文件位置
logfile E:\redis\redis-cluster\redis_100.log
2.4.1.2 从库配置
# 修改为从库监听的端口号
port 6381
# 添加主库信息
replicaof 10.41.170.130 6380
2.4.2、springboot配置
spring:
# redis 配置
redis:
master-slave:
master: 10.41.170.130:6380
slaves:
- 10.41.170.100:6381
- 10.41.170.119:6379
# 连接超时时间
timeout: 10s
# Lettuce 连接池配置
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 5
# 连接池中的最大空闲连接
max-idle: 10
# 连接池的最大数据库连接数
max-active: 20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 1000ms
2.4.3、业务代码修改
添加Properties解析,示例代码如下
@Configuration
# prefix需要与redis的根目录一致
@ConfigurationProperties(prefix = "spring.redis.master-slave")
public class RedisMasterSlaveProperties {
private String master;
private List<String> slaves;
private String password;
// getter和setter方法
...
}
2.4.4、lettuce配置解析
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
@SuppressWarnings(value = {"unchecked", "rawtypes"})
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
...
}
@Bean
public RedisConnectionFactory lettuceConnectionFactory(RedisMasterSlaveProperties redisMasterSlaveProperties) {
// 解析主节点
String[] masterParts = redisMasterSlaveProperties.getMaster().split(":");
RedisStaticMasterReplicaConfiguration masterReplicaConfig = new RedisStaticMasterReplicaConfiguration(
masterParts[0], Integer.parseInt(masterParts[1])
);
// 添加从节点
for (String slave : redisMasterSlaveProperties.getSlaves()) {
String[] parts = slave.split(":");
masterReplicaConfig.addNode(parts[0], Integer.parseInt(parts[1]));
}
// 配置Lettuce客户端与读取策略
LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder()
.readFrom(ReadFrom.REPLICA_PREFERRED)
.build();
return new LettuceConnectionFactory(masterReplicaConfig, lettuceClientConfiguration);
}
2.5、主从测试
2.5.1、主库INFO返回信息
我们从INFO REPLICATION可以看到主库的role为master
2.5.2、从库INFO返回信息
我们从INFO REPLICATION可以看到主库的role为slave
2.5.3、主从库同步测试
2.5.3.1、redis客户端测试
当前主库和从库数据如下
我们在主库中添加一条test_key:1003的数据,从库不做任何手动操作。
重新reload从库,我们可以看到数据已经同步到从库中
2.5.3.2、springboot工程测试
使用postman添加一条数据:test_key:1004
查看主库和从库数据最新数据,同步成功
3、Redis 哨兵机制
3.1、概述
在本文档中,我们将重点介绍Redis版本2.8及其后续版本的哨兵机制。
哨兵模式是主从复制模式的一种进阶形式,继承了主从复制的所有优势,如数据一致性和读写分离。它的核心优点在于能够自动实现主从切换和故障转移,从而提升了系统的可用性和鲁棒性。在哨兵模式下,系统能够从手动切换转变为自动切换,极大地增强了系统的自动化程度和稳定性。然而,哨兵模式也存在一定的局限性,特别是在在线扩容方面。当集群容量接近或达到上限时,进行扩容操作相对较为复杂和困难。
注意事项:Redis 在 Windows 平台上不受官方支持,Redis 官方只提供了源码包(zip、tar.gz 格式)。
Redis 官网地址:redis.io/ Redis 源码地址:github.com/redis/redis
3.1.1、微软官方维护的 Redis
下载地址:github.com/microsoftar… 注意:仅有 Redis2.0 和 Redis3.0 的部分版本,最后一次更新是2016年,目前已停止维护了。而截止到2023年6月Redis官网的最新版本是 Redis7.2
tporadowski 大神也提供了 支持 Windows平台的 Redis 安装包,目前仍在维护,目前最新版本是 5.0.14,更新速度跟Redis官网也相差好几个大版本。 下载地址:github.com/tporadowski/redis/releases
3.2、Redis哨兵原理
自Redis 2.8版本起,官方引入了Sentinel(哨兵)架构,旨在提升系统的高可用性。哨兵模式主要通过后台监控机制来确保Redis服务的稳定性。在这一模式中,哨兵负责实时监控主节点的运行状况。一旦主节点出现故障,哨兵将基于预设的投票机制,自动将某个从节点晋升为新的主节点,以保持服务的连续性和数据的可用性。
哨兵本身是一个独立的进程,运行在Redis本身进程之外。它通过周期性地向Redis节点发送命令,并等待节点的响应,来判断被监控的Redis实例是否正常运行。通过这种方式,哨兵能够监控和管理一个或多个Redis实例,确保整个Redis服务的高可用性和稳定性。
3.3、哨兵模式环境搭建
3.3.1、redis配置
3.3.1.1、主库sentinel配置
新建sentinel配置文件sentinel.conf,添加配置内容如下
# 哨兵sentinel实例运行的端口,为了跟主库一致,我们直接定义为26380端口
port 26380
# 本地ip
bind 0.0.0.0
# 哨兵监听的主服务器 后面的1表示主机挂掉以后进行投票,只需要2票就可以从机变主机
sentinel monitor ebgmaster 10.41.170.130 6380 2
# 设置主机的密码(无密码可以省略)
# sentinel auth-pass ebgmaster admin
# 设置未得到主机响应时间,此处代表5秒未响应视为宕机
sentinel down-after-milliseconds ebgmaster 5000
# 设置等待主机活动时间,此处代表15秒主机未活动,则重新选举主机
sentinel failover-timeout ebgmaster 15000
# 设置重新选举主机后,同一时间同步数据的从机数量,此处代表重新选举主机后,每次2台从机同步主机数据,直到所有从机同步结束
sentinel config-epoch ebgmaster 2
# 执行故障转移时, 最多有2个从服务器同时对新的主服务器进行同步
sentinel leader-epoch ebgmaster 2
# 修改为以守护进程模式后台运行
daemonize yes
# 因为这里在同一台机器上运行多个实例,所以需要指定
pidfile E:\redis\redis-cluster\sentinel_130.pid
# 修改日志文件位置
logfile E:\redis\redis-cluster\sentinel_130.log
3.3.1.2、主库sentinel进程启动
# windows中启动命令
redis-server.exe sentinel.conf --sentinel
#Linux启动命令
./redis-sentinel sentinel_119.conf
运行效果如下,在日志文件中也可以查看日志信息:E:\redis\redis-cluster\sentinel_130.log
重复前面的操作,在119与100节点添加sentinel,并启动进程
3.4、查看哨兵的状态
3.4.1、查询哨兵状态
命令 redis-cli.exe -p 26379
进入客户端
命令 info sentinel
查看
可以看出sentinel状态正常,能够检测到redis的2个从节点,3个哨兵
3.4.2、宕机测试
关闭主库redis,重新查看哨兵状态
将主节点130 redis关闭,模拟宕机的情况。 哨兵投票选举出新的从节点119升为主节点。
当节点130 重新启动之后,自动降为从节点
4、Redis Cluster
4.1、概述
Redis Cluster,采用了去中心化的多主多从架构,以提高数据的可用性和伸缩性。这一架构使得Redis Cluster能够在保持高性能的同时,支持更大规模的数据存储和管理。以下是Redis Cluster的几个关键特点和优势的详细阐述:
-
去中心化的多主多从架构:
-
- 每个从节点都复制主节点的数据,但不直接参与读写操作,主要用于数据备份和故障恢复。
- 这种架构使得每个节点都可以在需要时承担主节点的角色,从而提高了整体系统的可靠性和容错能力。
-
数据处理与性能:
-
- Redis Cluster在处理涉及多个键的操作时可能面临性能挑战,尤其是在数据量大和高并发的场景下。这是因为多key操作可能需要跨多个节点进行,从而增加了操作的复杂性。
- 然而,对于单key操作,Redis Cluster能够保持其一贯的高性能,特别是在读操作上。
-
动态扩容和收缩能力:
-
- Redis Cluster支持动态地添加或移除节点,这意味着可以根据实际需求调整集群的规模,无需停机或中断服务。
- 这一特性对于处理不断变化的负载和数据量非常重要,使得Redis Cluster在大型应用中更具弹性。
-
节点间的通信与故障转移:
-
- 在Redis Cluster中,主节点之间会进行定期的健康检查和状态同步,确保数据的一致性。
- 当主节点出现故障时,其他主节点可以通过选举机制快速选出新的主节点,实现故障的自动转移,从而确保服务的连续性。
4.2、cluster原理
4.2.1、Redis Cluster 节点分配与主从模式
Redis Cluster 通过高效的节点分配和稳健的主从模式,确保了数据的高可用性和稳定性。以下是对其核心机制的详细解释:
4.2.1.1、节点间的哈希槽分配
Redis Cluster 使用哈希槽(hash slot)机制来分配数据。假设我们有三个主节点:A、B、C,它们可以部署在同一台机器的不同端口上,或分布在三台不同的服务器上。在这种设置下,16384个哈希槽将被如下分配:
- 节点A负责管理0至5460号槽;
- 节点B负责管理5461至10922号槽;
- 节点C负责管理10923至16383号槽。
4.2.1.2、数据的保存和获取
- 存入数据**:例如,存储一个键值对,键名为“key”,其哈希值按照 CRC16(‘key’) % 16384 = 6782 计算。根据这个哈希槽号,数据将被存储在节点B上。
- 获取数据:无论连接哪个节点(A、B、C),获取键名为“key”的数据时,都会根据同样的哈希算法路由到节点B上提取数据。
4.2.1.3、新增或删除主节点
-
新增节点:假设新增一个节点D,Redis Cluster 会将部分哈希槽从其他节点迁移至D节点。这可能导致哈希槽分布如下调整:
-
- 节点A:1365-5460
- 节点B:6827-10922
- 节点C:12288-16383
- 节点D:0-1364,5461-6826,10923-12287
-
删除节点:删除节点时,其管理的哈希槽会被迁移到其他节点上。迁移完成后,该节点即可被安全移除。
4.2.2、Redis Cluster主从模式
- 主从的重要性:为了保障数据的高可用性,Redis Cluster 引入了主从模式。在这种模式下,每个主节点都有一个或多个从节点。主节点处理所有的读写操作,而从节点主要负责数据备份。如果主节点发生故障,从节点中的一个将被提升为新的主节点,以确保集群的稳定运行。
- 未设置从节点的风险:以ABC三个主节点的集群为例,如果这些主节点都没有配置从节点,当其中一个(如B)发生故障时,整个集群的可用性将受到影响。A和C节点的哈希槽也将无法访问。
实例说明
在建立集群时,为每个主节点配置从节点是非常重要的。例如,集群包含主节点A、B、C,及其对应的从节点A1、B1、C1。这样,即使B节点出现故障,B1节点可以被提升为新的主节点,保证集群的持续运行。当B节点恢复时,它将成为B1的从节点。然而,需要注意的是,如果B节点和其对应的从节点B1同时出现故障,Redis Cluster 将无法提供服务。
4.3、cluster模式环境部
4.3.1、redis环境简述
redis
Redis Cluster被配置为三主三从模式。这意味着每台服务器上的两个Redis节点中,一个节点作为主库(master),另一个作为从库(slave)。以下是具体的服务器和节点配置:
4.3.1.1、服务器及节点配置
服务器IP | 主库端口(Master) | 从库端口(Slave) |
---|---|---|
10.41.170.30 | 6381 | 6382 |
10.41.170.40 | 6381 | 6382 |
10.41.170.130 | 6381 | 6382 |
注意事项
- 在Redis Cluster模式下,集群只支持一个数据库,即默认的数据库0。
- 由于集群不支持多数据库,后台代码配置时无法选择Redis库,所有操作均默认针对数据库0进行。
4.3.1.2、2redis配置文件配置
开启集群模式:cluster-enabled yes
# 绑定的IP地址,0.0.0.0代表监听所有的IP地址
bind 0.0.0.0
# 关闭保护模式,允许远程连接
protected-mode no
# 设置Redis监听的端口号
port 6381
# 开启集群模式
cluster-enabled yes
# 集群节点超时时间
cluster-node-timeout 5000
# 集群配置文件
cluster-config-file nodes-6381.conf
# 修改pid文件名,以守护进程运行的时候,会产生pid文件,默认位置为 /run/redis.pid
# 因为这里在同一台机器上运行多个实例,所以需要指定
pidfile "E:\ebgsd\redis\6381\redis-cluster\redis_6381.pid"
# 修改日志文件位置
logfile "E:\ebgsd\redis\6381\redis-cluster\redis_6381.log"
# 配置数据存储目录
dir "E:\ebgsd\redis\6381\data"
# 设置内存满时的数据淘汰策略为LRU
maxmemory-policy allkeys-lru
# 客户端连接超时时间,0表示无超时时间
timeout 0
# TCP keepalive时间,用于检测和断开空闲连接
tcp-keepalive 60
# 设置日志级别
loglevel notice
# 设置不同时间间隔的数据持久化规则
save 900 1
save 300 10
save 60 10000
# 关闭键空间事件通知
notify-keyspace-events ""
# 设置最大客户端连接数
maxclients 1000000
# 开启AOF持久化
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# 设置AOF持久化的同步方式为每秒同步
appendfsync everysec
# Lua脚本最大执行时间
lua-time-limit 5000
# 慢查询日志的配置
slowlog-log-slower-than 10000
slowlog-max-len 128
# 设置Redis的最大内存限制
maxmemory 80gb
# 设置TCP连接的最大等待队列长度
tcp-backlog 2048
# 跟踪延迟信息的百分位数
# latency-tracking-info-percentiles 50 99 99.9
# 用户权限设置
# user default on nopass sanitize-payload ~* &* +@all
# 启动时不显示Redis logo
# always-show-logo no
# 设置进程标题
# set-proc-title yes
# 进程标题模板
# proc-title-template "{title} {listen-addr} {server-mode}"
# 如果后台保存错误则停止写入
stop-writes-on-bgsave-error yes
# 开启RDB文件压缩
rdbcompression yes
# 开启RDB文件校验
rdbchecksum yes
# RDB文件名
dbfilename dump.rdb
# 从节点为只读模式
replica-serve-stale-data yes
replica-read-only yes
# 关闭无盘复制模式
repl-diskless-sync no
# 无盘复制模式的延迟时间
repl-diskless-sync-delay 5
# 开启TCP_NODELAY
repl-disable-tcp-nodelay no
# 从节点的优先级
replica-priority 100
# ACL日志最大长度
# acllog-max-len 128
# 懒释放相关配置
# lazyfree-lazy-eviction no
# lazyfree-lazy-expire no
# lazyfree-lazy-server-del no
replica-lazy-flush no
# lazyfree-lazy-user-del no
# lazyfree-lazy-user-flush no
# 不调整OOM分数
# oom-score-adj no
# OOM分数调整值
# oom-score-adj-values 0 200 800
# 禁用透明大页
# disable-thp yes
# 重写时不禁用AOF fsync
no-appendfsync-on-rewrite no
# AOF重写相关配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 加载截断的AOF文件
aof-load-truncated yes
# 延迟监控阈值
latency-monitor-threshold 0
# 数据结构的详细配置
# hash-max-listpack-entries 512
# hash-max-listpack-value 64
# list-max-listpack-size -2
# list-compress-depth 0
set-max-intset-entries 512
# zset-max-listpack-entries 128
# zset-max-listpack-value 64
hll-sparse-max-bytes 3000
# 激活重哈希
activerehashing yes
# 客户端输出缓冲区限制
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
# 设置Redis内部调度器的执行频率
hz 10
# AOF重写增量fsync
aof-rewrite-incremental-fsync yes
# 使用jemalloc后台线程
# jemalloc-bg-thread yes
# 设置为守护进程模式
daemonize yes
# 不使用监管模式
supervised no
4.3.2、Redis cluster启动
启动后,会启动所有的redis服务
redis-server.exe redis_6379.conf
启动后,会同时开启一个集群总线端口,集群总线端口是redis客户端连接的端口+10000
启动redis集群,第一次启动时会卡在Waiting for the cluster to join ....
上、一直没有反应。
解决方案:第一次启动初始化比较慢,可删除每个节点下的appendonlydir 、dump.rdb和nodes.conf文件,重启启动
#前面三个表示主库,后面三个表示从库
redis-cli.exe --cluster create --cluster-replicas 1 10.41.170.30:6381 10.41.170.40:6381 10.41.170.130:6381 10.41.170.30:6382 10.41.170.40:6382 10.41.170.130:6382
注: --cluster-replicas 1
表示创建自动创建并给每个 master 节点分配一个 slave 节点;
前三个IP:PORT为master节点 ,三主三从模式;
4.3.3、查看集群信息
# 直接查询,任意节点
redis-cli.exe --cluster info 10.41.170.130:6381
4.3.4、集群常用命令
# 进入集群
redis-cli.exe -h 10.41.170.130 -p 6381 -c -a myredis
# -c 表示集群支持,支持自动重定向 myredis表示密码
#进入后即可使用相关命令
集群(cluster): CLUSTER INFO # 查看集群信息 CLUSTER NODES # 查看集群所有节点信息
节点(node):
CLUSTER MEET IP PORT 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子
CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点
CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点
CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面
4.3.5、cluster重新创建
- 关闭所有已启动的redis节点
- 删除集群相关文件(在设置数据存储目录dir目录下) 删除每个节点下的appendonlydir 、dump.rdb和nodes.conf文件
- 启动所有Redis节点
- 重新创建cluster集群
redis-cli.exe --cluster create --cluster-replicas 1 10.41.170.30:6381 10.41.170.40:6381 10.41.170.130:6381 10.41.170.30:6382 10.41.170.40:6382 10.41.170.130:6382
若创建失败,提示
4.4、springboot配置
4.4.1、引入 pom 依赖
<!--redis相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
4.4.2、yml 配置文件
spring:
redis:
cluster:
# 集群节点
nodes: 10.41.170.160:6379,10.41.170.161:6379,10.41.170.162:6379,10.41.170.160:6380,10.41.170.161:6380,10.41.170.162:6380
# 最大重定向次数
max-redirects: 5
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 5
# 连接池中的最大空闲连接
max-idle: 10
# 连接池的最大数据库连接数
max-active: 20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 1000ms
enabled: true
4.4.3、RedisConfig配置文件
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport
{
@Bean
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
{
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}
4.5、测试
4.5.1、redis客户端测试
进入客户端
redis-cli.exe -h 10.41.170.130 -p 6381 -c
在尝试写入几个值,如下图,发现 【test_k31写到了40,test_k41写到了30,没显示具体节点是写到了130】
测试在130节点上获取写到30的key,能获取到说明集群部署成功
4.5.2、springboot工程测试
已经在不同节点写入数据,测试从130和30获取数据
结合写到不同节点信息,可以看到能正常获取到数据
redis 经典用例
- 会话管理:Redis 是一种高效的会话存储方案,能够存储用户的会话数据,并提供快速的读写访问。通过在 Redis 中存储会话数据,我们可以实现分布式和可扩展的会话管理。
- 缓存应用:Redis 最常见的用途之一是作为缓存存储。它能够把频繁访问的数据存储在内存中,从而显著提升访问速度和性能。使用 Redis 缓存数据结果,可以减少对后端数据源的频繁访问,加速应用响应时间。
- 分布式锁:Redis 的原子操作和高性能特性使其成为实现分布式锁的理想选择。利用 Redis 的 SETNX(SET if Not eXists)命令,可以实现基于 Redis 的分布式锁,有效协调多进程或服务器对共享资源的访问。
- 计数器功能:Redis 支持原子操作,适合用作高效的计数器。它可用于跟踪网站访问次数、统计应用中的事件频率等。Redis 的原子递增和递减操作确保计数器的更新不受并发操作干扰。
- 限流器:Redis 可作为限流器,控制对特定操作或资源的访问频率。通过结合计数器和过期特性,Redis 支持基于时间窗口的限流策略,有助于控制系统请求速率,防止过载。
- 全局唯一标识符:Redis 能生成全局唯一标识符(GUID),用于唯一识别实体或对象。它通过自增功能或 UUID 算法来生成全局唯一的 ID。
- 购物车功能:Redis 可作为购物车数据存储方案,存储用户选择的商品信息,并提供快速读写操作。通过 Redis 存储购物车数据,可以实现高性能和可扩展的购物车功能。
- 用户留存分析:Redis 能存储并跟踪用户活动信息,用于分析用户留存率。通过记录用户行为数据和时间戳,可以计算和追踪用户在特定时间段内的留存率。
- 消息队列:Redis 的发布/订阅功能使其可作为轻量级的消息队列解决方案。它适用于在不同应用程序或服务间传递消息,并支持多订阅者模式。
- 实时排行榜:Redis 可用于实现实时排行榜。通过将用户得分或指标存储在有序集合中,并利用 Redis 的排序功能,可以方便地计算和更新排行榜,支持实时排名查询。