RedisはAOFを開いたのでhangが住んでいた問題処理


問題の説明
ビジネスフィードバックは正常にインタフェースが100 ms以内に正常にアクセスし、呼び出し時間が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が多忙である場合、例えば、書き込みディスクに別のアプリケーションがある場合、またはAOF rewriteまたはRDB snapshot(この場合、別の一時ファイルが書き込まれているが、それぞれ連続して書かれているが、2つのファイル間の切り替えによりディスクヘッドのトラッキング時間が長くなる)は、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)を呼び出さずに、Blockされないようにcacheにのみ存在する自救的な方法を提供する.しかし、2秒を超えてもこのままであれば、redisがBlockに住まれてもwrite(2)を無理に実行します.
「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-cli INFOでaof_を見ることができますdelayed_fsyncの値は1加算されます.
したがって、fsyncがeverysecに設定されたときにデータが失われる可能性について最も厳密な言い方は、fdatasyncが長時間実行されている場合、redisが意外に閉じられると、ファイル内の2秒未満のデータが失われることです.
fdatasyncが正常に動作している場合、redisの予期せぬシャットダウンは影響しません.オペレーティングシステムcrashの場合にのみ1秒未満のデータ損失が発生します.
 
 
解決策
方法1:aofを閉じる
この方法は業務と確認が必要であり,個人的にはredis主従+sentinel方式を採用すれば主ノードが掛かってノードから自分で主点に昇格し,主ノードが回復した後に全量一度データを同期すればよいと考えられ,関係もあまり大きくない
方法2:システム構成の変更
もとはAOF rewriteの時にずっと没頭していた呼び出しwrite(2)で、システム自身がsyncをトリガします.RedHat Enterprise 6では、vmがデフォルトで設定.dirty_background_ratio=10、つまり10%の使用可能なメモリを消費してからバックグラウンドflushを開始しますが、私のサーバには8 Gメモリがあります.
一度にflushが多すぎるとブロックするのは明らかなので、sysctl vmを断固として設定しました.dirty_bytes=33554432(32 M)、問題解決.
それからissueを提案して、AOF rewriteの時タイミングもfdatasyncを実行しますか、antirezは新版に返信して、AOF rewriteの時32 Mはアクティブ呼び出し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