Redis AOF重写阻塞因素

持久化阻塞


对于开启了持久化功能的Redis节点, 需要排查是否是持久化导致的阻塞。 持久化引起主线程阻塞的操作主要有: fork阻塞、 AOF刷盘阻塞、HugePage写操作阻塞。

 

fork操作


当Redis做RDB或AOF重写时, 一个必不可少的操作就是执行fork操作创建子进程, 对于大多数操作系统来说fork是个重量级错误 虽然fork创建的子进程不需要拷贝父进程的物理内存空间, 但是会复制父进程的空间内存页表。 例如对于10GB的Redis进程, 需要复制大约20MB的内存页表, 因此fork操作耗时跟进程总内存量息息相关, 如果使用虚拟化技术, 特别是Xen虚拟机, fork操作会更耗时。

fork耗时问题定位: 对于高流量的Redis实例OPS可达5万以上 如果fork操作耗时在秒级别将拖慢Redis几万条命令执行, 对线上应用延迟影响非常明显。 正常情况下fork耗时应该是每GB消耗20毫秒左右。 可以在info stats统计中查latest_fork_usec指标获取最近一次fork操作耗时, 单位微秒。

如何改善fork操作的耗时:
1) 优先使用物理机或者高效支持fork操作的虚拟化技术, 避免使用Xen。
2) 控制Redis实例最大可用内存, fork耗时跟内存量成正比, 线上建议每个Redis实例内存控制在10GB以内。
3) 合理配置Linux内存分配策略, 避免物理内存不足导致fork失败
4) 降低fork操作的频率, 如适度放宽RDB自动触发时机, 避免不必要的全量复制等

 
  1.  

    [root@localhost ~]# /usr/local/redis//bin/redis-cli bgsave
    
    Background saving started
    
    
    
    
    [root@localhost ~]# tail -f /usr/local/redis/redis_6379.log
    
    1320:M 06 May 2020 21:57:12.690 * Background saving started by pid 20322
    
    20322:C 06 May 2020 21:57:12.771 * DB saved on disk
    
    20322:C 06 May 2020 21:57:12.772 * RDB: 4 MB of memory used by copy-on-write
    
    1320:M 06 May 2020 21:57:12.781 * Background saving terminated with success
    
    
    
    [root@localhost ~]# /usr/local/redis/bin//redis-cli info stats | grep la
    
    
    latest_fork_usec:37470

     

 

fork阻塞


fork操作发生在RDB和AOF重写时, Redis主线程调用fork操作产生共享内存的子进程, 由子进程完成持久化文件重写工作。 如果fork操作本身耗时过长, 必然会导致主线程的阻塞。可以执行info stats命令获取到latest_fork_usec指标, 表示Redis最近一次
fork操作耗时, 如果耗时很大, 比如超过1秒, 则需要做出优化调整, 如避免使用过大的内存实例和规避fork缓慢的操作系统等。
 

 

AOF刷盘阻塞


当我们开启AOF持久化功能时, 文件刷盘的方式一般采用每秒一次, 后台线程每秒对AOF文件做fsync操作。 当硬盘压力过大时, fsync操作需要等待, 直到写入完成。 如果主线程发现距离上一次的fsync成功超过2秒, 为了数据安全性它会阻塞直到后台线程执行fsync操作完成。 这种阻塞行为主要是硬盘压力引起, 可以查看Redis日志识别出这种情况, 当发生这种阻塞行
为时, 会打印如下日志:

 
  1.  

    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.

     

也可以查看info persistence统计中的aof_delayed_fsync指标, 每次发生datasync阻塞主线程时会累加。 
 

当开启AOF持久化时, 常用的同步硬盘的策略是everysec, 用于平衡性能和数据安全性。 对于这种方式, Redis使用另一条线程每秒执行fsync同步硬盘。 当系统硬盘资源繁忙时, 会造成Redis主线程阻塞, 如图5-5所示。
                                             

阻塞流程分析:
1) 主线程负责写入AOF缓冲区。
2) AOF线程负责每秒执行一次同步磁盘操作,并记录最近一次同步时间(AOF线程复制统计时间,主线程负责对比和上次时间差)
3) 主线程负责对比上次AOF同步时间:
·如果距上次同步成功时间在2秒内, 主线程直接返回。
·如果距上次同步成功时间超过2秒, 主线程将会阻塞, 直到同步操作完成

通过对AOF阻塞流程可以发现两个问题:
1) everysec配置最多可能丢失2秒数据, 不是1秒。
2) 如果系统fsync缓慢, 将会导致Redis主线程阻塞影响效率。

AOF阻塞问题定位:
1) 发生AOF阻塞时, Redis输出如下日志, 用于记录AOF fsync阻塞导致拖慢Redis服务的行为:

 
  1.  

    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

     

2) 每当发生AOF追加阻塞事件发生时, 在info Persistence统计中,aof_delayed_fsync指标会累加, 查看这个指标方便定位AOF阻塞问题。

 
  1.  

    [root@localhost ~]# /usr/local/redis/bin/redis-cli info | grep aof_delay
    
    aof_delayed_fsync:0

     

3) AOF同步最多允许2秒的延迟, 当延迟发生时说明硬盘存在高负载问题, 可以通过监控工具如iotop, 定位消耗硬盘IO资源的进程。

运维提示
硬盘压力可能是Redis进程引起的, 也可能是其他进程引起的, 可以使用iotop查看具体是哪个进程消耗过多的硬盘资源。

 

HugePage写操作阻塞


子进程在执行重写期间利用Linux写时复制技术降低内存开销, 因此只有写操作时Redis才复制要修改的内存页。 对于开启Transparent HugePages的操作系统, 每次写命令引起的复制内存页单位由4K变为2MB, 放大了512倍, 会拖慢写操作的执行时间, 导致大量写操作慢查询。 例如简单的incr命令也会出现在慢查询中。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis AOF是一种持久化机制,用于将Redis服务器的操作日志以追加的方式记录在磁盘上。引用中提到,当AOF文件的体积变得过大时,Redis可以自动进行AOF重写AOF重写实际上是对当前数据集所需的最小命令集合进行重写,而不是对原有的AOF文件进行写入和读取操作。这个重写过程是在后台进行的,通过fork子进程来执行。重写后的新AOF文件能够恢复当前数据集的状态。 引用中提到,RedisAOF重写程序放在后台子进程中执行的原因是为了避免影响服务器的请求处理能力。通过将AOF重写程序放在后台执行,可以确保服务器能够继续处理请求,而不会被AOF重写过程阻塞。 在Redis服务器中,redisServer结构维护着服务器的状态,而aof_buf域则用来保存等待写入AOF文件的协议文本(RESP)。这些协议文本包含了对键的操作命令,用于记录服务器的操作日志。当需要将操作日志写入AOF文件时,这些协议文本会被写入到AOF缓冲区中,然后由后台的AOF子进程负责将缓冲区中的内容写入到AOF文件中。这种方式可以提高性能,并且减少了直接写入文件的开销。引用中提到了这一点。 综上所述,RedisAOF机制是通过记录操作日志来实现数据持久化的。当AOF文件体积过大时,Redis会自动进行AOF重写,将当前数据集所需的最小命令集合写入一个新的AOF文件中。为了避免影响服务器的请求处理能力,AOF重写过程会在后台执行。通过维护一个AOF缓冲区,Redis可以将待写入的协议文本暂时保存在内存中,然后由后台子进程负责将其写入AOF文件中。这种机制可以提高性能并减少直接写入文件的开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值