コンテンツにスキップ

Redis はシングルスレッドなのになぜ毎秒数百万リクエストを処理できるのか

原文

Interviewer:

Redis is single threaded, then how does it handle millions of requests per second?

要約

Redis はシングルスレッドでコマンド処理を行うが、インメモリ操作 + I/O多重化(epoll/kqueue) の組み合わせによりスレッドのロック競合なしに毎秒 100 万以上のリクエストを処理できる。「シングルスレッド」の弱点は、ネットワーク I/O ではなく、重い計算処理にある。

回答

Redis がシングルスレッドで高速な理由は主に3つ:

  1. インメモリ操作 → ディスク I/O がないため1コマンドが数マイクロ秒で完了
  2. I/O 多重化epoll/kqueue で何万もの接続を1スレッドで同時処理
  3. ロックなし → マルチスレッドのロック競合・コンテキストスイッチコストが0

解説

なぜシングルスレッドを選んだか

マルチスレッドにすると: - 共有データへのアクセスに mutex/lock が必要 - コンテキストスイッチのオーバーヘッド - デッドロックのリスク

Redis のワークロード(単純なキー操作)では、ロックのコストがスレッド並列化の恩恵を上回る

I/O 多重化のしくみ

クライアント A ─┐
クライアント B ─┤→ epoll → イベントループ(1スレッド)→ コマンド処理 → レスポンス
クライアント C ─┘

epoll はカーネルレベルで「どの接続にデータが届いたか」を監視し、準備できたものだけイベントループに通知する。I/O 待ちの間スレッドをブロックしない。

ベンチマーク感覚

操作 速度の目安
GET / SET 〜1μs(マイクロ秒)
秒間処理数 100万〜300万 ops/sec(条件による)
レイテンシ サブミリ秒

注意点:シングルスレッドの弱点

  • 重い O(N) 操作(KEYS *、LRANGE 全件など)はブロックする
  • Redis 6.0 以降は I/O スレッドが追加され、読み書き処理が並列化(コマンド処理は引き続きシングルスレッド)
  • WAITOBJECT ENCODING 等の一部コマンドも注意

面接での答え方

「Redis がシングルスレッドで高速な理由は、コマンド処理がすべてインメモリで完結し、1コマンドが数マイクロ秒で終わるためです。またネットワーク I/O には epoll を使った I/O 多重化を採用しており、1スレッドで数万の接続を同時にさばけます。マルチスレッドにするとロック競合が生じ、Redis の単純な操作ではむしろ遅くなります。」

→ 関連: Webキャッシュ戦略10のシステム設計概念

リンク