1. ホーム
  2. Redis

Redis の例外と使用法のまとめ

2022-02-10 23:50:27

検索結果に一致するキーを一括削除するには?

redis-cli -p 6380 -a ooxx keys simple_user:* | xargs redis-cli -p 6380 -a ooxx del

redisのハッシュ構造には、数千万個のキーが格納されると推測されます。

取得時にhscanを使用しますが、バージョンが3.2.1以上でないと有効でないことに注意が必要です。

カウント値が512以上の場合はページングが有効になり、それ以外の場合はすべて表示され、カーソル値は0を返します。

コマンドモード

hscan key cursor [MATCH pattern] [COUNT count]

カーソル、0から始まり、カーソル値が0に戻り、探索が完了するまで、新しいカーソルで結果を返す、以下のようなカーソルです。

redis 127.0.0.1:6379> scan 0
1) "17"
2) 1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
   10) "key:7"
   11) "key:1"
redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"

例,一度に1000個の要素を取得する場合

hscan role_logout_log 0 count 1000

----------------------------------

現象:各種リリース、その他のコマンドが動作しない

ログを見る

ServiceException: redis.clients.jedis.exceptions.JedisDataException: ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context
	at com.linguyu.common.db.Redis.publish(Redis.java:1402)
	at com.lingyu.game.service.stat.StatRepository.publish(StatRepository.java:16)
	at com.lingyu.game.service.stat.StatManager.statRealTime(StatManager.java:232)
	at com.lingyu.game.service.job.JobManager.statRealTime(JobManager.java:336)
	at sun.reflect.GeneratedMethodAccessor203.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
	at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	FutureTask.runAndReset(FutureTask.java:308)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:756)
Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context
	at redis.clients.jedis.Protocol.processError(Protocol.java:117)
	Protocol.process(Protocol.java:151)
	Protocol.read(Protocol.java:205) at redis.clients.jedis.Protocol.read(Protocol.java:205)
	at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297)
	at redis.clients.jedis.Connection.getIntegerReply(Connection.java:222)
	at redis.clients.jedis.Jedis.publish(Jedis.java:2601)
	at com.linyu.common.db.Redis.publish(Redis.java:1399)

現象:バックグラウンドのサブスクリプションスレッドが朝方に理由もなく終了し、5時間程度統計や監視ができなくなる。

ログを見る

原因:このエラーは、Redis接続をパブリッシャーとサブスクライバーで共有できないことに起因しています。実際には、パブリッシャー用の接続(または接続のプール)と、サブスクライバースレッド用の専用の接続が必要です。

サブスクライバースレッドが何らかの理由で脱出したため、ブロックされていたサブスクライブ接続が再び使用されるようになり、いったん他のことに使用されると上記の例外が報告され、サブスクライブ接続は他のことに使用できなくなり、さもなければ上記の問題が発生することになります。

参考にしてください。 redis pub sub with jedis , sub crashes with error.

