Redis持久化

一、 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. 手动触发
  • save命令:阻塞服务【已废弃】

对应日志:* DB saved on disk

  • bgsave命令:fork子进程阶段阻塞

对应日志:

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重写串行化

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值