redisクリーンアップで超過したメモリ異常を1回記録する
3468 ワード
今日redisの実行状況をチェックすると、そのうちの1つが切れていることがわかりました.redisログを表示すると、実行時に異常が発生してクラッシュが発生したことがわかります.
例外ログ
ぶんせき
ログの分析といくつかの資料の閲覧を通じて、問題はmem_に現れる可能性が高い.usedメモリがmaxmemoryの設定を超え、超過したメモリのクリーンアップがトリガーされると発生します.redisのLRU実装:当mem_usedメモリはmaxmemoryの設定を超えており、すべての読み書き要求に対してredisがトリガーされる.c/freeMemoryIfNeeded(void)関数は、メモリをクリーンアップします.このクリーンアッププロセスは、十分なメモリ領域がクリーンアップされるまでブロックされます. ここでのLRUまたはTTLポリシーは、redisのすべてのkeyではなく、プロファイル内のmaxmemory-samples個のkeyをサンプルプールとしてサンプリングクリーンアップします. maxmemory-samplesはredis-3.0にある.0のデフォルト構成は5であり、増加するとLRUまたはTTLの精度が向上し、redis作成者がテストした結果、この構成が10の場合、完全なLRUの精度に非常に近いことが分かった.
メモリが消費されると、redisが突然大量に追放され、この追放中に正常な読み書き要求がブロックされ、redisが短時間で使用できなくなり、深刻な状況でredisがクラッシュします.逐出qpsの急増が非常に大きい原因:一度に逐出して多くの空間を解放する必要があると閉塞を招く.具体的な原因はmem_tofreeの計算ロジックに問題があります.mem_tofreeは、実際に割り当てられたメモリの総量-AOFバッファに関連するメモリを統計します.このときrehashがあると、一時的にバケツを割り当ててrehashを作ります.この部分のメモリは除外されていませんので、rehashフェーズで計算されたmem_tofreeは大きくなり、1つの時点で大量のkeyを追放する必要があり、追放されたloopはブロックされ、この段階でblock redisの要求があります.
しょり maxmemory-policyポリシーallkeys-randomはできるだけ使用しないでください.このポリシーを使用すると、基本的に毎日この問題が発生します.allkeys-lruを使用して置き換えることができます. はできるだけ実際の需要に応じてredisの許容最大メモリ設定を設定し、redisメモリが許容最大メモリ設定に近い場合、redisクラスタの拡張を行い、redisが頻繁にメモリをクリーンアップすることを避ける.ホストに十分なメモリ容量があることを保証し、メモリ消費量のピークは85%を超えないことが望ましい. ネット上で与えられた処理方案:github上@Rosantaが与えた解決方案:メモリを解放する循環論理の中で最大一定回数実行し、しきい値に達したら追い出さず、次の要求が来た時にもう少し空間を解放する.この案の利点はblock全体のプロセスができず、正常な業務の読み書き要求に影響がないことです.潜在的な問題は、単一書き込みのデータが解放された空間よりも大きく、全体のメモリが低下するのではなく、上昇し続ける可能性があることです.@antirezが与えたシナリオ:同じ反復削除ですが、反復削除の論理の下でメモリが徐々に低下することを保証するフラグが追加されます.上昇している場合は、正常なリクエストをブロックします(メインのメモリサイズをコントロールします).詳細は、次のとおりです.https://github.com/antirez/redis/pull/4583
例外ログ
19952:C 05 Dec 00:14:56.326 * Concatenating 5.79 MB of AOF diff received from parent.
19952:C 05 Dec 00:14:56.438 * SYNC append only file rewrite performed
19952:C 05 Dec 00:14:56.439 * AOF rewrite: 315 MB of memory used by copy-on-write
11263:M 05 Dec 00:14:56.540 * Background AOF rewrite terminated with success
11263:M 05 Dec 00:14:56.540 * Residual parent diff successfully flushed to the rewritten AOF (0.01 MB)
11263:M 05 Dec 00:14:56.540 * Background AOF rewrite finished successfully
=== REDIS BUG REPORT START: Cut & paste starting from here ===
11263:M 05 Dec 00:37:13.096 # Redis 4.0.1 crashed by signal: 11
11263:M 05 Dec 00:37:13.096 # Crashed running the instuction at: 0x491ee2
11263:M 05 Dec 00:37:13.096 # Accessing address: 0x48
11263:M 05 Dec 00:37:13.096 # Failed assertion: (:0)
------ STACK TRACE ------
EIP:
/home/xxx/redis-4.0.1/bin/redis-server *:4109(freeMemoryIfNeeded+0x142)[0x491ee2]
Backtrace:
/home/xxx/redis-4.0.1/bin/redis-server *:4109(logStackTrace+0x29)[0x4679a9]
/home/xxx/redis-4.0.1/bin/redis-server *:4109(sigsegvHandler+0xac)[0x46804c]
/lib64/libpthread.so.0(+0xf370)[0x7faca2fe7370]
/home/xxx/redis-4.0.1/bin/redis-server *:4109(freeMemoryIfNeeded+0x142)[0x491ee2]
/home/xxx/redis-4.0.1/bin/redis-server *:4109(processCommand+0x405)[0x42c3d5]
/home/xxx/redis-4.0.1/bin/redis-server *:4109(processInputBuffer+0x105)[0x43b305]
/home/xxx/redis-4.0.1/bin/redis-server *:4109(aeProcessEvents+0x23d)[0x42648d]
/home/xxx/redis-4.0.1/bin/redis-server *:4109(aeMain+0x2b)[0x42676b]
/home/xxx/redis-4.0.1/bin/redis-server *:4109(main+0x49f)[0x4235ef]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7faca2c38b35]
/home/xxx/redis-4.0.1/bin/redis-server *:4109[0x4238e2]
ぶんせき
ログの分析といくつかの資料の閲覧を通じて、問題はmem_に現れる可能性が高い.usedメモリがmaxmemoryの設定を超え、超過したメモリのクリーンアップがトリガーされると発生します.redisのLRU実装:
メモリが消費されると、redisが突然大量に追放され、この追放中に正常な読み書き要求がブロックされ、redisが短時間で使用できなくなり、深刻な状況でredisがクラッシュします.逐出qpsの急増が非常に大きい原因:一度に逐出して多くの空間を解放する必要があると閉塞を招く.具体的な原因はmem_tofreeの計算ロジックに問題があります.mem_tofreeは、実際に割り当てられたメモリの総量-AOFバッファに関連するメモリを統計します.このときrehashがあると、一時的にバケツを割り当ててrehashを作ります.この部分のメモリは除外されていませんので、rehashフェーズで計算されたmem_tofreeは大きくなり、1つの時点で大量のkeyを追放する必要があり、追放されたloopはブロックされ、この段階でblock redisの要求があります.
しょり