ホームページ  >  記事  >  データベース  >  Jedis 使用時の一般的なクライアント例外 (概要)

Jedis 使用時の一般的なクライアント例外 (概要)

青灯夜游
青灯夜游転載
2021-05-28 11:23:102786ブラウズ

この記事では、Redis クライアントの一般的な例外の概要を紹介します (Jedis の記事)。一定の参考値があるので、困っている友達が参考になれば幸いです。

Jedis 使用時の一般的なクライアント例外 (概要)

[はじめに] Jedis は、Java バージョンの Redis のクライアント実装です。 Redis クライアントの使用中、クライアントが不適切に使用されているか、Redis サーバーに問題があるかにかかわらず、クライアントはいくつかの例外に応答します。この記事では、Jedis の使用中に発生する一般的な例外を分析します。 [関連する推奨事項: Redis ビデオ チュートリアル ]

1. 接続プールから接続を取得できません

JedisPool 内の Jedis オブジェクトの数は制限されており、デフォルトは 8 です。ここではデフォルト設定が使用されることを想定しており、8 つの Jedis オブジェクトが占有されて返されない場合、呼び出し元が JedisPool から Jedis を借用したい場合は、待機する必要があります (たとえば、maxWaitMillis>0 が設定されている場合)。 maxWaitMillis 時間以内に Jedis オブジェクトを取得できない場合は、次の例外がスローされます。

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
 …
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
 at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)

別の状況、つまり blockWhenExhausted=false が設定されている場合、呼び出し元がプールにリソースがないことを検出すると、待機せずにすぐに例外がスローされます。 blockWhenExhausted=false の効果。

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
 …
Caused by: java.util.NoSuchElementException: Pool exhausted
 at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)

この問題に関して、議論する必要があるのは、接続プールにリソースがない理由です。リソースが不足している理由はさまざまに考えられます。

1. クライアント: 接続プールには、小さい場合、供給が需要を上回るため、上記のエラーが発生しますが、通常の状況では、JedisPool の処理効率が低下するため、通常の状況ではデフォルトの最大接続数 (8) を超えるだけで十分です。そしてジェダイは十分に高い。

2. クライアント: 接続プールが正しく使用されていません。たとえば、解放されていません。たとえば、次のコードに示すように: JedisPool を定義し、デフォルトの接続プール構成を使用します。

GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);
//向JedisPool借用8次连接,但是没有执行归还操作。
for (int i = 0; i < 8; i++) {
    Jedis jedis = null;
    try {
 jedis = jedisPool.getResource();
 jedis.ping();
    } catch (Exception e) {
 e.printStackTrace();
    }
}

呼び出し元が接続プールから Jedis を借用すると (次のように)、例外がスローされます:

jedisPool.getResource().ping();

3. クライアント: 遅いクエリ操作があります。これらの遅いクエリによって保持されている Jedis オブジェクトは遅く返されるため、プールがいっぱいになります。

4. サーバー: クライアントは正常ですが、Redis サーバーが何らかの理由でクライアント コマンドの実行プロセスをブロックするため、クライアントもこの例外をスローします。この例外には多くの理由があることがわかります。例外の外観に騙されないでください。すべての問題を解決できるマスター キーはありません。開発と運用保守は、継続的に Redis に対する理解を強化し、手がかりをたどって徐々に問題を見つけてください。

2. クライアントの読み取りおよび書き込みタイムアウト

Jedis が Redis を呼び出すときに、読み取りおよび書き込みタイムアウトが発生すると、次の例外が表示されます:

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out

この例外の理由は次のとおりです。

読み取りおよび書き込みのタイムアウトの設定が短すぎます。
コマンド自体は比較的遅いです。
クライアントとサーバー間のネットワークが異常です。
Redis 自体がブロックされています。

3. クライアント接続タイムアウト

Jedis が Redis を呼び出すときに、読み取りおよび書き込みタイムアウトが発生すると、次の例外が表示されます:

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out

Theこの例外の理由は次のとおりです。

