Redis主从复制
Redis 的主从复制(Replication)是一种常见的高可用性和扩展性解决方案。通过主从复制,可以将一个 Redis 实例(称为"主节点")的数据复制到一个或多个其他 Redis 实例(称为"从节点")。这种机制不仅可以提高读取性能,还能增加系统的容错性和数据冗余度。
什么是主从复制?
主从复制是指将主节点的数据复制到一个或多个从节点的过程。在主从复制模式下,主节点负责写操作,而从节点主要用于读操作。主节点会将写入的所有数据同步到从节点,确保从节点的数据与主节点保持一致。
主从复制的实现机制
-
初始同步:
- 当从节点第一次连接到主节点时,会进行一次全量同步(full synchronization),主节点会将所有数据发送给从节点。
- 主节点会生成一个 RDB 文件(Redis Data Base),并通过网络传输给从节点。
- 从节点接收到 RDB 文件后,会将其加载到内存中,重建数据集。
-
增量同步:
- 在初始同步之后,主节点和从节点之间会通过复制日志(replication log)的方式进行增量同步。
- 主节点将所有写操作记录到复制日志中。
- 从节点通过网络连接到主节点,定期拉取主节点的写操作,并将其应用到自己的数据集上。
配置主从复制
整体实验环境为3台设备
redis-master
redis-node1
redis-node2
配置主节点
-
启用复制 :
- 在主节点的配置文件
redis.conf
中,确保slaveof
参数未被设置或设置为no one
。 - 如果需要手动禁用复制,可以设置
slaveof no one
。
- 在主节点的配置文件
关闭protected模式
bash
vim /etc/redis/6379.conf
protected-mode no
重启redis服务
bash
/etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...
- 持久化设置 :
- 配置持久化(如 RDB 或 AOF)以确保数据安全。
配置从节点
-
设置从节点:
-
在从节点的配置文件
redis.conf
中,设置slaveof
参数指向主节点的 IP 地址和端口号:shslaveof <master-ip> <master-port>
例如:
shslaveof 172.25.254.100 6379
-
-
从节点配置:
- 可以设置从节点的其他配置选项,如:
repl-backlog-size
:设置复制缓冲区大小。repl-backlog-ttl
:设置复制缓冲区的存活时间。
- 可以设置从节点的其他配置选项,如:
主从复制的工作流程
- slave节点发送同步亲求到master节点
- slave节点通过master节点的认证开始进行同
- master节点会开启bgsave进程发送内存rbd到slave节点,在此过程中是异步操作,也就是说master节点仍然可以进行写入动作
- slave节点收到rdb后首先清空自己的所有数据
- slave节点加载rdb并进行数据恢复
- 在master和slave同步过程中master还会开启新的bgsave进程把没有同步的数据进行缓存
- 然后通过自有的replactionfeedslave函数把未通过内存快照发动到slave的数据一条一条写入到 slave中
从节点连接主节点 :
从节点启动后,会尝试连接到主节点。
如果连接成功,从节点会发送 PSYNC
命令给主节点,请求同步。
全量同步:
如果是首次连接或从节点没有上次复制的信息,主节点会生成 RDB 文件,并发送给从节点。
从节点接收到 RDB 文件后,加载数据到内存中。
增量同步:
在全量同步之后,主节点会将所有写操作记录到复制日志中。
从节点定期拉取主节点的写操作,并应用到自己的数据集上。
断点续传
什么是断点续传?
当master-slave网络连接断掉后,slave重新连接master时,会触发全量复制,但是从2.8版本开始,slave与master能够在网络连接断开重连后,只从中断处继续进行复制,而不必重新同步,这就是所谓的断点续传。
断电续传这个新特性使用psync命令,旧的实现中使用sync命令。Redis2.8版本可以检测出它所连接的服务器是否支持PSYNC命令,不支持的话使用SYNC命令。master服务器收到slave发送的psync命令后,会根据自身的情况做出对应的处理,可能是FULLRESYNC runid offset触发全量复制,也可能是CONTINUE触发增量复制
命令格式:psync runid offset
工作原理:
(1)master服务器在内存缓冲区中给每个slave服务器都维护了一份同步备份日志(in-memory backlog),缓存最近一段时间的数据,默认大小1m,如果超过这个大小就会清理掉。
(2)同时,master 和 slave 服务器都维护了一个复制偏移量(replication offset)和 master线程ID(master run id),每个slave服务器在跟master服务器进行同步时都会携带master run id 和 最后一次同步的复制偏移量offset,通过offset可以知道主从之间的数据不一致的情况。
(3)当连接断开时,slave服务器会重新连接上master服务器,然后请求继续复制。假如主从服务器的两个master run id相同,并且指定的偏移量offset在同步备份日志中还有效,复制就会从上次中断的点开始继续。如果其中一个条件不满足,就会进行完全重新同步,因为主运行id不保存在磁盘中,如果从服务器重启的话就只能进行完全同步了。
(4)在部分同步过程中,master会将本地记录的同步备份日志中记录的指令依次发送给slave服务器从而达到数据一致。
主从复制的优势
-
读写分离:
- 从节点主要用于读操作,可以显著提高读取性能。
- 主节点仅处理写操作,可以减少写操作对读性能的影响。
-
高可用性:
- 如果主节点发生故障,可以从节点中选择一个作为新的主节点,实现故障转移。
- 多个从节点可以提供数据冗余,提高数据的可靠性。
-
数据备份:
- 从节点可以作为数据备份,确保数据不会因单点故障而丢失。
配置示例
配置主节点
sh
# redis.conf
# 确保 slaveof 参数未被设置或设置为 no one
slaveof no one
# 配置持久化
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir .
配置从节点
sh
# redis.conf
# 设置从节点指向主节点
slaveof 192.168.1.100 6379
# 配置复制缓冲区
repl-backlog-size 1mb
repl-backlog-ttl 60
故障转移
如果主节点发生故障,可以从节点中选择一个作为新的主节点。这个过程可以手动完成,也可以通过 Redis Sentinel 自动完成。
Redis Sentinel(哨兵高可用)
Sentinel 进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,
可以实现Master和Slave服务器的切换,保证系统的高可用,此功能在redis2.6+的版本已引用,Redis的
哨兵模式到了2.8版本之后就稳定了下来。一般在生产环境也建议使用Redis的2.8版本的以后版本
每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave定时发送消息,以确认对方是否"活"
着,如果发现对方在指定配置时间(此项可配置)内未得到回应,则暂时认为对方已离线,也就是所谓的" 主观认为宕机"
(主观:是每个成员都具有的独自的而且可能相同也可能不同的意识),英文名称: Subjective Down,简称SDOWN
有主观宕机,对应的有客观宕机。当"哨兵群"中的多数Sentinel进程在对Master主服务器做出SDOWN 的 判断,并且通过
SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判
断,这种方式就是"客观宕机"(客观:是不依赖于某种意识而已经实际存在的一切事物),英文名称是: Objectively Down, 简称
ODOWN 通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改
相关配置,并开启故障转移(failover) Sentinel 机制可以解决master和slave角色的自动切换问题,但单个 Master
的性能瓶颈问题无法解决,类 似于MySQL中的MHA功能 Redis
Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数
Redis 哨兵(Sentinel)是 Redis 提供的一种高可用性解决方案,它用于监控 Redis 主从集群的健康状况,并在主节点发生故障时自动进行故障转移。哨兵系统的设计目的是为了提高 Redis 集群的可靠性和可用性,确保即使在主节点故障的情况下,系统仍然能够正常运行。
什么是 Redis 哨兵
Redis 哨任(Sentinel)是一个分布式监控系统,用于监控多个 Redis 实例的健康状况。它不仅可以监控主节点(Master),还可以监控从节点(Slave)。哨兵系统通过一组独立运行的哨兵实例组成,它们之间相互协作,共同监控 Redis 集群的状态。
哨兵的主要功能
-
监控:
- 监控 Redis 主节点和从节点的状态。
- 监控主从复制关系是否正常。
-
消息通信:
- 哨兵实例之间通过消息通信机制进行信息交流。
- 哨兵可以发送消息给其他哨兵或 Redis 节点。
-
故障转移:
- 当主节点发生故障时,哨兵可以自动选择一个合适的从节点作为新的主节点,并将其他从节点指向新的主节点。
- 故障转移过程是自动化的,无需人工干预。
-
配置中心:
- 哨兵可以作为 Redis 集群的配置中心,管理 Redis 实例的配置信息。
-
通知:
- 哨兵可以向管理员发送通知,报告 Redis 集群的状态变化。
哨兵的工作原理
监控机制
-
心跳检测:
- 哨兵定期向主节点、从节点和其他哨兵实例发送心跳信号(ping)。
- 如果在一定时间内没有收到回复,则认为该节点处于不可达状态。
-
主从状态监控:
- 哨兵通过定期查询从节点,了解从节点与主节点的同步状态。
- 如果主节点发生故障,哨兵会根据一定的选举机制,决定是否进行故障转移。
消息通信
-
哨兵之间的通信:
- 哨兵实例之间通过 Redis 发布/订阅机制进行消息通信。
- 每个哨兵都会订阅一个特殊的频道,用于接收其他哨兵的消息。
-
主从节点的通信:
- 哨兵通过 Redis 命令与主节点和从节点进行通信,获取集群状态信息。
故障转移
-
故障检测:
- 当哨兵检测到主节点不可达时,会发起投票机制,决定是否进行故障转移。
- 如果超过半数的哨兵确认主节点确实不可达,则启动故障转移流程。
-
选择新的主节点:
- 哨兵从当前的从节点中选择一个作为新的主节点。
- 选择标准包括从节点的复制偏移量、连接时间和优先级。
-
重新配置从节点:
- 新的主节点被选出后,哨兵会将其他从节点重新配置为指向新的主节点。
- 哨兵也会通知客户端新的主节点地址。
配置哨兵
配置哨兵实例
-
创建哨兵配置文件:
- 创建一个哨兵的配置文件
sentinel.conf
。 - 配置哨兵监听的端口、日志级别等基本参数。
- 创建一个哨兵的配置文件
-
监控主节点:
-
配置哨兵监控的主节点信息:
shsentinel monitor <service-name> <ip> <port> <quorum>
例如:
shsentinel monitor mymaster 192.168.1.100 6379 2
-
启动哨兵实例
-
启动哨兵:
-
在 Redis 安装目录下,启动哨兵实例:
shredis-server /path/to/sentinel.conf --sentinel
-
-
启动多个哨兵实例:
- 可以在同一台机器上启动多个哨兵实例,或者在不同的机器上启动。
- 确保每个哨兵实例都使用相同的配置文件。
监控与管理
-
哨兵状态监控:
-
可以通过 Redis 命令行工具
redis-cli
查询哨兵的状态:shredis-cli -s <sentinel-ip> <sentinel-port>
-
-
故障转移管理:
-
哨兵会自动管理故障转移过程,但在特殊情况下也可以手动触发故障转移:
shsentinel failover <service-name>
-
例子
假设有一个 Redis 主从集群,其中包含一个主节点和多个从节点。为了实现高可用性,我们可以配置一组哨兵实例来监控这个集群。
配置哨兵实例
sh
# sentinel.conf
port 26379
dir /var/lib/redis/6379/sentinel
logfile "/var/log/redis_sentinel.log"
# 监控主节点
sentinel monitor mymaster 192.168.1.100 6379 2
# 日志级别
daemonize yes
loglevel notice
启动哨兵实例
sh
redis-server /etc/redis/sentinel.conf --sentinel
配置主节点
sh
# redis.conf
port 6379
# 确保 slaveof 参数指向哨兵
slaveof no one
配置从节点
sh
# redis.conf
port 6379
slaveof 192.168.1.100 6379
Redis Cluster 无中心化设计
Redis Cluster 是 Redis 提供的一种无中心化的集群解决方案,它允许 Redis 在分布式环境中运行,从而实现水平扩展和高可用性。Redis Cluster 通过将数据分片(Sharding)和复制(Replication)相结合,提供了高度可扩展和容错的特性。
在哨兵sentinel机制中,可以解决redis高可用问题,即当master故障后可以自动将slave提升为master,
从而可以保证redis服务的正常使用,但是无法解决redis单机写入的瓶颈问题,即单机redis写入性能受
限于单机的内存大小、并发数量、网卡速率等因素。 redis 3.0版本之后推出了无中心架构的redis
cluster机制,在无中心的redis集群当中,其每个节点保存 当前节点数据和整个集群状态,每个节点都和其他所有节点连接
什么是 Redis Cluster
Redis Cluster 是一个无中心化的集群架构,它允许多个 Redis 节点协同工作,通过数据分片和复制来提高性能和可靠性。与传统的主从复制不同,Redis Cluster 中的每个节点都可以独立运行,并且可以动态地加入或退出集群。
Redis Cluster 的主要特点
-
无中心化:
- Redis Cluster 没有中心节点来管理集群的状态。
- 所有的节点都是平等的,每个节点都负责管理一部分数据和维护集群状态。
-
数据分片:
- Redis Cluster 将数据划分为 16,384 个槽(Slots),每个槽可以分配给集群中的任意一个节点。
- 这种分片机制使得数据可以均匀分布在多个节点上,从而实现水平扩展。
-
自动重分配:
- 如果集群中的某个节点失效或新增节点,Redis Cluster 可以自动重新分配槽,以确保数据均匀分布。
- 这种动态调整机制使得集群可以在不中断服务的情况下进行扩展或缩减。
-
读写分离:
- 每个主节点都有一个或多个从节点,主节点负责写操作,从节点负责读操作,实现读写分离。
- 从节点可以作为备用节点,在主节点发生故障时自动接管其工作。
-
高可用性:
- 通过数据复制和故障转移机制,提高了系统的可用性。
- 如果主节点发生故障,集群会自动选择一个从节点升为主节点,继续提供服务。
-
一致性哈希:
- Redis Cluster 使用一致性哈希算法来确定键属于哪个槽,从而分配给相应的节点。
- 这种算法有助于在节点增减时最小化键的重新分配,减少数据迁移带来的影响。
Redis cluster架构
假如三个主节点分别是:A, B, C 三个节点,采用哈希槽 (hash slot)的方式来分配16384个slot 的话它们
三个节点分别承担的slot 区间可以是:
节点A覆盖 0-5460
节点B覆盖 5461-10922
节点C覆盖 10923-16383
Redis cluster 主从架构
Redis cluster的架构虽然解决了并发的问题,但是又引入了一个新的问题,每个Redis master的高可用
如何解决?
那就是对每个master 节点都实现主从复制,从而实现 redis 高可用性
redis cluster部署架构说明
Redis Cluster 的工作流程
初始化集群
-
准备节点:
-
准备多个 Redis 节点,并确保每个节点的配置文件
redis.conf
中设置了集群模式:shcluster-enabled yes
-
-
创建集群:
-
使用
redis-cli
工具来创建集群:shredis-cli --cluster create node1_ip:node1_port node2_ip:node2_port ... nodeN_ip:noden_port --cluster-replicas 1
-
数据分片
-
槽分配:
- Redis Cluster 将 16,384 个槽分配给集群中的节点。
- 每个槽只能由一个节点负责。
-
键到槽的映射:
- Redis Cluster 使用 CRC16 算法计算键的哈希值,并将该值映射到一个槽上。
- 这样可以确保键值对总是存储在同一个节点上。
数据读写
-
写操作:
- 写操作总是发生在主节点上。
- 写入的数据会被复制到从节点,实现数据的高可用性。
-
读操作:
- 读操作可以在主节点或从节点上执行。
- 从节点主要用于读操作,减轻主节点的负担,提高读性能。
故障转移
-
故障检测:
- Redis Cluster 使用心跳机制来检测节点的健康状态。
- 如果主节点长时间没有响应心跳,集群会认为该节点已失效。
-
自动故障转移:
- 当主节点失效时,集群会选择一个从节点升为主节点,并更新集群状态。
- 这一过程是自动化的,无需人工干预。
配置 Redis Cluster
配置节点
-
配置文件:
-
在每个节点的
redis.conf
文件中,设置集群模式:shcluster-enabled yes cluster-config-file nodes-6379.conf cluster-node-timeout 15000
-
-
端口和 IP 地址:
-
每个节点需要一个唯一的 IP 地址和端口号。
-
在
redis.conf
中设置节点的 IP 地址和端口号:shbind 0.0.0.0 port 6379
-
-
集群配置文件:
- 每个节点都需要一个集群配置文件
nodes.conf
,用于存储集群状态信息。
- 每个节点都需要一个集群配置文件
创建集群
-
使用
redis-cli
创建集群:-
使用
redis-cli
工具创建集群:shredis-cli --cluster create node1_ip:node1_port node2_ip:node2_port ... nodeN_ip:noden_port --cluster-replicas 1
-
其中
--cluster-replicas 1
表示每个主节点至少有一个从节点。
-
-
手动配置集群:
-
如果需要手动配置集群,可以使用
redis-cli
的cluster
命令:shredis-cli --cluster add-node node_ip:node_port cluster_ip:cluster_port
-
Redis-cli--cluster参数说明
bash
[root@redis-master1 ~]# redis-cli --cluster help
Cluster Manager Commands:
create host1:port1 ... hostN:portN #创建集群
--cluster-replicas <arg> #指定master的副本数
check <host:port> or <host> <port> #检测集群信息
info <host:port> or <host> <port> #查看集群信息
fix <host:port> or <host> <port> #修复集群
reshard <host:port> or <host> <port> #在线热迁移集群指定主机的slots数据
rebalance <host:port> or <host> <port> #平衡各集群主机的slot数量
add-node new_host:new_port existing_host:existing_port #添加主机
del-node host:port node_id #删除主机
import host:port #导入外部redis服务器的数据到
当前集群
Redis Cluster 的限制
尽管 Redis Cluster 提供了许多优点,但也存在一些限制:
-
数据类型:
- Redis Cluster 目前不支持所有 Redis 数据类型,如 Streams 和 Modules。
- 一些高级功能(如 GEO 命令)可能不受支持或表现不佳。
-
事务支持有限:
- Redis Cluster 不支持跨槽的事务,即不能在一个事务中同时操作属于不同槽的数据。
-
复杂性增加:
- 集群环境增加了管理和维护的复杂性,尤其是在故障恢复和扩展方面。
-
客户端兼容性:
- 需要使用集群感知的客户端库来与 Redis Cluster 交互,以正确处理数据分片和故障转移。
Redis Cluster 的应用场景
Redis Cluster 适用于需要高可用性和水平扩展的应用场景,特别是在处理大量并发读写请求的情况下。例如:
-
Web 应用程序缓存:
- 通过 Redis Cluster 提供高可用性和高性能的缓存服务。
-
实时数据分析:
- 在大数据分析和实时数据处理中,Redis Cluster 可以提供快速的数据访问和处理能力。
-
分布式系统:
- 在分布式系统中,Redis Cluster 可以作为共享缓存或消息队列,提高系统的整体性能。