溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis因為開了AOF導致hang住的問題處理

發布時間:2020-03-16 13:30:08 來源:網絡 閱讀:5889 作者:emma_cql 欄目:關系型數據庫

問題描述

業務反饋正常有個接口正常訪問在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


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女