2015-04-13 05:00:00.256 ERROR [Message SubScribe Monitor][SubScribeManager.java:127] - Subscription thread exited for no reason
ServiceException: redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
        at com.lingyu.common.db.Redis.subscribe(Redis.java:1439) ~[Redis.class:?]
        at com.linguyu.common.db.SubScribeManager.run(SubScribeManager.java:125) ~[SubScribeManager.class:?]
        at java.lang.Thread.run(Thread.java:745) [? :1.7.0_65]
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
        at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:198) ~[jedis-2.6.2.jar:?]
        at redis.clients.util.RedisInputStream.read(RedisInputStream.java:180) ~[jedis-2.6.2.jar:?]
        at redis.clients.jedis.Protocol.processBulkReply(Protocol.java:158) ~[jedis-2.6.2.jar:?]
        at redis.clients.jedis.Protocol.process(Prot





try{}catch(Exception e){}で抜け出せそうなんだけど、迷うなぁ~~~。

この記事で調べました。

https://github.com/xetorthio/jedis/issues/932

redis-serverが接続を閉じたため、例外が発生しました。

クライアント出力バッファーリミット

クライアント側のバッファ制御。クライアントとサーバーのやりとりでは、各接続はバッファに関連付けられ、クライアントが受け入れるのを待っている応答をキューに入れるために使用されます。もしクライアントが応答情報を適時に消費できなければ、バッファは継続的にバックログとなり、サーバにメモリ圧迫を与えることになります。バッファが閾値に達した場合、接続は閉じられ、バッファは削除されます。
バッファ制御の種類には、ノーマル -> 通常の接続、スレーブ -> スレーブとの接続、パブサブ -> パブ/サブタイプの接続があり、このタイプの接続では、パブ側がメッセージを集中的にポストするが、サブ側が十分に消費しないことがあるため、しばしば問題が発生します。
コマンド形式:client-output-buffer-limit <class> <hard> <soft> <seconds>" ここで hard はバッファの最大値を示し、閾値に達すると直ちに接続を終了します。
softはquot;許容値"を意味し、秒単位で動作します。バッファ値がsoftを超え、継続時間が秒に達すると接続も直ちに閉じられ、softを超えても秒後にバッファデータがsoftより少なくなると接続は維持されます。
hardとsoftの両方を0に設定すると、バッファ制御は無効になります。通常、hardはsoftより大きいです。

生産ラインでのパラメータ調整(メモリとコンフィグレーションの変更を並行して行う)。

127.0.0.1:6380> CONFIG GET client-output-buffer-limit
クライアント出力バッファーリミット
normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60
127.0.0.1:6380> config set client-output-buffer-limit 'normal 0 0 0 slave 268435456 67108864 60 pubsub 0 0 0 0'
redis.conf
クライアント出力バッファー制限 pubsub 0 0 0

===========================================================

昨日、ロシア地域でバックエンドアクティビティのアップロードにまた失敗しました。バックエンドアクティビティはredos経由で公開されましたが、公開が失敗したことがわかりました。手動でスモールバイトを公開しようとしましたが、ラージバイトが失敗し、情報が表示されない状態になりました。

原因は、イントラネットのLAN転送にパケットサイズの制限があり、一定サイズ以上のパケットは転送できず、接続に失敗してしまうためです。制限をオンにすることで解決します。

=============================================================

6470672人
一人当たり平均、メモリフットプリント887バイト、AOFディスクフットプリント608個、RDBディスクフットプリント344個
ファイルキャッシュがさらにメモリフットプリントの半分を占めるので、約10ギガバイト以上のフットプリントになります

=============================================================

スロークエリで取得

スローログ取得

127.0.0.1:6379> slowlog 
get
 
 1) 1) (integer) 27
    2) (integer) 1417531320
    3) (integer) 24623
    4) 1) "info"

.0.1:6379> slowlog 

 
 1) 1) (integer) 27
    2) (integer) 1417531320
    3) (integer) 24623
    4) 1) "info"


もらう


