Docker での Redis 接続の急増をトラブルシューティングした実践的な記録

Docker での Redis 接続の急増をトラブルシューティングした実践的な記録

土曜日、本番サーバー上の Redis サーバーが利用できなくなり、エラー メッセージは次のようになりました。

ステータスは利用できず、バックグラウンド チェッカーが復元されるまで使用できません。ストリームの予期しない終了。期待されるタイプは「ステータス」です

下の図に示すように、6300 は Redis サーバーが実行されるポートです。

このような問題に遭遇したのは初めてでした。おそらく Redis がダウンしているのだろうと思い、telnet ip+port を使用しました。正常に動作していることがわかったので、redis を入力して現在の接続状態を確認することを考えました。ざっと見たところ、その数は1,903個にも上りました。

そこで、コードによって作成された redis 接続が多すぎることが原因だと思い、コードを確認しました。

redis は 1 か所のみに作成され、サービス登録時にも実行されることがわかります。つまり、アプリケーションの起動時に 1 回だけ実行されます。その後、プロジェクト全体が検索されましたが、redis の初期化と呼ばれる場所は他にありませんでした。

納得できません。Redis でデータを読み書きするたびに接続が作成されるということですか?頻繁に読んだり書いたりすることと関係があるのでしょうか?いつもうまくいかない気がするので、テストコードを作成してテストします。

ローカルに redis 環境を構築します。テストする前に、接続数を確認します。現在、接続数は 1 つだけであり、これが現在の cmd 接続クライアントです。これは正常です。

テストを開始し、プログラムを実行します。コードは接続オブジェクトを作成し、合計 1000 回の書き込みと 1000 回の読み取りをテストします。

接続をどのようにテストしても、常に 6 つの接続があります。つまり、プログラムは最大 5 つの接続 (主にスレッド プール) を作成します。

したがって、このコードの基本的な保存と読み取りには問題はまったくありません。

しかし、本番サーバーでは Docker 経由で約 6 つのアプリケーションが実行されていたため、コードのトラブルシューティングを完全にあきらめたわけではありません。それらはすべて同じ Redis に接続されています。他のアプリケーションが原因でしょうか?

次に、Redis 接続リスト内の任意のポートを介して対応するプロセス情報を直接照会し、それらがどのアプリケーションであるかを確認します。

Linux では、ネットワーク ポート番号を照会することでプロセス情報が表示されます。

netstat -atunlp | grep 60852 

まず、このポートに対応する IP を確認します。たとえば、最初の IP は 172.17.0.1 です。 Docker に精通している学生であれば、この IP が Docker ゲートウェイ IP であることを知っておく必要があります。コンテナ内のプログラムはすべて、このゲートウェイ IP を介してホスト マシンと通信します。 ifconfig を通じて docker のゲートウェイ IP を見つけることができます。2 番目の 172.17.0.3:6379 は redis のコンテナ IP です。

この時点では、どのコンテナと接続を確立するかのプログラムが見つかりません。

最も愚かな方法は、コンテナに一つずつ入力することです。つまり、docker exec –it test /bin/bash を実行して、現在のコンテナのネットワーク接続ステータスを確認します。これは非常に面倒で、一連のコマンドを実行するために多くのコンポーネントをインストールする必要があります。

別の方法は、lsof コマンドを使用することです。このコマンドが利用できない場合はインストールする必要があります。このプロセスを通じてすべてのネットワーク接続を見つけることができます。

たとえば、メインプロセスは docker であり、その pid は 582251 であることがわかりました。

lsof -i |grep 582251またはlsof -i -p 582251

結果は下図の通りです。右側に実際に表示されるのは特定の IP です。この IP は Docker コンテナの特定の IP アドレスです。

すべての IP とポートがわかったので、コマンドの実行結果をダウンロードできます。

まず、各コンテナに対応する IP を見つけます。

docker examine name |grep IPAddress //name コンテナ名またはID 

各 IP を見つけたら、ダウンロードしたすべてのネットワーク接続情報に基づいて統計を収集し、どの IP に最も多くの接続があるかを確認します。接続が最も多い IP には問題があるはずです。

次に、この IP に対応するコンテナにデプロイされたプログラムを見つけ、redis の設定を確認しました。スレッドプールが 200 に設定されていることがわかりました。

さらに、github を通じて、CSRedisCore にも preheat という予熱メカニズムがあり、そのデフォルト値は 5 つの予熱接続であることがわかりました。

スレッド プールは 200 に設定されており、さらに 5 つの接続用の予熱メカニズムがあります。200 * 5 = 1000 が作成されるかどうかはわかりません。時間があるときにソースコードを注意深く研究します。これは現時点では単なる推測です。

