この記事では、Redis6 のスレッド モデルを理解し、シングル スレッド モデルとマルチ スレッド モデルを紹介します。
単純に Redis がシングルスレッドかマルチスレッドかというと、この答えになります。バージョンによって使用されるスレッド モデルは異なります。 [関連する推奨事項: Redis ビデオ チュートリアル ]
multi が追加され始めています。 -スレッド関連 (非同期削除)。
主に、Redis のネットワーク IO とキーと値のペアの読み取りと書き込みが 1 つのスレッドで完了することを意味します。Redis がクライアントのリクエストを処理する際には、取得 (ソケットの読み取り)、解析、実行、コンテンツの返却 (ソケット) が含まれます。書き込みなど)など。順次メインスレッドによって処理されます。これは「シングルスレッド」と呼ばれます。これは、Redis が外部のキーと値のストレージ サービスを提供するための主要なプロセスでもあります。 ただし、
永続化、非同期削除、クラスター データの同期などの Redis の他の機能は、実際には追加のスレッドによって実行されます。
Redis ワーカー スレッドはシングルスレッドであると言えます。ただし、
Redis 全体はマルチスレッドです;2.2 シングルスレッドのパフォーマンスが高速な理由
高速パフォーマンスの主な理由: メモリ操作に基づく: すべてのデータはメモリに保存されるため、すべての操作はメモリ レベルで行われます
単純なデータ構造: Redis のデータ構造は特別に設計されており、ほとんどの場合、これらの単純なデータ構造の検索と操作の複雑さは #o(1)
2.3 シングルスレッドを使用する理由マルチスレッドのサポートが開始されました。 簡単に言えば、Redis 4.0 より前にシングル スレッドが使用されてきた主な理由は 3 つあります。
シングル スレッド モデルを使用すると、Redis の開発とメンテナンスが簡単になります。シングルスレッド モデルは開発とデバッグを容易にします。マルチスレッド モデルはいくつかの面ではうまく機能しますが、プログラムの実行順序に不確実性が生じ、同時読み取りと書き込みで一連の問題が発生し、システムの複雑さが増大し、スレッドの切り替え、ロックとロック解除、デッドロックによって引き起こされるパフォーマンスの低下。 RedisはAEイベントモデルやIO多重化などの技術により非常に高い処理性能を持っているため、マルチスレッドを使用する必要がありません。シングルスレッドメカニズムにより、Redis の内部実装の複雑さが大幅に軽減され、Hash の慣性、Rehash、Lpush およびその他の「スレッド安全でない」コマンドをロックなしで実行できます。 シングルスレッド モデルが使用されている場合でも、主に多重化およびノンブロッキング IO を使用して、複数のクライアント リクエストを同時に処理できます。 #Redis システムの場合、主な
パフォーマンスのボトルネックは、CPU
ではなくメモリまたはネットワーク帯域幅です。
#3. Redis マルチスレッド モデル
##3.1 マルチスレッドを導入する理由
シングルスレッドは非常に優れているのに、なぜマルチスレッドを導入するのでしょうか?
シングルスレッドには、大きなキーの削除問題など、独自の問題もあります。
通常の状況では、del コマンドを使用してデータをすばやく削除できますが、削除されたキーが数千の要素を含むハッシュ セットなどの非常に大きなオブジェクトである場合、del コマンドにより Redis マスターが失敗します。行き詰まっています。
そのため、Redis 4.0 では新しいマルチスレッド モジュールが追加されました。もちろん、このバージョンのマルチスレッドは主に、データ削除効率が比較的低いという問題を解決するためのものです。 lazy deletion を使用すると、Redis のラグの問題 (大規模なキーの削除など) を効果的に回避できます。手順は次のとおりです:
unlink key: DEL を使用する 同じキー削除関数の遅延なしの実装です. 唯一の違いは、UNLINK がセット タイプのキーを削除するときに、セット キーの要素数が 64 より大きい場合、メイン スレッドはキーの要素のみを削除することです。データベース辞書から削除するキーと実際のメモリ解放操作は別のバイオによって実行されます。要素の数が少ない場合 (64 未満)、または String 型の場合も、メイン スレッドで直接削除されます。
flushall/flushdb async: データベースのフラッシュ コマンド flashall/flushdb に、async 非同期クリーンアップ オプションが追加され、データベースのクリア時に Redis が非同期で動作するようになります。実装ロジックは、データベースに新しい空の辞書を作成し、元の古いデータベース辞書をバックグラウンド スレッドに渡して、データを 1 つずつ削除してメモリを解放します。
lazy free の本質は、より高い削除によって
特定のコスト (メイン時間のレプリケーション、メインスレッドの CPU タイム スライスの占有) を削除することです。 Operations、redis より メインスレッドが取り除かれ、bio サブスレッドが処理できるようになり、メインスレッドのブロック時間が大幅に短縮されます。これにより、削除によって生じるパフォーマンスと安定性の問題が軽減されます。
3.2 マルチスレッドの動作原理
I/O の読み取りと書き込み自体がブロックされます。ソケット、Redis データは呼び出しを通じてカーネル空間からユーザー空間にコピーされ、呼び出しのために Redis に渡されます。このコピー プロセスはブロックされています。データ量が多いと、コピーに時間がかかります。 、これらの操作は単一のスレッドに基づいて実行されます。 Redis 6.0 では、I/O 読み取りおよび書き込みのパフォーマンスを向上させるために、新しい マルチスレッド関数が追加されました . 彼の主な実装アイデアは、IO 読み取りと書き込みを組み合わせることです。メインスレッドのタスクを独立したスレッドのグループに分割して実行できるため、複数のソケットの読み取りと書き込みを並列化できます。マルチチャネル I/O 多重化テクノロジの使用により、単一のスレッドで複数のタスクを効率的に処理できます。接続リクエスト (ネットワーク IO 時間の消費を最小限に抑える)、最も時間のかかるソケットの読み取り、リクエストの解析、書き込みは個別にアウトソーシングされ、残りのコマンドの実行は引き続きメイン スレッドによってシリアルに実行され、メモリ内のデータと対話します。 上の図と組み合わせると、
ネットワーク データの読み取りと書き込み、およびリクエスト プロトコルの解析が複数の IO スレッドを通じて処理されることがわかります。実際のコマンドの実行には、メイン スレッドの操作が引き続き使用されます (スレッド安全性)、これは良い妥協点です。したがって、 は Redis 全体ではマルチスレッドですが、ワーカー スレッド (コマンド実行) では依然としてシングルスレッドです。
プロセスは次のように簡単に説明されます:
ソケットの読み取りが完了しました
(コマンドが受信されない場合は、次回の IO 継続を待ちます)
ソケットへのデータの書き込みが完了しました(一度完了していない場合は、次回再度書き込まれます)
機能は次のとおりです:
現在のパフォーマンスは 1 倍以上向上する可能性があります。
質問 1: 待機リストは常にブロックされ、満員でない場合は処理されませんか? 返信:
ブロック時に検出されるのは、IO スレッドにまだタスクがあるかどうかです。処理が完了するまで待ってから続行してください。これらのタスクは実行中に追加されます。タスク数 これについてはまだ疑問が残っているのですが、誰か説明(コメント)してもらえませんか?
3.4 マルチスレッドはデフォルトで有効ですか?
Redis6.0 では、マルチスレッド メカニズムはデフォルトでオフになっています。マルチスレッド機能を使用する必要がある場合は、次の 2 つの手順を完了する必要があります。 redis.confの設定。
に設定することをお勧めします。スレッド数は、マシン コアとスレッドの数よりも少なくなければなりません。必ずしもマシン コアとスレッドの数が優れているわけではありません。
I/O の読み取りと書き込みをマルチスレッド に変えるだけで、
コマンドの実行は依然としてメインスレッド によってシリアルに実行されるため、マルチスレッド
で Redis を動作させることはできません。スレッド セーフティの問題が発生しました。
Redis 元のシングルスレッド設計であっても、元の設計に反する現在のマルチスレッド設計であっても、目的は 1 つだけです。Redis をますます高速化することです。
プログラミング関連の知識について詳しくは、プログラミング入門をご覧ください。 !
以上がRedis6 のシングルスレッド モデルとマルチスレッド モデルの簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。