Redis はシングルスレッドですが、なぜこれほど高速なのでしょうか?理由の 1 つは、redis がノンブロッキング IO と多重化を使用して多数のクライアント接続を処理するためです。次の記事では、Redis のスレッド IO モデルについて説明します。お役に立てば幸いです。
Redis はシングルスレッド アプリケーションであり、NodeJs と Nginx はどちらもシングルスレッドであり、いずれも高性能サーバーのモデルです。 [関連する推奨事項: Redis ビデオ チュートリアル ]
Redis がシングルスレッドで高速である理由:
まず、すべてのデータがメモリ内にあるため、すべての操作がメモリレベルの操作なので、redis を使用する場合は、時間計算量が O(n) の命令に注意してください。シングルスレッドであるため、データ量が多すぎると、他の命令がブロックされて待機します。
#2 番目の理由は、redis がノンブロッキング IO と多重化を使用して多数のクライアント接続を処理するためです。 ノンブロッキング IOソケットの読み取りおよび書き込みメソッドを使用する場合、デフォルトはブロックです。つまり、読み取りメソッドを呼び出してパラメーターを渡します。 n、読み取りの最大数を示します n バイトを取った後に戻ります。バイトがない場合、スレッドはデータが到着するか接続が閉じられるまで読み取りメソッドで待機し続けます。読み取りメソッドはこの時点で戻り、スレッドは次のロジックを実行できます。書き込みメソッドは通常、ブロックしません。カーネルによってソケットに割り当てられた書き込みバッファーがいっぱいでない限り、バッファーに空き領域ができるまで、書き込みメソッドはブロックされます。 次の図は、ソケットの読み取りと書き込みの詳細なプロセスを示しています。 ノンブロッキング IO では、ソケットを使用するときに Non_Blocking オプションが提供されます。このオプションをオンにすると、読み取りメソッドと書き込みメソッドはブロックされませんが、ブロックされるのと同じだけ読み取ることができます。できる限り書き込めます。 どれだけ読み取れるかは、カーネルによってソケットに割り当てられた読み取りバッファ内のデータ バイト数によって決まり、どのくらい書き込めるかはデータによって決まります。カーネルによってソケットの書き込みバッファに割り当てられます。バイト数、読み取りメソッドと書き込みメソッドは、戻り値を通じてプログラムに読み書きされたバイト数を通知します。 ノンブロッキング IO とは、読み取りおよび書き込み時にスレッドをブロックする必要がなくなったことを意味します。読み取りと書き込みは即座に完了し、スレッドは他の作業を続行できます。 多重化 (イベント ポーリング)ノンブロッキング IO は非常に高速ですが、問題も発生します。スレッドはデータを読み取り、その一部を読み取った後に戻ります。読み取りが完了していません。 . 残りのデータはいつ読み続けられますか? 、データを書き込んでいますが、バッファーがいっぱいで完全に書き込まれていません。残りのデータはいつ書き続けられますか? 読み取りを継続できる場合、または書き込みを継続できる場合は、アプリケーションに読み取りまたは書き込みを継続できることを通知する通知を送信する必要があります。この問題を処理するには、イベント ポーリング API が使用されます。
select
オペレーティング システムは、ユーザー プログラムの選択機能を提供します。入力は、読み取りおよび書き込み記述子リスト read_fds および write_fds です。出力は、対応する読み取り可能および書き込み可能なイベントです。 はタイムアウト パラメーターも提供します。スレッドは最大でタイムアウトまで待つことができます。この期間中、イベントが発生すると、メソッドはすぐに戻ります。スレッドは処理を続行します。タイムアウト時間を超えた場合、メソッドも戻ります。イベントが取得されると、スレッドは対応するイベントを 1 つずつ処理できます。処理後、メソッドの呼び出しを継続します。 select API ポーリングなので、スレッドは実際には無限ループであり、選択を続けます。ノンストップで処理を行ったり来たりするこの無限ループはイベント ループと呼ばれ、ループはサイクルです。 イベント ループ疑似コード:while True read_events, write_events = select(read_fds, write_fds, timeout) for event in read_events: handle_read(event.fd) for event in write_events: handle_write(event.fd) handle_others() # 做其他的逻辑处理,处理定时任务等等
サーバーは IO イベントに応答する必要があるだけでなく、アプリケーション自身のタイミング タスクなど、他のことも処理する必要があります。スレッドが選択呼び出しでブロックした場合、待機中になります。 select が返されると、一部のスケジュールされたタスクは期限切れになっていますが、実行されていません。
Redis のスケジュールされたタスクは、最小ヒープと呼ばれるデータ構造に記録されます。このヒープでは、最も速いタスクが実行されます。各サイクル サイクル中、redis はその時点に達したヒープ内のタスクを処理します。ヒープが記録されます。select が再度呼び出されるとき、この時間は になります。タイムアウトの値は、この期間中に他のタスクを実行する必要がないことを意味します。Redis は最大でこの時間の間は安全にブロックでき、その後、対応する処理を実行します。時間切れです。
NodeJ と Nginx のイベント処理原理は Redis と似ています。
プログラミング関連の知識について詳しくは、
プログラミング ビデオ以上がこの記事では、Redis のスレッド IO モデルをすぐに理解できるようにします。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。