Redis相关特性
事务
-
Redis 事务允许将多个命令打包在一起,按顺序执行,并保证这些命令的原子性(即事务中的命令要么全部执行,要么全部不执行)。Redis 事务通过
MULTI
、EXEC
、DISCARD
和WATCH
等命令实现。 -
事务的基本操作
-
MULTI
-
标记事务的开始。执行
MULTI
后,Redis 会将后续的命令放入队列中,而不是立即执行。 -
MULTI
-
-
EXEC
-
执行事务中的所有命令。Redis 会按顺序执行队列中的命令,并返回每个命令的结果。
-
EXEC
-
-
DISCARD
-
取消事务,清空事务队列中的所有命令。
-
DISCARD
-
-
WATCH
-
监视一个或多个键。如果在事务执行之前,这些键被其他客户端修改,则事务会被取消(即
EXEC
返回nil
)。实现乐观锁 -
# 客户端 1 127.0.0.1:6379> WATCH key1 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET key1 "value1" QUEUED# 客户端 2 127.0.0.1:6379> SET key1 "new_value" OK# 客户端 1 127.0.0.1:6379> EXEC (nil) # 事务被取消
-
-
-
事务的执行流程
- 使用
MULTI
开始事务。 - 将多个命令添加到事务队列中。
- 使用
EXEC
执行事务,或使用DISCARD
取消事务。
- 使用
-
事务的局限性
- 不支持回滚:Redis 事务不支持回滚。如果事务中的某个命令失败,其他命令仍然会执行。
- 错误处理:Redis 事务中的错误分为两种:
- 语法错误:在命令入队时检测到错误(如命令不存在),整个事务会被取消。
- 运行时错误:在命令执行时检测到错误(如对字符串执行
INCR
),只有该命令会失败,其他命令仍然会执行。
-
Redis 事务和关系型数据库事务的区别?
- 原子性:Redis 事务是原子性的,但不支持回滚。
- 隔离性:Redis 事务是单线程执行的,因此具有天然的隔离性。
- 持久性:Redis 事务的持久性取决于 Redis 的持久化配置(如 RDB 或 AOF)。
-
总结
-
命令 功能描述 示例 MULTI
标记事务的开始 MULTI
EXEC
执行事务中的所有命令 EXEC
DISCARD
取消事务,清空事务队列 DISCARD
WATCH
监视一个或多个键,实现乐观锁 WATCH key1 key2
-
持久化
基本介绍:
- Redis 的持久化机制是为了确保数据在 Redis 服务器重启或崩溃后能够被恢复。Redis 提供了两种主要的持久化机制:RDB(Redis Database) 和 AOF(Append-Only File)。这两种机制各有优缺点,可以根据实际需求选择使用其中一种或结合使用。
RDB(Redis Database)
-
RDB 是 Redis 的默认持久化方式。它通过生成数据快照(snapshot)来保存 Redis 的数据。
-
工作原理
- RDB 会在指定的时间间隔内,将内存中的数据快照保存到磁盘上的一个二进制文件(默认文件名为
dump.rdb
)。 - 快照生成时,Redis 会 fork 一个子进程来处理保存操作,主进程继续处理客户端请求。
- RDB 会在指定的时间间隔内,将内存中的数据快照保存到磁盘上的一个二进制文件(默认文件名为
-
快照生成方式
- 手动触发:通过执行
SAVE
或BGSAVE
命令生成快照。SAVE
,同步生成 RDB 快照。执行SAVE
时,Redis 会阻塞所有客户端请求,直到快照生成完成。BGSAVE
异步生成 RDB 快照。执行BGSAVE
时,Redis 会 fork 一个子进程来处理快照生成,主进程继续处理客户端请求。
- 自动触发:根据配置文件中的
save
规则,在满足条件时自动生成快照。
- 手动触发:通过执行
-
快照生成过程
- Redis 会 fork 一个子进程来处理快照生成操作,主进程继续处理客户端请求。
- 子进程将内存中的数据写入到一个临时 RDB 文件中。
- 写入完成后,用临时文件替换旧的 RDB 文件。
-
配置
-
在 Redis 配置文件(
redis.conf
)中,可以通过以下参数配置 RDB: -
save 900 1 # 在 900 秒内,如果至少有 1 个键被修改,则生成快照 save 300 10 # 在 300 秒内,如果至少有 10 个键被修改,则生成快照 save 60 10000 # 在 60 秒内,如果至少有 10000 个键被修改,则生成快照
-
dbfilename
-
指定 RDB 文件的名称,默认值为
dump.rdb
。 -
dbfilename dump.rdb
-
-
dir
-
指定 RDB 文件的保存目录,默认值为 Redis 的工作目录。
-
dir ./
-
-
stop-writes-on-bgsave-error
-
如果设置为
yes
,当 RDB 快照生成失败时,Redis 会拒绝写入操作,直到问题解决。 -
stop-writes-on-bgsave-error yes
-
-
-
优点
- 性能高:RDB 生成快照时对性能影响较小。
- 文件紧凑:RDB 文件是二进制格式,文件体积小,适合备份和恢复。
- 恢复速度快:RDB 文件加载速度快,适合大规模数据恢复。
-
缺点
- 数据丢失风险:如果 Redis 在两次快照之间崩溃,最后一次快照之后的数据会丢失。
- 不适合实时持久化:RDB 是定期生成快照,无法做到实时持久化。
AOF(Append-Only File)
-
AOF 通过记录 Redis 的写操作日志来保存数据。每次写操作都会被追加到 AOF 文件的末尾。
-
工作原理
- AOF 文件是一个文本文件,记录了 Redis 的所有写操作(如
SET
、INCR
等)。 - Redis 重启时,会重新执行 AOF 文件中的命令来恢复数据。
- AOF 文件是一个文本文件,记录了 Redis 的所有写操作(如
-
配置
-
在 Redis 配置文件(
redis.conf
)中,可以通过以下参数配置 AOF: -
appendonly yes # 启用 AOF appendfilename "appendonly.aof" # AOF 文件名 appendfsync everysec # 每秒同步一次 AOF 文件
-
appendfsync
参数有以下选项:always
:每次写操作都同步到磁盘,数据安全性最高,但性能最差。everysec
:每秒同步一次,性能和安全性之间取得平衡(默认值)。no
:由操作系统决定何时同步,性能最好,但数据安全性最低。
-
-
优点
- 数据安全性高:AOF 可以记录每次写操作,数据丢失的风险较低。
- 可读性强:AOF 文件是文本格式,可以手动查看和修改。
- 支持实时持久化:AOF 可以配置为每次写操作都同步到磁盘,适合对数据安全性要求高的场景。
-
缺点
- 文件体积大:AOF 文件记录了所有写操作,文件体积通常比 RDB 大。
- 恢复速度慢:Redis 重启时需要重新执行 AOF 文件中的命令,恢复速度较慢。
- 性能开销:AOF 的同步操作会对性能产生一定影响,尤其是在
appendfsync always
模式下。
-
AOF 重写
-
AOF 文件会不断增长,Redis 提供了 AOF 重写机制来压缩 AOF 文件。AOF 重写会生成一个新的 AOF 文件,只包含恢复当前数据集所需的最小命令集。
-
触发方式:
-
手动触发:执行
BGREWRITEAOF
命令。(异步执行AOF重写)REWRITEAOF
同步执行 AOF 重写。
-
自动触发:根据配置参数
auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
。 -
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
- 表示当前 AOF 文件大小比上一次重写后的 AOF 文件大小增长了 100%(即翻倍)时,触发 AOF 重写
- 如果
auto-aof-rewrite-min-size
设置为64mb
,则表示只有当前 AOF 文件大小超过 64MB 时,Redis 才会检查是否满足auto-aof-rewrite-percentage
的条件。
-
-
结合使用
- Redis 允许同时启用 RDB 和 AOF,以兼顾性能和数据安全性。
- RDB:用于定期生成数据快照,适合备份和快速恢复。
- AOF:用于记录每次写操作,确保数据的安全性。
- 在 Redis 重启时,会优先使用 AOF 文件来恢复数据(如果 AOF 文件存在),因为 AOF 文件通常包含更完整的数据。
- RDB 和 AOF 的备份
- RDB 备份:定期将
dump.rdb
文件复制到安全位置。 - AOF 备份:定期将
appendonly.aof
文件复制到安全位置。
- RDB 备份:定期将
主从复制
- Redis 的 主从复制(Replication) 是一种数据同步机制,允许将一个 Redis 实例(主节点)的数据复制到一个或多个 Redis 实例(从节点)。主从复制的主要目的是实现数据冗余、读写分离和高可用性。
主从复制的基本知识
- 角色定义
- 主节点(Master):负责写操作,并将数据同步到从节点。
- 从节点(Slave):负责读操作,并从主节点同步数据。
- 数据同步过程
- 初始化同步:
- 从节点启动时,会向主节点发送
SYNC
命令。 - 清除从节点的现有数据:
- 从节点会删除自己的所有数据,以确保与主节点的数据完全一致。
- 主节点接收到
SYNC
命令后,会生成一个 RDB 快照文件,并将其发送给从节点。 - 从节点加载 RDB 文件,完成初始化数据同步。
- 从节点启动时,会向主节点发送
- 增量同步:
- 初始化同步完成后,主节点会将后续的写操作命令(如
SET
、DEL
)发送给从节点。 - 从节点执行这些命令,保持与主节点的数据一致。
- 初始化同步完成后,主节点会将后续的写操作命令(如
- 断线重连:
- 如果从节点与主节点断开连接,重新连接后会尝试进行 部分同步。
- 如果部分同步失败,则会触发 全量同步。
- 初始化同步:
- 主从复制的特性
- 读写分离
- 主节点负责写操作,从节点负责读操作。
- 通过将读请求分发到从节点,可以减轻主节点的负载。
- 数据冗余
- 从节点保存与主节点相同的数据,提供数据冗余。
- 如果主节点发生故障,可以从从节点恢复数据。
- 高可用性
- 通过主从复制,可以实现 Redis 的高可用性。
- 结合哨兵(Sentinel)或集群(Cluster),可以实现自动故障转移。
- 读写分离
- 主从复制的注意事项
- 数据一致性
- 主从复制是异步的,从节点的数据可能会短暂落后于主节点。
- 如果需要强一致性,可以使用
WAIT
命令等待从节点同步完成。
- 主节点故障
- 如果主节点发生故障,需要手动或自动(通过哨兵)将从节点提升为主节点。
- 从节点只读
- 从节点默认是只读的,无法执行写操作。
- 可以通过配置
replica-read-only no
允许从节点执行写操作,但不推荐。
- 数据一致性
配置主从复制
-
配置从节点
-
在从节点的配置文件(
redis.conf
)中,添加以下配置:-
保存配置文件后,需要重启 Redis 服务
redis-server /path/to/redis.conf
-
replicaof <master-ip> <master-port> replicaof 127.0.0.1 6379
-
-
或者在启动从节点时,通过命令行参数指定主节点:
-
临时生效:通过命令行参数指定的配置仅在当前 Redis 实例运行时有效。
-
redis-server --replicaof 127.0.0.1 6379 redis-6380.conf
-
-
在 Redis 运行时,可以使用
CONFIG SET
命令动态修改配置:-
CONFIG SET replicaof 127.0.0.1 6379
-
为了使配置永久生效,还需要将配置保存到配置文件中:
-
CONFIG REWRITE
-
-
-
查看复制状态
-
在主节点或从节点上运行以下命令,查看复制状态:
-
info replication
-
-
查看节点状态
-
尝试连接节点:
-
redis-cli -h <node-ip> -p <node-port> ping
- 如果返回
Could not connect to Redis at <node-ip>:<node-port>: Connection refused
,说明节点可能宕机。
- 如果返回
-
-
登录节点所在的服务器
-
如果节点宕机,登录到节点所在的服务器,检查 Redis 服务状态和系统日志。
-
通过 SSH 登录服务器:
-
检查 Redis 服务状态:
-
如果 Redis 是通过
systemd
管理的,运行以下命令: -
sudo systemctl status redis
- 如果状态为
inactive
或failed
,说明 Redis 服务已停止。
- 如果状态为
-
-
查看 Redis 日志:
- Redis 日志通常位于
/var/log/redis/redis-server.log
或/var/log/redis.log
。查看日志以了解宕机原因:
- Redis 日志通常位于
-
检查系统资源:
- 使用
top
或htop
查看 CPU 和内存使用情况: - 使用
df -h
检查磁盘空间:
- 使用
-
-
使用监控工具
- 如果有监控工具(如 Prometheus、Grafana、RedisInsight 等),可以通过这些工具查看节点的历史状态和宕机时间。
-
恢复节点
-
sudo systemctl restart redis
-
手动更换主节点
-
前提
- 有 Redis 实例的管理权限。
- 知道当前主节点和从节点的 IP 地址和端口号。
- 已经确认从节点的数据是最新的(与主节点同步)。或者选择数据最新的从节点作为新的主节点
-
步骤:
-
选择一个数据最新的从节点作为新的主节点。
-
提升从节点为主节点:
-
redis-cli -h <slave-ip> -p <slave-port> REPLICAOF NO ONE
-
-
更新其他从节点:
-
将其他从节点重新配置为复制新的主节点:
-
redis-cli -h <other-slave-ip> -p <other-slave-port> REPLICAOF <new-master-ip> <new-master-port>
-
-
更新客户端配置:
- 将客户端的连接配置更新为新的主节点地址。
-
-
如果原主节点恢复后,可以将其重新加入集群作为从节点。
哨兵
哨兵机制的介绍
- Redis 的 哨兵机制(Sentinel) 是一种高可用性解决方案,用于监控 Redis 主从实例的状态,并在主节点故障时自动进行故障转移(Failover)。哨兵机制可以确保 Redis 服务在出现故障时仍然可用。
- 独立的进程:哨兵是一个独立的进程,与 Redis 主从实例分开运行。
- Sentinel 依赖于 Redis 的可执行文件和运行时环境。
- 哨兵机制的作用
- 监控:哨兵会持续监控 Redis 主节点和从节点的健康状态。
- 通知:当 Redis 实例出现故障时,哨兵可以通过 API 或脚本通知管理员。
- 自动故障转移:如果主节点故障,哨兵会自动将一个从节点提升为新的主节点。
- 配置提供者:客户端可以通过哨兵获取当前的主节点地址。
- 哨兵机制的工作原理
- 哨兵的组成
- 哨兵节点:运行 Sentinel 进程的 Redis 实例,负责监控和故障转移。
- 主节点:被监控的 Redis 主实例。
- 从节点:被监控的 Redis 从实例。
- 哨兵的组成
- 哨兵的工作流程
- 监控:
- 哨兵会定期向主节点和从节点发送
PING
命令,检查它们是否正常运行。 - 如果主节点未响应,哨兵会将其标记为 主观下线(Subjectively Down, SDOWN)。
- 哨兵会定期向主节点和从节点发送
- 确认故障:
- 当多个哨兵都认为主节点下线时,哨兵会将其标记为 客观下线(Objectively Down, ODOWN)。
- 选举领导者:
- 哨兵集群会通过 Raft 算法选举一个领导者哨兵,负责执行故障转移。
- 故障转移:
- 领导者哨兵会选择一个从节点,将其提升为新的主节点。
- 更新其他从节点的配置,使它们复制新的主节点。
- 通知客户端新的主节点地址。
- 监控:
配置哨兵的步骤
-
准备 Redis 主从复制
-
创建哨兵配置文件
-
创建一个哨兵配置文件(如
sentinel.conf
),内容如下: -
port 26379 sentinel monitor mymaster 127.0.0.1 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 10000 sentinel parallel-syncs mymaster 1
-
port 26379
:哨兵节点的端口。 -
sentinel monitor mymaster 127.0.0.1 6379 2
:监控名为mymaster
的主节点,IP 为127.0.0.1
,端口为6379
,2
表示至少需要 2 个哨兵同意才能判定主节点故障。 -
sentinel down-after-milliseconds mymaster 5000
:如果主节点 5000 毫秒未响应,则标记为主观下线。 -
sentinel failover-timeout mymaster 10000
:故障转移的超时时间为 10000 毫秒。如果故障转移在超时时间内未完成,哨兵会认为故障转移失败,并可能重新尝试。 -
sentinel parallel-syncs mymaster 1
:故障转移时,每次只同步一个从节点。如果多个从节点同时从新的主节点同步数据,可能会对主节点造成较大的负载。
-
-
启动哨兵节点
-
redis-sentinel /path/to/sentinel.conf
-
-
配置多个哨兵节点
- 为了实现高可用性,建议至少配置 3 个哨兵节点。每个哨兵节点的配置文件类似,但
port
和sentinel monitor
中的 IP 和端口需要根据实际情况调整。
- 为了实现高可用性,建议至少配置 3 个哨兵节点。每个哨兵节点的配置文件类似,但
-
验证哨兵配置
-
连接到哨兵节点:
-
redis-cli -p 26379
-
-
运行以下命令查看哨兵状态:
-
info sentinel
-
-
-
哨兵机制的注意事项
- 哨兵节点的数量
- 建议至少部署 3 个哨兵节点,以确保高可用性。
- 哨兵节点的数量应为奇数,以避免选举时出现平票。
- 网络分区
- 在网络分区的情况下,哨兵可能会错误地判定主节点故障。
- 可以通过配置
quorum
参数来减少误判的概率。
- 客户端支持
- 客户端需要支持哨兵机制,才能自动获取主节点地址。
- 哨兵节点的数量