Redis-Redisスレッドモデル(グラフィック)

Redisスレッドモデル

ファイルイベントハンドラー

RedisはReactorモデルに基づくネットワークイベントプロセッサを開発しました。このプロセッサはファイルイベントプロセッサと呼ばれます。それは4つの部分で構成されています:複数のソケット、IO多重化プログラム、ファイルイベントディスパッチャー、およびイベントハンドラー。ファイルイベントディスパッチャーキューの消費はシングルスレッドであるため、Redisはシングルスレッドモデルと呼ばれます。
ここに画像の説明を挿入

メッセージ処理フロー

  • ファイルイベントハンドラーは、I / O多重化プログラムを使用して複数のソケットを同時に監視し、ソケットによって現在実行されているタスクに従って、ソケットに異なるイベントハンドラーを関連付けます。
  • 監視対象のソケットが接続応答(受け入れ)、読み取り(読み取り)、書き込み(書き込み)、閉じる(閉じる)などの操作を実行する準備ができると、操作に対応するファイルイベントが生成され、ファイルイベントハンドラーは、ソケットに関連付けられたイベントハンドラーを呼び出して、これらのイベントを処理します。

複数のファイルイベントが同時に発生する可能性がありますが、I / O多重化プログラムは常にすべてのイベント生成ソケットをキューにプッシュし、次にこのキューを順番に(順次)押します。同期して、一度に1つのソケット、ソケットはファイルイベントディスパッチャーに送信されます:前のソケットによって生成されたイベントが処理されるとき(ソケットは、イベントに関連付けられたイベントハンドラーによって実行されます)完了)、I / O多重化プログラムは次のソケットをファイルイベントディスパッチャーに送信し続けます。

I / O多重化プログラムの実現

RedisのI / O多重化プログラムのすべての機能は、select、epoll、evport、kqueue I / O多重化関数ライブラリをパッケージ化することによって実現されます。各I / O多重化関数ライブラリはRedisにありますソースコードは、ae_select.c、ae_epoll.c、ae_kqueue.cなどの個別のファイルに対応しています。

Redisは各I / O多重化関数ライブラリに同じAPIを実装しているため、I / O多重化プログラムの基本的な実装は交換可能です。次
ここに画像の説明を挿入
図に示すように、RedisはI / O多重化にあります多重化プログラムの実装では、#includeマクロを使用して、ソースコード内の対応するルールを定義します。プログラムは、コンパイル時にRedisのI / O多重化として、システムで最高のパフォーマンスを持つI / O多重化関数ライブラリを自動的に選択します。プログラムの基本的な実装:

/* Include the best multiplexing layer supported by this system.
 * The following should be ordered by performances, descending. */
#ifdef HAVE_EVPORT
#include "ae_evport.c"
#else
    #ifdef HAVE_EPOLL
    #include "ae_epoll.c"
    #else
        #ifdef HAVE_KQUEUE
        #include "ae_kqueue.c"
        #else
        #include "ae_select.c"
        #endif
    #endif
#endif

ファイルイベントの種類

I / O多重化プログラムは、複数のソケットのae.h / AE_READABLEイベントとae.h / AE_WRITABLEイベントを監視できます。これら2つのタイプのイベントとソケット操作の対応は次のとおりです。

  • ソケットが読み取り可能になるとき(クライアントがソケットで書き込み操作を実行するか、クローズ操作を実行するとき)、または新しい受け入れ可能なソケットが表示されたとき(クライアントからサーバーへの待機ソケット)接続操作を実行します)、ソケットはAE_READABLEイベントを生成します
  • ソケットが書き込み可能になると(クライアントがソケットで読み取り操作を実行する)、ソケットはAE_WRITABLEイベントを生成します。I / O多重化プログラムにより、サーバーはソケットのAE_READABLEイベントとAE_WRITABLEイベントを同時にリッスンできます。ソケットがこれら2つのイベントを同時に生成した場合、ファイルイベントディスパッチャーはAE_READABLEイベントを優先し、AE_READABLEイベントが処理されるまで待機しますその後、AE_WRITABLEイベントが処理されます。つまり、ソケットが読み取りと書き込みの両方が可能な場合、サーバーは最初にソケットを読み取り、次にソケットに書き込みます。

ファイルイベントハンドラー

Redisは、ファイルイベント用に複数のプロセッサを作成しました。これらのイベントプロセッサは、さまざまなネットワーク通信要件を実装するために使用されます。一般的に使用されるプロセッサは次のとおりです。

  • サーバーに接続されている各クライアントに応答するには、サーバーは、リスニングソケットの接続応答プロセッサを関連付ける必要があります。
  • クライアントからコマンド要求を受信するために、サーバーはクライアントソケットのコマンド要求プロセッサを関連付ける必要があります。
  • コマンドの実行結果をクライアントに返すために、サーバーはクライアントソケットのコマンド応答プロセッサを関連付ける必要があります。

接続応答プロセッサ

networking.cのacceptTcpHandler関数は、Redisの接続応答プロセッサです。このプロセッサは、サーバーのリスニングソケットに接続するクライアントに応答するために使用され、sys / socket.h / accept関数のラッパーとして実装されます。

