Redisケース実戦分析


【1】ケース1現象:生産システムが運行を開始したばかりの段階で、システムが安定している.しかし、しばらく実行すると、一部の期間のシステムインタフェースの応答が遅くなることが分かった.クライアント・ログを表示すると、次のエラーが発生することがよくあります.
redis.clients.jedis.exception.JedisConnectionException:java.net.SocketTimeoutException:Read time out問題位置決め:slowlogを実行して遅いクエリーログを表示し、大量のkeysコマンド操作を発見し、keysコマンドは大量の同時状況で性能が非常に悪く、生産環境は、できるだけkeysを使用しないようにし、次にkeysを使用するコードを見つけて最適化し、time out問題が解決するまで.
192.168.17.46:6386> slowlog get
 1) 1) (integer) 22
    2) (integer) 1563344158
    3) (integer) 10193
    4) 1) "SET"
       2) "getBatchChapterFiles"
       3) "\x0b\xfa\529:\t489761532B\x02-1J\t48976181... (1293 more bytes)"
 2) 1) (integer) 21
    2) (integer) 1545403066
    3) (integer) 10915
    4) 1) "GET"
       2) "getVolumeChapters#data"

【2】ケース2:生産環境が長時間稼働していると、インタフェースからデータの返却に失敗したり、監視カメラからデータベースの圧力が一時的に増加していることがよく見られます.クライアント・ログを表示すると、redis.clients.jedis.exceptions.JedisConnectionException:Cloud not get a resource from the pool
redisログでエラーが見つかりました:[2489]02 Jun 10:43:42#Error allocating resours for the client
問題の位置付け:client listコマンドを実行すると、多くのclientのidle時間が特に長いことがわかります.構成を確認すると、timeoutとtcp-keepalive(心拍検出)はいずれも有効(いずれも0)であり、Redisサービス側にはサービス側接続が無効になったかどうかを確認する有効なメカニズムがないことが分かった.サーバがクライアントネットワークとフラッシュオフし、tcpが中断すると、この場合のclientはredisサービス側に保持され続け、idle(アイドル)時間特長のclient接続が発生します.解決策:timeoutとtcp-keepaliveを設定して、失効した接続をクリーンアップします.
redis/bin>redis-cli -h 192.168.17.46 -p 6386 info Clients
# Clients
connected_clients:5000                      ---------------  
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

192.168.17.46:6386> CONFIG GET timeout 
1) "timeout"
2) "0"

192.168.17.46:6386> CONFIG GET tcp-keepalive
1) "tcp-keepalive"
2) "0"
192.168.17.46:6386> client list
id=612260747 addr=192.168.17.92:53069 fd=806 name= age=114 idle=21 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping
id=612260593 addr=192.168.41.44:38248 fd=381 name= age=131 idle=61 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get

フィールド定義addr:クライアントのアドレスとポートfd:ソケットで使用されるファイル記述子age:秒で計算された接続時間長idle:秒で計算されたアイドル時間長flags:クライアントflagdb:クライアントが使用しているデータベースIDsub:サブスクリプションチャネル数psub:サブスクリプションモード数multi:トランザクションで実行されるコマンド数qbuf:クエリーバッファの長さ(バイト単位、0はクエリーバッファが割り当てられていないことを示す)qbuf-free:クエリーバッファの空き領域の長さ(バイト単位、0は空き領域がないことを示す)obl:出力バッファの長さ(バイト単位、0は出力バッファが割り当てられていないことを示す)oll:出力リストに含まれるオブジェクトの数(出力バッファに空き容量がない場合、コマンド返信は文字列オブジェクトとしてこのキューにエンキューされます)omem:出力バッファと出力リストに消費されるメモリの合計events:ファイル記述子イベントcmd:最近実行されたコマンド
【3】ケース3:Redisが突然アクセスできなくなり、次のエラーを返します.
redis.client.jedis.exception.JedisDataException:MISCONF Redis is configured to save RDB snapshots,but is currently not able to persist on disk.Commands that may modify the data set are disabled.Please check Redis logs for details about the error問題の位置付け:redisログを表示すると、Cant save in background:fork:Cannot allocate memory Redisメモリのデータをディスクに保存する際に、メインスレッドの偽死を防ぐために、Forkのサブプロセスがこの保存操作を完了するために、このForkのサブプロセスはメインプロセスと同じメモリを割り当てる必要があります.この場合、必要なメモリの2倍になります.この時点で使用可能なメモリが必要なメモリを割り当てるのに十分でない場合、Forkサブプロセスは失敗し、データをディスクに永続化できません.Linuxカーネルパラメータvmを変更する.overcommit_mememeory=1(カーネルが現在のメモリステータスにかかわらず、すべての物理メモリを割り当てることを許可していることを示す)の問題を解決します.
192.168.17.46:6386> CONFIG GET logfile
1) "logfile"
2) "/home/redis02/redis/log/6386.log"