一、 RDB
将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化,完成后对原有文件进行原子替换。
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
#LZF算法压缩RDB文件,消耗CPU,大幅降低文件体积,建议开启
rdbcompression yes
#指定rdb文件
dbfilename dump-8379.rdb
#指定数据目录
dir /usr/local/redis-8379
#磁盘写满或故障切换,可以通过confit set dir {newDir}和config set dbfilename {newFileName}进行动态执行,执行bgsave切换,适用于AOF
1. 手动触发
对应日志:* DB saved on disk
对应日志:
107864:M 23 Nov 12:54:25.775 * Background saving started by pid 180423
180423:C 23 Nov 12:54:27.176 * DB saved on disk
180423:C 23 Nov 12:54:27.177 * RDB: 124 MB of memory used by copy-on-write
107864:M 23 Nov 12:54:27.237 * Background saving terminated with success
2. 自动触发
- save配置,【save m n】,m秒内发生n次修改时,自动触发bgsave
- debug reload命令重新加载redis时,触发save操作
- 执行shutdown命令时,如果没有开启AOF,自动执行bgsave
3. 优缺点
优点:
- 全量快照
- RDB恢复数据远快于AOF
缺点:
-
重量级,成本高
-
RDB版本兼容性问题
注:无法做到实时持久化,一般用户数据冷备和复制传输
4. 文件异常
#Short read or OOM loading DB. Unrecoverable error,aborting now
#执行redis-check-dump检测RDB文件获取错误报告
二、 AOF【append only file】
将Reids的操作日志以追加的方式写入文件,重启时重新执行AOF文件中的命令恢复数据。
解决了数据持久化的实时性。目前已经成为主流持久化方式
appendonly yes
appendfilename "appendonly-8379.aof"
appendfsync everysec
#指定数据目录,同RDB
dir /usr/local/redis-8379
流程:
1.命令写入【aof_buf】缓冲区;append
2.策略同步【AOF文件】;sync
3.文件重写【压缩】;rewrite
4.数据恢复【重启】;load
1.同步策略
appendfsync
- always:命令写入aof_buf,调用系统fsync同步AOF文件。负载较高可能影响性能
- everysec:命令写入aof_buf,调用系统write后返回,独立线程每秒调用fsync同步文件。建议配置,兼顾性能和数据安全性。【秒级数据丢失】
- no:命令写入aof_buf,调用系统write后返回,不调用fsync,由操作系统同步硬盘,周期最长30s。单次同步数据量大,周期不可控,无法保证数据安全性
系统调用write及fsync说明:
- write操作触发延迟写(delayed write),通过内核页缓冲区提高硬盘I/O性能
- fsync针对单个文件做强制硬盘同步,将阻塞直到写入硬盘完成后返回,保证数据持久化
2.重写机制
AOF文件压缩
- 超时数据不再写入文件
- 无效命令不写入文件
- 多条写命令合并
优点:降低文件占用空间;优化重启加载速度
触发方式:
手动触发:调用bgrewriteaof命令
自动触发:
auto-aof-rewrite-min-size 64mb #运行AOF重写时文件最小体积
auto-aof-rewrite-percentage 100#当前AOF文件空间和上次重写后AOF文件空间比值
107864:M 23 Nov 16:50:13.586 * Starting automatic rewriting of AOF on 100% growth
107864:M 23 Nov 16:50:13.587 * Background append only file rewriting started by pid 184991
107864:M 23 Nov 16:50:15.536 * AOF rewrite child asks to stop sending diffs.
184991:C 23 Nov 16:50:15.536 * Parent agreed to stop sending diffs. Finalizing AOF...
184991:C 23 Nov 16:50:15.536 * Concatenating 0.24 MB of AOF diff received from parent.
184991:C 23 Nov 16:50:15.536 * SYNC append only file rewrite performed
184991:C 23 Nov 16:50:15.537 * AOF rewrite: 150 MB of memory used by copy-on-write
107864:M 23 Nov 16:50:15.590 * Background AOF rewrite terminated with success
107864:M 23 Nov 16:50:15.590 * Residual parent diff successfully flushed to the rewritten AOF (0.01 MB)
107864:M 23 Nov 16:50:15.591 * Background AOF rewrite finished successfully
3.文件校验
#Bad file format reading the append only file:xxxx
#AOF文件备份后,执行redis-check-aof --fix修复,修复后使用diff -u对比数据差异,尽量人工修改补全
--------
!!!Warning:short read while loading the AOF file!!!
...
AOF loaded anyway because aof-load-truncated is enabled
#忽视,Redis默认配置aof-load-truncated兼容尾部文件命令写入补全的情况
三、重启加载
1.加载流程
1).AOF持久化开启且存在AOF文件时,优先加载AOF
- DB loaded from append only file: 5.xxx seconds
2).AOF关闭或者AOF不存在时,加载RDB文件
- DB loaded from disk: 5.xxx seconds
3).加载成功后,Redis启动成功
4).AOF/RDB文件存在错误时,Redis启动失败打印错误信息
四、性能优化
持久化一般为影响Redis性能的主要原因
1.主线程阻塞-fork操作
Redis做RDB或AOF重写时,执行fork操作,复制父进程的内存空间页表【10GB复制20MB,一般每GB耗时20ms左右】阻塞主进程。通过info stats→latest_fork_usec获取最近一次fork微秒耗时
优化:
- 优先使用物理机或者高效fork操作的虚拟化技术,避免使用Xen等
- 控制Redis实例最大可用内存,一般控制在10GB以内
- Linux内存分配策略优化
- 降低fork频率,如放宽AOF自动触发时机,尽量避免全量复制
2.主线程阻塞-AOF追加阻塞
独立线程执行fsync同步硬盘,当系统硬盘资源繁忙时,会造成Redis主线程阻塞
流程:
1)主线程写入AOF缓冲区
2)如每秒执行fsync,并记录同步时间
3)主线程对比上次AOF同步时间:距上次同步成功时间2s内,主线程返回;超过2s,主线程阻塞直到同步完成
问题:
- everysec配置最多可能丢失2s数据
- 系统fsync缓慢,会导致Redis主线程阻塞影响效率
常见问题:
- AOF阻塞日志:
* Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.
- aof_delayed_fsync指标累加
- 磁盘高负载问题排查
优化:磁盘负载
3.子进程开销
3.1 CPU
CPU密集操作【通常单核接近90%】,将进程数据分批写入文件。
优化:
- 尽量确保CPU资源与父进程不会资源竞争
- 多实例环境下,尽量确保同一时刻只有一个子进程执行重写工作
3.2 内存
1.子进程通过写时复制【copy-on-write】与父进程共享内存页,优化避免了双倍内存占用。父进程处理写请求时对需要修改的页创建副本
2.内存消耗监控。
RDB重写日志。如:【RDB: 124 MB】
AOF重写日志。如:【AOF rewrite: 150 MB+rewritten AOF (0.01 MB)】
优化:
- 避免在大量写入时做子进程重写操作,会导致父进程维护大量页副本消耗内存
- 同上
- 关闭THP(Transparent Huge Pages),【4k→2MB】大幅增加重写期间副本内存消耗
3.3 硬盘
优化:
- 磁盘负载资源保证【服务磁盘隔离/高性能磁盘】
- 开启no-appendfsync-on-rewrite,在AOF重写期间不做fsync操作默认关闭。注:极端情况下可能丢失整个AOF重写期间的数据
注:多实例手动完成AOF重写串行化