Redisサーバーが初期化されると、プログラムは接続応答プロセッサをサーバーの待機ソケットのAE_READABLEイベントに関連付けます。クライアントがsys / socket.h / connect関数を使用してサーバーの待機ソケットに接続すると、図に示すように、ソケットはAE_READABLEイベントを生成し、接続応答プロセッサをトリガーして実行し、対応するソケット応答操作を実行します。
ここに画像の説明を挿入

コマンド要求ハンドラ

networking.cのreadQueryFromClient関数はRedisコマンドリクエストプロセッサです。このプロセッサは、クライアントから送信されたコマンドリクエストの内容をソケットから読み取る役割を果たします。これは、特にunistd.h / read関数のパッケージとして実装されています。

クライアントが接続応答プロセッサを介してサーバーに正常に接続すると、サーバーはクライアントソケットのAE_READABLEイベントをコマンド要求プロセッサに関連付けます。クライアントがコマンド要求をサーバーに送信すると、ソケットは図に示すように、AE_READABLEイベントを生成し、コマンドをトリガーしてプロセッサに実行を要求し、対応するソケット読み取り操作を実行します。
ここに画像の説明を挿入
クライアントがサーバーに接続するプロセス全体の間、サーバーは常にクライアントソケットのAE_READABLEイベント関連コマンドをプロセッサに要求します。

コマンド応答プロセッサー

networking.cのsendReplyToClient関数はRedisコマンド応答プロセッサです。このプロセッサは、サーバーがunistd.h / write関数のパッケージとして実装されているソケットを介してクライアントにコマンドを実行した後に取得したコマンド応答を返します。

サーバーにクライアントに送信するコマンド応答がある場合、サーバーはクライアントソケットのAE_WRITABLEイベントをコマンド応答プロセッサに関連付けます。クライアントがサーバーからコマンド応答を受信する準備ができると、AE_WRITABLEイベントが生成されます、図に示すように、コマンド応答プロセッサの実行をトリガーし、対応するソケット書き込み操作を実行します。
ここに画像の説明を挿入
コマンド応答が送信されると、サーバーはコマンド応答プロセッサとクライアントソケットのAE_WRITABLEイベントの関連付けを解除します

完全なクライアントサーバー接続イベントの例

Redisサーバーが動作していると仮定すると、このサーバーのリスニングソケットのAE_READABLEイベントはリスニング状態にあり、イベントに対応するプロセッサは接続応答プロセッサです。

この時点でRedisクライアントがRedisサーバーへの接続を開始すると、リスニングソケットがAE_READABLEイベントを生成し、接続応答プロセッサの実行をトリガーします。プロセッサはクライアントの接続要求に応答し、クライアントソケットを作成します。そして、クライアントの状態と、クライアントソケットのAE_READABLEイベントをコマンドリクエストプロセッサに関連付けて、クライアントがコマンドリクエストをメインサーバーに送信できるようにします。

その後、クライアントはコマンドリクエストをRedisサーバーに送信し、クライアントソケットはAE_READABLEイベントを生成し、コマンドをトリガーしてプロセッサに実行を要求し、プロセッサはクライアントのコマンドコンテンツを読み取り、関連するプログラムに渡して実行します。

コマンドを実行すると、対応するコマンド応答が生成されます。これらのコマンド応答をクライアントに送信するために、サーバーはクライアントソケットのAE_WRITABLEイベントをコマンド応答プロセッサに関連付けます。クライアントがコマンド応答を読み取ろうとすると、クライアントはエンドソケットはAE_WRITABLEイベントを生成し、これがコマンド応答プロセッサの実行をトリガーします。コマンド応答プロセッサがすべてのコマンド応答をソケットに書き込むと、サーバーはAE_WRITABLEイベントとクライアントソケットのコマンド応答プロセッサを解放しますの関係。
ここに画像の説明を挿入

思考の問題

Q:
Redisのシングルスレッドモデルがなぜ効率的であるのですか?
A:

  1. 純粋なメモリアクセス:データはメモリに格納され、メモリの応答時間は約100ナノ秒で、これは1秒あたりのRedisの1兆レベルのアクセスの重要な基準です。
  2. ノンブロッキングI / O:RedisはI / O多重化テクノロジーの実装としてepollを使用し、Redis独自のイベント処理モデルは、epollの接続、読み取り、書き込み、終了をI / Oではなく時間に変換します時間の無駄が多すぎます。
  3. シングルスレッドは、スレッドの切り替えと競合状態の消費を回避します。
  4. Redisはシングルスレッドモデルを使用します。各コマンドの実行に時間がかかる場合、他のスレッドがブロックされます。これは、Redisなどの高性能サービスにとって致命的であるため、Redisは高速実行用のデータベースです。

コンテンツは、個人的な学習目的でのみ、オンライン記事を参照して編成されています。

  1. https://www.jianshu.com/p/6264fa82ac33
  2. https://blog.csdn.net/m0_37524661/article/details/87086267

おすすめ

転載: blog.csdn.net/magentodaddy/article/details/108532361