目录
一、Redis持久化概述
1.什么是Redis持久化
Redis 是一个内存数据库,数据存储在内存中,为了避免因意外断电等原因导致数据丢失,Redis 提供了持久化功能,可以将内存中的数据定期保存到硬盘上
2.持久化方式
一、RDB持久化(快照持久化)
①定期将内存中的数据生成快照并保存为二进制文件(.rdb)
②可以手动触发(`SAVE` 或 `BGSAVE`),也可以根据配置的时间和操作次数自动触发二、AOF持久化(追加文件持久化)
①记录每个写操作的日志,将这些命令追加到文件(.aof)中
②Redis 重启时,通过执行 AOF 文件中的命令恢复数据
③支持多种同步策略,以平衡性能和数据安全性
3.RDB持久化
3.1概念
RDB 持久化是指在指定时间间隔内将内存中的数据生成快照,并保存到硬盘中(因此也称为快照持久化)。它使用二进制压缩格式存储,生成的文件后缀为 `.rdb`。当 Redis 重新启动时,可以读取该快照文件来恢复数据。这种方式的优点是性能较高,适合大规模数据恢复,但可能导致在最后一次快照后产生的数据丢失
3.2触发条件
手动触发:
save命令:会生成 RDB 文件,但会阻塞 Redis 服务器进程,直到文件创建完成。在此期间,服务器无法处理任何命令请求,基本已被废弃
bgsave:会创建一个子进程来生成 RDB 文件,父进程继续处理请求。虽然在子进程创建时会短暂阻塞,但整体上不会影响主进程,因此在生产环境中推荐使用 BGSAVE
自动触发:
自动触发的 RDB 持久化同样优先使用 BGSAVE。可以在配置文件中通过 `save m n` 指定触发条件可在配置文件里修改参数
vim /etc/redis/6379.conf
--219行--以下三个save条件满足任意一个时,都会引起bgsave的调用
save 900 1 :当时间到900秒时,如果redis数据发生了至少1次变化,则执行bgsave
save 300 10 :当时间到300秒时,如果redis数据发生了至少10次变化,则执行bgsave
save 60 10000 :当时间到60秒时,如果redis数据发生了至少10000次变化,则执行bgsave
--254行--指定RDB文件名
dbfilename dump.rdb
--264行--指定RDB文件和AOF文件所在目录
dir /var/lib/redis/6379
--242行--是否开启RDB文件压缩
rdbcompression yes
3.3执行流程
1. 父进程检查:
Redis 父进程首先检查当前是否正在执行 SAVE、BGSAVE 或 BGREWRITEAOF。如果正在执行,BGSAVE 命令将直接返回,不会启动新的子进程。这是为了避免并发的子进程同时进行大量磁盘写操作,从而引起性能问题2. 创建子进程:
如果没有其他持久化操作正在进行,父进程会执行 fork 操作来创建子进程。在此过程中,父进程会阻塞,无法处理来自客户端的任何命令3. 返回信息:
一旦成功 fork 后,BGSAVE 命令返回“Background saving started”信息,父进程解除阻塞,可以继续响应其他命令4. 子进程创建 RDB 文件:
子进程负责根据父进程的内存快照生成 RDB 文件。它会创建一个临时快照文件,完成后通过原子操作替换旧的 RDB 文件5. 完成信号:
子进程在完成 RDB 文件的生成后,会向父进程发送信号,表示持久化操作已完成。父进程接收到信号后,会更新相关的统计信息
3.4启动时加载
1. 自动加载:
RDB 文件的加载在 Redis 服务器启动时自动执行,无需专门命令2. 优先级:
当 AOF(Append-Only File)开启时,Redis 优先加载 AOF 文件以恢复数据。只有在 AOF 关闭的情况下,Redis 才会检测并加载 RDB 文件3. 阻塞状态:
在加载 RDB 文件期间,Redis 服务器会处于阻塞状态,无法处理任何客户端请求,直到加载完成4. 文件校验:
Redis 在载入 RDB 文件时,会进行文件完整性校验。如果发现文件损坏,会在日志中记录错误,并导致 Redis 启动失败
4. AOF持久化
4.1概念
AOF(Append-Only File)持久化是 Redis 的一种数据持久化机制,它将 Redis 执行的每次写入和删除命令记录到一个单独的日志文件中。与 RDB 持久化将进程数据快照写入文件不同,AOF 只记录变更操作,而查询操作则不会被记录
4.2启动AOF
开启AOF持久化需要修改配置文件
vim /etc/redis/6379.conf
--700行--修改,开启AOF
appendonly yes
--704行--指定AOF文件名称
appendfilename "appendonly.aof"
--796行--是否忽略最后一条可能存在问题的指令
aof-load-truncated yes
重启Redis服务器使配置生效
/etc/init.d/redis_6379 restart
4.3执行流程
1. 命令追加 (Append)
写命令追加
①Redis 将接收到的每个写入和删除命令追加到缓冲区 `aof_buf` 中,而不是直接写入磁盘。这种方式减少了频繁的硬盘 I/O 操作,提高了性能
②命令以 Redis 协议的文本格式存储,确保兼容性和可读性2. 文件写入 (Write) 和文件同步 (Sync)
同步策略
Redis 提供了三种 AOF 缓存区的同步策略:①appendfsync always:
每次写命令后,立即调用 fsync 同步到 AOF 文件,确保数据安全,但会降低性能②appendfsync no:
写入后仅调用 write,不进行 fsync 同步,由操作系统负责。这种方式性能较好,但数据安全性较差③appendfsync everysecond(默认):
写入后调用 write,然后每秒由专门的线程调用一次 fsync。这种方式在性能与数据安全性之间取得平衡,是推荐的配置3. 文件重写 (Rewrite)
定期重写:
为防止 AOF 文件过大,Redis 定期进行 AOF 文件重写。它会生成一个新的压缩版本,保留必要的写命令,从而减少磁盘占用
4.4启动时加载
主要特点
1. 优先加载 AOF:
Redis启动时会检查 AOF 文件。如果 AOF 文件存在且有效,Redis 将优先使用它来恢复数据2. AOF 文件不存在时的行为:
如果 AOF 文件开启但不存在,即使 RDB 文件存在,Redis 也不会加载 RDB 文件3. 文件校验:
Redis 在加载 AOF 文件时,会对文件进行校验。如果发现文件损坏,启动将失败,并在日志中记录错误信息4. 不完整的 AOF 文件:
如果 AOF 文件的结尾不完整(如因为机器突然宕机导致),但 `aof-load-truncated` 参数开启(默认开启),Redis 会忽略 AOF 文件的尾部数据,并成功启动,同时在日志中输出警告配置参数
aof-load-truncated:
该参数控制在 AOF 文件尾部不完整时的行为。开启时,Redis 会在启动时忽略不完整的部分,确保能继续运行;关闭时,Redis 将因文件损坏而无法启动
5.RDB和AOF的优缺点
RDB持久化
优点:
①文件紧凑,体积小,传输快,适合全量复制
②恢复速度快
③对性能影响较小缺点:
①不支持实时持久化,数据丢失风险较高
②兼容性差,旧版本Redis可能无法读取新版本RDB文件
③在执行bgsave时,主进程会被阻塞,IO压力增大AOF持久化
优点:
①支持秒级持久化,能更好地保护数据
②兼容性好,容易与不同版本的Redis配合使用缺点:
①文件体积较大,恢复速度慢
②对性能影响大,频繁写入导致IO压力增加,可能引发AOF追加阻塞问题
③类似于RDB的重写过程也会导致阻塞和IO压力
二、Redis性能管理
1.查看Redis内存使用
登录到redis数据库,然后查看redis内存使用情况
redis-cli -h 172.16.58.10 -p 6379
172.16.58.10:6379> info memory
# Memory
used_memory:853304
used_memory_human:833.30K
used_memory_rss:10510336
used_memory_rss_human:10.02M
used_memory_peak:853304
used_memory_peak_human:833.30K
used_memory_peak_perc:100.01%
used_memory_overhead:841078
used_memory_startup:791384
used_memory_dataset:12226
used_memory_dataset_perc:19.74%
allocator_allocated:1661928
allocator_active:2068480
allocator_resident:9039872
total_system_memory:1911857152
total_system_memory_human:1.78G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.24
allocator_frag_bytes:406552
allocator_rss_ratio:4.37
allocator_rss_bytes:6971392
rss_overhead_ratio:1.16
rss_overhead_bytes:1470464
mem_fragmentation_ratio:12.94
mem_fragmentation_bytes:9698056
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
2.内存碎片率
2.1定义
内存碎片率 = used_memory_rss / used_memory,其中:
①used_memory_rss:Redis 实例所占的物理内存,包括内存碎片
②used_memory:Redis 实际使用的内存总量
2.2内存碎片的来源
内存碎片是由于操作系统在分配和回收内存时未能有效利用物理内存导致的,尤其是在需要分配大块连续内存时
2.3监测内存碎片率的重要性
合理范围:
①稍大于1:表示内存碎片较低,Redis 性能良好
②超过1.5:表示内存使用效率低,需采取措施(如重启 Redis)
③低于1:表示内存分配超出物理内存,操作系统在进行交换,需增加物理内存或优化 Redis 内存使用
2.4优化建议
①定期监控内存碎片率,使用 redis-cli 进行性能分析
②在内存碎片率较高时,考虑使用SHUTDOWN SAVE命令重启Redis实例,以清理内存碎片
③如果碎片率长期较高,可能需要优化数据结构或配置 Redis 的内存管理策略
3.内存使用率
3.1定义
当 Redis 实例的内存使用率超过可用的最大内存时,操作系统将开始使用交换空间(swap),这可能导致性能下降
3.2避免内存交换发生的方法
1. 根据缓存数据大小选择 Redis 实例:
在部署 Redis 时,确保实例的内存配置足以容纳预期的数据量,避免内存超限2. 使用 Hash 数据结构:
Hash 数据结构比其他数据结构(如字符串或列表)更有效地利用内存,特别是在存储多个字段的数据时,能减少内存开销3. 设置 Key 的过期时间:
通过设置适当的过期时间,确保不再使用的数据能及时被清理,从而释放内存,降低内存使用率
3.3监控和优化
①定期监控内存使用情况:
使用 INFO memory 命令查看内存使用率,及时发现潜在问题
②调整 Redis 配置:根据实际使用情况,考虑调整最大内存配置或优化数据存储方式,以减少内存占用
4.内存回收key
4.1内存回收策略
内存清理策略旨在合理分配 Redis 的有限内存资源,当达到设置的最大内存阈值时,必须选择一种策略来回收键(key)
4.2配置最大内存策略
配置最大内存策略
在配置文件 /etc/redis/6379.conf 中,可以修改 maxmemory-policy 属性来设定内存回收策略。默认情况下,策略是 noeviction,即禁止删除数据
4.3可用的回收策略
1. volatile-lru:
使用最近最少使用(LRU)算法从设置了过期时间的键中淘汰数据。主要针对那些设置了 TTL 的键2. volatile-ttl:
从已设置过期时间的键中挑选即将过期的键进行淘汰,优先移除即将过期的键3. volatile-random:
随机选择设置了过期时间的键进行淘汰,适用于那些设置了 TTL 的键4. allkeys-lru:
使用 LRU 算法从所有键中淘汰数据,而不仅限于设置了过期时间的键5. allkeys-random:
随机从所有键中选择数据进行淘汰,适用于任意键6. noeviction:
禁止淘汰数据。若内存达到最大阈值,后续的写入操作将返回错误
4.4实施建议
①选择合适的策略:
根据应用场景选择最适合的回收策略,确保系统性能与数据存储需求的平衡
②定期监控:监控内存使用情况,确保选择的策略能够有效管理内存,避免出现内存溢出或性能下降的情况