接続タイムアウトの設定が短すぎます。
Redis がブロックされているため、tcp-backlog がいっぱいになり、新しい接続が失敗します。
クライアントとサーバー間のネットワークが異常です。

4. クライアント バッファ例外

Jedis が Redis を呼び出すときに、クライアント データ フロー例外が発生すると、次の例外が発生します。

redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.

この例外の理由は次のとおりです:

1. 出力バッファがいっぱいです。たとえば、通常のクライアントの出力バッファを 1M 1M 60 に設定します。

config set client-output-buffer-limit "normal 1048576 1048576 60 slave 268435456 67108864 60 pubsub 33554432 8388608 60"

get コマンドを使用してビッグキー (3M など) を取得すると、この例外が発生します。

2. 長期アイドル接続はサーバーによってアクティブに切断されます。タイムアウト構成設定と、独自の接続プール構成でアイドル状態の検出が必要かどうかを確認できます。

3. 異常な同時読み取りおよび書き込み: Jedis オブジェクトが複数のスレッドによって同時に操作されるため、上記の例外が発生する可能性があります。

5. Lua スクリプトが実行中です

Redis が現在 Lua スクリプトを実行中で、lua-time-limit を超えた場合、Jedis が Redis を呼び出すと、Jedis は次のメッセージを受け取ります。以下例外。この種の問題に対処する方法 (Lua lua-time-limit 構成は前の章で紹介されています)

redis.clients.jedis.exceptions.JedisDataException: BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.

#6. Redis は永続化ファイルをロードしています #Jedis が Redis を呼び出す この時点で、Redis が永続ファイルをロードしている場合は、次の例外が発生します。

redis.clients.jedis.exceptions.JedisDataException: LOADING Redis is loading the dataset in memory

7. Redis によって使用されるメモリが maxmemory 構成を超えています

Jedis が書き込み操作を実行するために Redis を呼び出すとき、Redis によって使用されるメモリが maxmemory 構成を超えている場合、 maxmemory を設定すると、次の例外が発生します。この時点で maxmemory を調整し、メモリ増大の原因を特定する必要があります (maxmemory については前の章で紹介されています)

redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when used memory > &#39;maxmemory&#39;.

8. クライアントの数接続が大きすぎます

クライアント接続の数が maxclients を超える場合、新しく要求された接続で次の例外が発生します:

redis.clients.jedis.exceptions.JedisDataException: ERR max number of clients reached

この時点で、新しいクライアント接続が実行されると、どのコマンドでも、戻り結果は次のようになります:

127.0.0.1:6379> get hello
(error) ERR max number of clients reached

这个问题可能会比较棘手,因为此时无法执行Redis命令,一般来说可以从两个方面进行着手。

1.客户端:如果maxclients参数不是很小的话,应用方的客户端连接数基本不会超过maxclients,通常来看是由于应用方对于Redis客户端使用不当造成的。此时如果应用方是分布式结构的话,可以通过下线部分应用节点(例如占用连接较多的节点),使得Redis的连接数先降下来。从而让绝大部分节点可以正常运行,此时在再通过查找程序bug或者调整maxclients进行问题的修复。

2.服务端:如果此时客户端无法处理,而当前Redis为高可用模式(例如Redis Sentinel和Redis Cluster),可以考虑将当前Redis做故障转移。

此问题不存在确定的解决方式,但是无论从哪个方面进行处理,故障的快速恢复极为重要,当然更为重要的是找到问题的所在,否则一段时间后客户端连接数依然会超过maxclients。

附赠GenericObjectPoolConfig的重要属性

Jedis 使用時の一般的なクライアント例外 (概要)

原文地址:https://mp.weixin.qq.com/s?__biz=MjM5NTk0MTM1Mw==&mid=2650650677&idx=1&sn=cbb1cb9fefdf9641a4a7c775660114e8&chksm=bef9c6b3898e4fa5a31ac6e572dca4c20a37d6c1dcb41004d831b34300c5c9ae0ed8c3a1bb45&scene=21#wechat_redirect

作者:付磊

更多编程相关知识,请访问:编程教学!!

以上がJedis 使用時の一般的なクライアント例外 (概要)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。