redis を poolsize=5、preheat=false に変更しました。スレッド プールには 5 つのスレッドがあり、予熱機構はオフになっています。

接続設定を変更し、アプリケーション サーバーと Redis サーバーを再起動した後 (確立された接続を完全にクリアするため)、接続数は減少しましたが、それほど大きな減少ではありませんでした。その後、Redis のアイドル時間が長すぎるため、接続プールが多くの接続を維持し、解放されないことが判明しました。

タイムアウトを30秒に設定しました

CONFIG SET timeout 30 を実行します (単位は秒です。この方法は一時的な変更のみであり、現在の操作に有効です。長期的な効果を得るには、Redis 構成ファイルを変更することを忘れないでください)

次に接続数を確認します。接続数は一度に大幅に減少します。

要約:

1. Redis 接続が劇的に増加した場合、まずは自分のアプリケーションに問題があるかどうか調べます。たとえば、接続プールが大きすぎることと、デフォルトの予熱メカニズムに問題があることがわかりました。また、接続を作成するときにコード レベルが複数回トリガーされていないかどうかを確認してください。トリガーされている場合は、修正する必要があります。場所が複数回呼び出されるかどうかに応じて、インスタンスは注入によって作成されるようになりました。

2. 接続アイドル タイムアウトなどの Redis サーバー構成を変更します。最大接続数やデフォルト値も確認できます。

これで、Docker で Redis 接続が急増する問題のトラブルシューティングに関するこの記事は終了です。Docker で Redis 接続が急増する問題のトラブルシューティングに関する関連コンテンツの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Redis メモリの異常な増加のトラブルシューティング手順の実践記録
  • RedisはLuaスクリプトを呼び出し、それを素早く使用します
  • JavaによるRedisクラスタのコード呼び出しと問題解決
  • ノード上のRedis呼び出し最適化例の詳細な説明
  • Redis を介して RPC リモート メソッド呼び出しを実装する (複数のプログラミング言語をサポート)
  • RedisがQRコードを呼び出すときの継続的な更新の分析

<<:  MySQL で union all を使用してユニオンソートを取得する方法

>>:  VueRouterルーティングの詳細な説明

推薦する

クラウドネイティブテクノロジーKubernetesスケジューリングユニットポッドの使用の詳細な説明

k8s の最小のスケジューリング単位 --- pod前回の記事では、k8s が解決できる問題を簡単に...

DD DT DLタグの使用例

通常は <ul><li> タグを使用しますが、dd タグと dt タグも便利...

Sublime / vscode による HTML コード生成の迅速な実装

目次基本的なHTML構造div とクラス名のショートカット キーを生成するクラス名を持つdiv ID...

IE のテキストモード! DOCTYPE の役割の紹介

前の記事で説明したフォームの自動入力の問題を解決した後、新しい問題が発生しました。ページの一部のスタ...

すべてのブラウザとの完全な互換性を実現するために最適なプリセットを選択してください

各ブラウザの select タグのプロパティと各ブラウザのサポートが多少異なるため、各ブラウザでの選...

Jenkinsはマイクロサービスをパッケージ化してDockerイメージを構築し、実行します。

目次環境の準備始める1. GitLabリモートリポジトリがマイクロサービスプロジェクトを作成する2....

Linuxのip netnsコマンドを使用してネットワークポートを分離し、IPアドレスを設定します。

1. 分離マーカーを追加します。 ip netns add fd 2. 指定されたネットワーク カ...

Linux でスペースを含むファイルを削除する (ディレクトリではない)

日常業務では、スペースのないファイルに遭遇することがよくあります。これにより、削除操作がはるかに簡単...

異なるインデックスを更新してMySQLのデッドロックルーチンを解決する

前回の記事では、ソース コードを使用してロック関連の情報をデバッグする方法を紹介しました。ここでは、...

MySQL ロック(テーブルロック、行ロック、共有ロック、排他ロック、ギャップロック)の詳細な説明

現実世界では、鍵は外の世界から身を隠したいときに使用するツールです。コンピュータでは、複数のプロセス...

ウェブページのカスタム選択ボックス選択

選択ドロップダウン リスト フォームは誰もがよく知っているかもしれませんが、デフォルトのドロップダウ...

MySQLインジェクションバイパスフィルタリング技術の概要

まず、GIF 操作を見てみましょう。ケース1: スペースがフィルタリングされるスペースの代わりに角括...

node.js が大規模プロジェクトに適さない理由

目次序文1. アプリケーションコンポーネント2. アプリケーションの種類3. アプリケーションサービ...

複数クリックを防ぐVueの実践

通常、クリック イベントは、メッセージ リマインダーのさまざまな状況に分割されます。これらが処理され...