Dragonfly:100万リクエスト規模のシステムに向けたRedisの代替ソリューション

Database tutorial - IT technology blog
Database tutorial - IT technology blog

Redisが「ボトルネック」になる時

サーバーのスペックは非常に高いのに、システムが重いと感じたことはありませんか?以前、あるECプロジェクトを管理していた際、フラッシュセールのたびにチーム全員が固唾を飲んで見守っていました。サーバーのRedisは32コアのCPUと128GBのRAMを搭載していましたが、トラフィックが急増するとレイテンシが2msから200msにまで跳ね上がったのです。皮肉なことに、全体のCPU使用率はわずか5%でしたが、Redisが動作している1つのコアだけが常に100%に張り付いていました。

理由は非常にシンプルです。従来のRedisはシングルスレッド(single-threaded)で動作します。たとえ128コアのサーバーを用意しても、コマンド処理に使われるのはそのうちの1コアだけです。これは、100箇所の入り口がある巨大なスーパーに、レジ打ちの店員が1人しかいないようなものです。客が増えれば増えるほど、行列は長くなります。これは非常にストレスのたまる状況です。

なぜRedisは垂直スケーリングが難しいのか?

その原因は**イベントループ(Event Loop)**というアーキテクチャにあります。すべてのリクエストは、その唯一のスレッドで処理されるのを順番待ちしなければなりません。これを解決するために、通常はRedis Clusterを選択します。しかし、クラスターの管理は、スロットの分割からノードのバランシング、複雑なマルチキー操作(multi-key operations)の処理に至るまで、まさに悪夢です。

さらに、Redisがスナップショット(RDB)を実行する際のLinuxのfork()メカニズムは、システムの「一瞬の停止」を引き起こすことがよくあります。データ量が多い場合、これらのレイテンシの急増は、背後のマイクロサービス群全体をダウンさせる可能性すらあります。

よく使われる暫定的な解決策

  • CPUのアップグレード: Redisはマルチコアを活用できないため、この方法はほとんど無意味です。
  • 手動シャーディング: 同一サーバー上で複数のRedisインスタンスを実行する方法です。複数のコアを活用できますが、キーのマッピングを自前で管理する必要があり、アプリケーションのコードが非常に複雑になります。
  • Redis Clusterの導入: 正当な解決策ですが、管理リソースを消費します。単一ノードの性能を限界まで引き出したい場合には最適とは言えません。

Dragonfly — 高スループットシステムへの新たな風

Dragonflyはこれまでの古いやり方を踏襲しません。これは、RedisおよびMemcachedプロトコルと完全な互換性を持ちながら、**マルチスレッド(Multi-threaded)**アーキテクチャ上で動作する最新のインメモリデータベースです。

「シェアードナッシング(shared-nothing)」設計により、Dragonflyの各スレッドはロックの競合なしにデータの特定部分を処理します。ベンチマークテストでは、単一インスタンスで毎秒最大400万リクエストを達成しました。これはRedisよりも25倍高速な数値であり、非常に驚異的です。

Dockerを使って一瞬でDragonflyをインストールする

試してみるには、Dockerを使うのが最も手っ取り早い方法です。パフォーマンスを最大化するために、ネットワークモードをhostに設定することをお勧めします。

docker run --network=host docker.dragonflydb.io/dragonflydb/dragonfly

注意:--network=hostを使用することで、DragonflyはDockerのブリッジネットワーク層をバイパスし、不要なオーバーヘッドを最小限に抑えることができます。

Linuxに直接インストールする

UbuntuやDebianのプロダクション環境にデプロイしたい場合は、バイナリ版を使用できます。

# 最新のリリースをダウンロード
wget https://github.com/dragonflydb/dragonfly/releases/latest/download/dragonfly-x86_64.tar.gz
tar -xvzf dragonfly-x86_64.tar.gz

# 起動
./dragonfly --logtostderr --port 6379

Dragonflyの使用:コードの変更は一切不要

最大のメリットは、**既存のコードをそのまま維持できる**点です。redis-pyioredisgo-redisのいずれを使用していても、接続先のIPアドレスとポートをDragonflyに向けるだけで完了です。すべてがスムーズに動作します。

おなじみのredis-cliで接続してみましょう。

redis-cli -p 6379
127.0.0.1:6379> SET user:1 "Dragonfly User"
OK
127.0.0.1:6379> INFO

INFOコマンドを実行すると、Dragonflyが実行中のスレッド数の詳細を表示します。通常、マシンのCPUコア数と一致します。

サンプルデータの処理テクニック

パフォーマンステストの際、CSVデータをJSONに素早く変換してデータベースに投入したいことがよくあります。面倒なPythonスクリプトを書く代わりに、私はよく toolcraft.app/ja/tools/data/csv-to-json のツールを使用します。このツールはブラウザ上で処理されるため、内部データの漏洩を心配する必要がなく、非常に安全かつ高速です。

実際のパフォーマンスを検証する

広告の言葉を鵜呑みにせず、8コア以上のマシンでmemtier_benchmarkを使用して、その明らかな違いを自分で確認してみてください。

# Dragonflyのスループットをテスト
memtier_benchmark -s 127.0.0.1 -p 6379 --protocol=redis --threads=8

スループットがコア数に比例して増加するのがわかるはずです。Redisの場合、スレッドをいくら増やしても、この数値はすぐに頭打ちになります。

どのような時にRedisからDragonflyへ移行すべきか?

強力なDragonflyですが、あらゆるケースにおける「銀の弾丸」ではありません。以下のような場合には移行を検討してください。

  • 極めて高いスループットが必要な場合: 負荷を分散させるためだけに、数十台のRedis Clusterノードを必死に維持している状況。
  • コストの最適化: 管理コストを抑えるために、10台の小規模サーバーを借りるのではなく、1台の強力な(マルチコアの)サーバーにデータを集約したい場合.
  • 効率的なメモリ管理: Dragonflyはdashtableアルゴリズムを使用しており、同じデータ量を保存する場合、RedisよりもRAMを約30%節約できます。

アプリケーションの規模が小さく、トラフィックが安定している場合は、引き続きRedisが安全な選択肢です。Redisは10年以上にわたって信頼性が実証されている業界標準です。

Lời kết

Dragonflyを使いこなすことは、数百万ユーザー規模のシステムスケーリングという課題を解決するための強力な武器を手に入れることと同じです。パフォーマンスやコストの悩みを解決できるのであれば、新しい技術の導入をためらわないでください。今日、ステージング環境でDragonflyを試してみてください。その結果にきっと驚くはずです。

Share: