Redis持久化常见问题

Fork操作

  1. 定义:调用fork函数给当前正在运行的进程创建一个子进程。根据copy-on-write(写时复制)机制,这是一种内核机制,在创建子进程并不发生复制,创建子进程后父子进程共用数据,只有在修改数据是才会创建新的空间。
  2. Redis中需要用到fork操作的相关命令:bgsave,bgrewriteaof,查看上一次fork消耗时间:info stats
  3. 同步操作 - 会对父进程执行的业务造成影响
  4. 与内存量息息相关 - 内存越大,耗时越长,同时也与机器类型相关
  5. 改善fork:
    • 优先使用物理机或者高效支持fork操作的虚拟化技术
    • 控制Redis实例的最大可用内存: maxmemory
    • 合理配置Linux内存分配策略:vm.overcommit_memory=1 。修改sysctl vm.overcommit_memory=1
        0 - 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
       b1 - 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
        2 - 表示内核允许分配超过所有物理内存和交换空间总和的内存
    • 降低fork频率:例如放宽AOP重写的自动触发时机

子进程的开销和优化

  1. CPU
    • 开销: RDB和AOF文件的生成,属于CPU密集型
    • 优化: 不做CPU绑定 ,不和CPU密集型一起部署
  2. 内存
    • 开销: fork内存开销,copy-on-write
    • 优化:echo never > /sys/kernel/mm/transparent_hugepage/enabled
  3. 硬盘
    • 开销:AOF和RDB文件写入,结合iostat,iotop分析
    • 优化:不和高硬盘负载服务部署在一起,根据写入量决定磁盘类型。
  4. 扩展:
    • CPU绑定 - 进程和CPU的绑定是为了让应用获得更好的性能,进程的Affinity属性指明了进程调度器能够把这个进程调度到哪些CPU上。CPU Affinity分为2种,soft affinity和hard affinity。soft affinity仅是一个建议,如果不可避免,调度器还是会把进程调度到其它的CPU上。hard affinity是调度器必须遵守的规则。
    • CPU密集型(CPU-bound),也叫计算密集型,系统运作时CPU的消耗接近100%,I/O读写可以在很短的时间完成,但是CPU的计算任务繁重。多重程序系统中,大部份时间用来做计算、逻辑判断等的程序称之CPU bound,一般而言,CPU bound的程序CPU占用率相当高。
    • I/O密集型指的是系统的CPU性能相对硬盘、内存要好很多,此时,系统运作大部分的状况是CPU在等I/O (硬盘/内存) 的读/写操作,CPU消耗并不高。I/O bound的程序需要大量的I/O操作。
    • Transparent hugepage默认是被开启的以便去改善操作系统的内存管理,但是在某种情况下会造成不可预知的节点重启和性能问题

AOF追加阻塞

  1. 定义:如果AOF文件同步时间与上次同步时间相比大于2s,Redis主进程就会阻塞,等待同步完成;如果AOF文件同步时间与上次同步时间相比小于2s,Redis主进程就会返回。其实这样做的目的是为了保证文件安全性的一种策略。

  2. 问题:

    • 主线程阻塞造成业务受影响
    • 虽然每秒everysec刷盘策略,但是实际上不是丢失1s数据,实际有可能丢失2s数据
  3. 问题定位

    • Redis日志

    • Info Persistence中的aof_delayed_fsync,同步延迟历史总数

参考资料

[1] https://coding.imooc.com/class/151.html

Author: HB
Link: http://www.huangbin.fun/Redis持久化常见问题.html
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.