cmdstat_XXX:calls=XXX,usec=XXX,usecpercall=XXX
10.104.5.98:6379>info commandstats
# Commandstats
cmdstat_get:calls=180608685,usec=470928529,usec_per_call=2.61
cmdstat_set:calls=147550519,usec=562225572,usec_per_call=3.81
cmdstat_del:calls=177224,usec=1643815,usec_per_call=9.28
cmdstat_exists:calls=14130110,usec=31402378,usec_per_call=2.22
cmdstat_incr:calls=1017,usec=3261,usec_per_call=3.21
cmdstat_mget:calls=666034,usec=18069595,usec_per_call=27.13
cmdstat_lpush:calls=103077132,usec=181583996,usec_per_call=1.76
cmdstat_lrange:calls=38777511,usec=138617427,usec_per_call=3.57
cmdstat_ltrim:calls=2056,usec=7622,usec_per_call=3.71
cmdstat_lrem:calls=103075076,usec=579401111,usec_per_call=5.62
cmdstat_zadd:calls=15900133,usec=56515414,usec_per_call=3.55
cmdstat_zincrby:calls=11747959,usec=196212310,usec_per_call=16.70
cmdstat_zrem:calls=257783,usec=1053833,usec_per_call=4.09
cmdstat_zrange:calls=7141527,usec=41950470,usec_per_call=5.87
cmdstat_zrevrangebyscore:calls=10,usec=51489,usec_per_call=5148.90
cmdstat_zcount:calls=16104028,usec=112221789,usec_per_call=6.97
cmdstat_zrevrange:calls=27497771,usec=582807534,usec_per_call=21.19
cmdstat_zscore:calls=8663683,usec=44001575,usec_per_call=5.08
cmdstat_zrank:calls=3,usec=43,usec_per_call=14.33
cmdstat_zrevrank:calls=15906400,usec=68891802,usec_per_call=4.33
cmdstat_hset:calls=10236125,usec=37507245,usec_per_call=3.66
cmdstat_hget:calls=1618802100,usec=2755577270,usec_per_call=1.70
cmdstat_hmset:calls=369619411,usec=4843444966,usec_per_call=13.10
cmdstat_hmget:calls=56015,usec=344231,usec_per_call=6.15
cmdstat_hincrby:calls=170633471,usec=884820311,usec_per_call=5.19
cmdstat_hdel:calls=44233,usec=201881,usec_per_call=4.56
cmdstat_hlen:calls=21724,usec=39834,usec_per_call=1.83
cmdstat_hgetall:calls=311374011,usec=3269118749,usec_per_call=10.50
cmdstat_hexists:calls=70864759,usec=285319509,usec_per_call=4.03
cmdstat_incrby:calls=2942269,usec=42251052,usec_per_call=14.36
cmdstat_decrby:calls=2050,usec=3616,usec_per_call=1.76
cmdstat_rename:calls=6472,usec=33326,usec_per_call=5.15
cmdstat_keys:calls=3636,usec=1974535725,usec_per_call=543051.62
cmdstat_dbsize:calls=9,usec=15,usec_per_call=1.67
cmdstat_ping:calls=46747,usec=61691,usec_per_call=1.32
cmdstat_type:calls=1,usec=3,usec_per_call=3.00
cmdstat_psync:calls=1,usec=3164,usec_per_call=3164.00
cmdstat_replconf:calls=21643928,usec=25568830,usec_per_call=1.18
cmdstat_info:calls=4,usec=3669,usec_per_call=917.25
cmdstat_config:calls=2,usec=37,usec_per_call=18.50
cmdstat_subscribe:calls=45505,usec=476993,usec_per_call=10.48
cmdstat_publish:calls=34572782,usec=262298295,usec_per_call=7.59
cmdstat_client:calls=3,usec=47628,usec_per_call=15876.00
cmdstat_eval:calls=20

メトリクスが示すところ。

  • すべてのスローログエントリーに一意のプログレッシブ識別子。 slowlogの実行番号

  • ログに記録されたコマンドが処理されたunixタイムスタンプ。

  • 実行に要した時間(マイクロ秒) 平均所要時間(マイクロ秒はミリ秒ではなくマイクロセコンドに変換されることに注意)。

  • コマンドの引数を構成する配列です。

slowlog len スローログの総数を取得します。

slowlog get number スローログの数を番号で取得する。

=======================================

commandstatsセクションには、コマンドの実行回数、コマンドにかかったCPU時間(ミリ秒単位)、各コマンドの平均実行CPU時間など、さまざまな種類のコマンドの実行統計が記録されます。 (内 ミリ秒 ) といった具合です。コマンドの種類ごとに、次のような形式の情報を1行ずつ追加していきます。

<span style="color:#000000">CONFIG SET dir /data/redis/</span>

