1. ホーム
  2. データベース
  3. レディス

Redisシングルスレッディングの正しい理解

2022-01-23 12:27:21

RedisのシングルスレッドとI/O多重化についてよく知らない学生も多いので、RedisのシングルスレッドとI/O多重化の原理をわかりやすく理解してもらうことで、Redisをしっかり学び、使うための基礎固めをしようと思っています。

I. シングルスレッドで理解するRedis

Redisクライアントからサーバーへの呼び出しは、コマンドの送信、コマンドの実行、結果の返信というプロセスを経ます。コマンド実行段階では、Redisはシングルスレッドなので、サーバーに届いたコマンドはすべてすぐに実行されず、キューに入り、一つずつ実行される。これがRedisの基本的なシングルスレッド・モデルです。

Redisサーバーは、ソケット(socket)を介してクライアントや他のRedisサーバーに接続し、ファイルイベントはソケット操作をサーバーが抽象化したものです。サーバとクライアントまたは他のサーバとの間の通信により、対応するファイルイベントが生成され、サーバはこれらのイベントをリッスンして処理し、一連のネットワーク通信処理を完了させます。

RedisはReactorパターンに基づいて、独自のネットワークイベントハンドラであるファイルイベントハンドラを開発しました。ファイルイベントハンドラは、I/O マルチプレクサを使用して複数のソケットを一度にリッスンし(I/O マルチプレクサのテクニックは後述)、ソケットが現在実行しているタスクに基づいて異なるイベントハンドラを関連付けます。ソケットは、ソケットが現在実行しているタスクによって異なるイベントハンドラに関連付けられます。ソケットがコネクションアンサー、リード、ライト、クローズなどを実行する準備ができると、その操作に対応するファイルイベントが生成され、ファイルイベントハンドラは、ソケットにあらかじめ関連付けられたイベントハンドラを呼び出してこれらのイベントを処理します。

ファイルイベントハンドラの構成要素

注:I/Oマルチプレクサがキューを介してファイルイベントディスパッチャにソケットを送信する場合

II. I/O多重化技術

I/O多重化("イベントドリブン"とも呼ばれる)について最初に理解しておくべきことは、オペレーティングシステムが、ソケットの1つが読み取りまたは書き込みに利用可能になったときに通知を与える機能を提供することである。この方法では、ノンブロッキングソケットで使用する場合、システムがどのディスクリプタが利用可能かを通知した場合にのみ読み込み操作を行うことができ、すべての読み込みが有効な読み込みであり、-1やEAGAINの純粋な戻り値ではなく、同様の書き込み操作を保証しています。

OSはこれをselect/poll/epoll/kqueueなどのシステムコール関数で行い、複数のディスクリプタの読み書きの可否を同時に監視し、1つのスレッド内で複数のディスクリプタに対するI/O操作を同時かつ交互に連続して行えるようにしている(これをI/O多重化という)。これはI/O多重化と呼ばれ、"multiple"は複数のネットワーク接続、"multiplexing"は同じRedis処理スレッドを多重化することを意味する。(上図のように)

I/Oを多重化することで、1つのスレッドで複数の接続要求を効率的に処理できる(ネットワークI/Oの時間消費を最小限に抑える)。また、Redisはメモリ上のデータ操作が非常に速いため、メモリ内操作がRedisのパフォーマンスのボトルネックにならず、すべてのRedisで高いスループットが得られるということです。

III. よくある質問に対する回答

1. なぜRedisはシングルスレッドが速いのですか?

1. 完全にメモリベースであり、リクエストの大部分は純粋にメモリ内の操作であるため、非常に高速である。データはHashMapと同様にメモリ上に存在し、ルックアップと操作の両方の時間複雑性がO(1)であるという利点がある。

2. データ構造がシンプルであるため、データに対する操作もRedisで特別に設計されています。

3. シングルスレッドで、不要なコンテキストスイッチや競合状態を回避し、マルチプロセスやマルチスレッドのスイッチによるCPU消費もなく、考慮すべきロックもなく、ロックとリリース操作もなく、デッドロックの可能性による性能消費もない。

4. 複数のI/O多重化モデルを使用したノンブロッキングI/O。

5. システム機能への通常のシステムコールは、移動とリクエストに時間を浪費するため、Redisは独自のVMメカニズムを直接構築します。

2. マルチプロセスやマルチスレッド処理を使用しない理由は?

1. マルチスレッド処理にはロックが必要な場合がある

2. マルチスレッド処理では、スレッドスイッチングが発生し、CPUを消費する場合があります。

3. シングルスレッド処理のデメリット?

1. 時間のかかるコマンドは、読み込みの同時実行性だけでなく、書き込みの同時実行性も低下させる可能性がある

2. マルチコアCPUの性能を生かせないが、1台のマシンで複数のRedisインスタンスを開くことで改善される可能性がある

4. Redisはスレッドセーフではないのですか?

しかし、複数のRedis操作に依存する複合操作(つまり複数のRedis操作コマンド)にはロックが必要であり、潜在的には分散ロックが必要です。

Redisのシングルスレッドについて正しく理解するための記事はここまでです。Redisのシングルスレッドについてもっと知りたい方は、スクリプトハウスの過去記事を検索するか、以下の関連記事を引き続き閲覧してください。