??斗地主捕鱼电竞提现秒到 广告位招租 - 15元/月全站展示
??支付宝搜索579087183领大额红包 ??伍彩集团官网直营彩票
??好待遇→招代理 ??伍彩集团官网直营彩票
??络茄网 广告位招租 - 15元/月全站展示
Redis因为开了AOF导致hang住的问题处理

转载   emma_cql   2018-09-14   浏览量:30


问题描述

业务反馈正常有个接口正常访问在100ms以内,有时候调用时长会要10多s,根据业务提供的时间查redis日志,以现有如下记录:

8788:M 24 Aug 01:21:26.008 * 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.
8788:M 24 Aug 01:21:45.006 * 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.

查看redis aof相关配置

127.0.0.1:6390> config get *append*
1) "no-appendfsync-on-rewrite"
2) "yes"
3) "appendfsync"
4) "everysec"
5) "appendonly"
6) "yes"


查看rdb的配置:

127.0.0.1:6390> config get save
1) "save"
2) ""

 

 查看redis的版本:

 127.0.0.1:6390> info server
# Server
redis_version:3.2.4

 

故障分析

打开AOF持久化功能后, Redis处理完每个事件后会调用write(2)将变化写入kernel的buffer,如果此时write(2)被阻塞,Redis就不能处理下一个事件。

Linux规定执行write(2)时,如果对同一个文件正在执行fdatasync(2)将kernel buffer写入物理磁盘,或者有system wide sync在执行,write(2)会被Block住,整个Redis被Block住。

如果系统IO繁忙,比如有别的应用在写盘,或者Redis自己在AOF rewrite或RDB snapshot(虽然此时写入的是另一个临时文件,虽然各自都在连续写,但两个文件间的切换使得磁盘磁头的寻道时间加长),就可能导致fdatasync(2)迟迟未能完成从而Block住write(2),Block住整个Redis。

为了更清晰的看到fdatasync(2)的执行时长,可以使用”strace -p (pid of redis server) -T -e -f trace=fdatasync”,但会影响系统性能。

Redis提供了一个自救的方式,当发现文件有在执行fdatasync(2)时,就先不调用write(2),只存在cache里,免得被Block。但如果已经超过两秒都还是这个样子,则会硬着头皮执行write(2),即使redis会被Block住。

此时那句要命的log会打?。骸癆synchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.”

之后用redis-cli INFO可以看到aof_delayed_fsync的值被加1。

因此,对于fsync设为everysec时丢失数据的可能性的最严谨说法是:如果有fdatasync在长时间的执行,此时redis意外关闭会造成文件里不多于两秒的数据丢失。

如果fdatasync运行正常,redis意外关闭没有影响,只有当操作系统crash时才会造成少于1秒的数据丢失。

 

 

解决方法

方法一:关闭aof

这个方法需要和业务确认是否可行,个人认为如果采用redis主从+sentinel方式的话主节点挂了从节点会自己提升为主点,主节点恢复后全量同步一次数据就可以了,关系也不是太大

方法二:修改系统配置

原来是AOF rewrite时一直埋头的调用write(2),由系统自己去触发sync。在RedHat Enterprise 6里,默认配置vm.dirty_background_ratio=10,也就是占用了10%的可用内存才会开始后台flush,而我的服务器有8G内存。

很明显一次flush太多数据会造成阻塞,所以最后果断设置了sysctl vm.dirty_bytes=33554432(32M),问题解决。

然后提了个issue,AOF rewrite时定时也执行一下fdatasync嘛, antirez回复新版中,AOF rewrite时32M就会重写主动调用fdatasync。

查看一下系统内核参数

>sysctl -a | grep dirty_background_ratio
vm.dirty_background_ratio = 10
>sysctl -a | grep vm.dirty_bytes
vm.dirty_bytes = 0

尝试修改一下配置文件/etc/sysctl.conf,并使配置立即生效

echo "vm.dirty_bytes=33554432" >> /etc/sysctl.conf
sysctl -p

验证修改是否成功

>sysctl -a | grep vm.dirty_bytes
vm.dirty_bytes = 33554432


 参考:

https://ningyu1.github.io/site/post/32-redis-aof/

https://redis.io/topics/latency


转载自://blog.51cto.com/chenql/2175432

招聘 不方便扫码就复制添加关注:程序员招聘谷,微信号:jobs1024


下一篇:

linux系统清除redis的key与数据方法
linux系统清除redis的key与数据方法。
redis.conf配置选项列举说明
redisconf配置选项列举说明。注:REDISCLUSTER之后的配置暂时没有列出来。实在是太多了。
redis 从库数据同步失败——爬坑记
早上上班,发现redis的一个slave节点down了一个。对,没错,不是数据不同步那么简单,连redis服务进程都自动退出了。场景:主从同步模式master-->slave1master-->slave2master-->slave3info状态:slave1,slave2都是state=online,offset=5744884846,lag=1正常状态,slave3是sta
java47: redis
javaredis
redis+spring
redis.properties#redis连接池配置参数redis.pool.maxTotal=200redis.pool.maxIdle=50redis.pool.minIdle=10redis.pool.testOnBorrow=trueredis.pool.testOnReturn=trueredis.pool.fairness=falseredis.pool.maxWaitMillis=
redis相关(搭建和数据落盘)
redis的单实例、主从搭建和数据持久化
基于Redis的MessageQueue队列封装
Redis的链表List可以用来做链表,高并发的特性非常适合做分布式的并行消息传递。左进右出$redis->lPush($key,$value);$redis->rPop($key);以下程序已在生产环境中正式使用?;赗edis的PHP消息队列封装
Redis常用命令-服务器相关命令
Auth验证密码是否正确如:auth“password”ping测试连接是否存活echo在命令行打印一些内容select选择数据库。Redis数据库编号从0~15,我们可以选择任意一个数据库来进行数据的存取。quit退出连接。dbsize返回当前数据库中key的数目。info获取服务器的信息和统计。monitor实时转储收到的请求。configget获取服务器配置信息。如:configgetdir
Redis常用命令-键值相关命令
keys返回满足给定pattern的所有key如:keys*exists确认一个key是否存在如:existsnamedel删除一个keyexpire设置一个key的过期时间(单位:秒)如:expireaddr10move将当前数据库中的key转移到其它数据库中如:moveage1persist移除给定key的过期时间randomkey随机返回key空间的一个keyrename重命名keytype
redis之sorted sets类型及操作
sortedsets类型及操作sortedset是set的一个升级版本,它在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序??梢岳斫馕辛搅械膍ysql表,一列存value,一列存顺序。操作中key理解为zset的名字。和set一样sortedset也是string类型元素的集合,不同的是每个元素都会关联一个double类型的