10.104.5.98:6379>info commandstats
# Commandstats
cmdstat_get:calls=180608685,usec=470928529,usec_per_call=2.61
cmdstat_set:calls=147550519,usec=562225572,usec_per_call=3.81
cmdstat_del:calls=177224,usec=1643815,usec_per_call=9.28
cmdstat_exists:calls=14130110,usec=31402378,usec_per_call=2.22
cmdstat_incr:calls=1017,usec=3261,usec_per_call=3.21
cmdstat_mget:calls=666034,usec=18069595,usec_per_call=27.13
cmdstat_lpush:calls=103077132,usec=181583996,usec_per_call=1.76
cmdstat_lrange:calls=38777511,usec=138617427,usec_per_call=3.57
cmdstat_ltrim:calls=2056,usec=7622,usec_per_call=3.71
cmdstat_lrem:calls=103075076,usec=579401111,usec_per_call=5.62
cmdstat_zadd:calls=15900133,usec=56515414,usec_per_call=3.55
cmdstat_zincrby:calls=11747959,usec=196212310,usec_per_call=16.70
cmdstat_zrem:calls=257783,usec=1053833,usec_per_call=4.09
cmdstat_zrange:calls=7141527,usec=41950470,usec_per_call=5.87
cmdstat_zrevrangebyscore:calls=10,usec=51489,usec_per_call=5148.90
cmdstat_zcount:calls=16104028,usec=112221789,usec_per_call=6.97
cmdstat_zrevrange:calls=27497771,usec=582807534,usec_per_call=21.19
cmdstat_zscore:calls=8663683,usec=44001575,usec_per_call=5.08
cmdstat_zrank:calls=3,usec=43,usec_per_call=14.33
cmdstat_zrevrank:calls=15906400,usec=68891802,usec_per_call=4.33
cmdstat_hset:calls=10236125,usec=37507245,usec_per_call=3.66
cmdstat_hget:calls=1618802100,usec=2755577270,usec_per_call=1.70
cmdstat_hmset:calls=369619411,usec=4843444966,usec_per_call=13.10
cmdstat_hmget:calls=56015,usec=344231,usec_per_call=6.15
cmdstat_hincrby:calls=170633471,usec=884820311,usec_per_call=5.19
cmdstat_hdel:calls=44233,usec=201881,usec_per_call=4.56
cmdstat_hlen:calls=21724,usec=39834,usec_per_call=1.83
cmdstat_hgetall:calls=311374011,usec=3269118749,usec_per_call=10.50
cmdstat_hexists:calls=70864759,usec=285319509,usec_per_call=4.03
cmdstat_incrby:calls=2942269,usec=42251052,usec_per_call=14.36
cmdstat_decrby:calls=2050,usec=3616,usec_per_call=1.76
cmdstat_rename:calls=6472,usec=33326,usec_per_call=5.15
cmdstat_keys:calls=3636,usec=1974535725,usec_per_call=543051.62
cmdstat_dbsize:calls=9,usec=15,usec_per_call=1.67
cmdstat_ping:calls=46747,usec=61691,usec_per_call=1.32
cmdstat_type:calls=1,usec=3,usec_per_call=3.00
cmdstat_psync:calls=1,usec=3164,usec_per_call=3164.00
cmdstat_replconf:calls=21643928,usec=25568830,usec_per_call=1.18
cmdstat_info:calls=4,usec=3669,usec_per_call=917.25
cmdstat_config:calls=2,usec=37,usec_per_call=18.50
cmdstat_subscribe:calls=45505,usec=476993,usec_per_call=10.48
cmdstat_publish:calls=34572782,usec=262298295,usec_per_call=7.59
cmdstat_client:calls=3,usec=47628,usec_per_call=15876.00
cmdstat_eval:calls=20

redis.2.8.23 バージョンをデプロイすると、2 つの警告が表示されます。

[32555] 09 Nov 12:06:37.804 # WARNING あなたはカーネルでTransparent Huge Pages (THP) サポートを有効にしています。この問題を解決するには、root で 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' コマンドを実行し、これを /etc/rc に追加してください。THPを無効にした後は、Redisを再起動する必要があります。
[32555] 09 Nov 12:06:37.804 # 警告: /proc/sys/net/core/somaxconn に低い値 128 が設定されているため、TCP バックログ設定 511 を強制することができない。

プロンプトに従うだけです。

echo never > /sys/kernel/mm/transparent_hugepage/enabled

echo 511 > /proc/sys/net/core/somaxconn

を追加し、/etc/rc.local に追加します。 

==============================================

Redis "MISCONF RedisはRDBスナップショットを保存するように構成されていますが、現在ディスクに永続化することはできません。

1. 設定なし vm.overcommit_memory=1  

2. ディスク容量不足

3. rdb ファイルが削除された、解決策 

<span style="color:#000000">CONFIG SET dir /data/redis/</span>