dragonfly - RedisとMemcachedの現代的な代替品

(A modern replacement for Redis and Memcached)

Created at: 2021-12-11 18:00:42
Language: C++
License: NOASSERTION

蜻蛉

ci-検定 ツイッターのURL

クイックスタート|不和チャット|GitHub ディスカッション |GitHub の問題|貢献

おそらく、宇宙で最速のメモリ内ストア!

Dragonflyは最新のインメモリデータストアで、RedisおよびMemcached APIと完全に互換性があります。Dragonflyは、マルチスレッドの共有なしアーキテクチャの上に新しいアルゴリズムとデータ構造を実装しています。その結果、DragonflyはRedisと比較してx25のパフォーマンスに達し、単一のインスタンスで何百万ものQPSをサポートします。

トンボのコア特性により、費用対効果が高く、高性能で使いやすいRedis代替品となっています。

ベンチマーク

トンボはc6gn.16xlargeで3.8M QPSを横断しており、Redisと比較してスループットがx25向上しています。

トンボのピークスループットでの99番目のレイテンシ百分位数:

オペアンプ R6グラム c6gn c7グラム
セット 0.8ミリ秒 1ミリ秒 1ミリ秒
取得 0.9ミリ秒 0.9ミリ秒 0.8ミリ秒
セテックス 0.9ミリ秒 1.1ミリ秒 1.3ミリ秒

すべてのベンチマークは、サーバータイプとインスタンスタイプごとに調整されたスレッド数を持つmemtier_benchmark(下記参照)を使用して実行されました。memtier は別の c6gn.16xlarge マシン上で実行されていました。setexベンチマークでは、500の有効期限範囲を使用したため、テストの最後に生き残ります。

  memtier_benchmark --ratio ... -t <threads> -c 30 -n 200000 --distinct-client-seed -d 256 \
     --expiry-range=...

パイプラインモードで実行している場合、DragonflyはSETで10M qps、GET操作で15M qpsに達します。

--pipeline=30

メムキャッシュ/トンボ

私たちは、AWSのインスタンスでmemcachedとDragonflyを比較しました。以下でわかるように、Dragonflyは、同等のレイテンシでスループットの点で、書き込みと読み取りの両方のワークロードでmemcachedを支配しています。書き込みワークロードの場合、Dragonflyはmemcachedの書き込みパスでの競合により、レイテンシも長くなります。

c6gn.16xlarge

ベンチマークの設定

サーバー QPS(数千QPS) レイテンシ 99% 99.9%
蜻蛉 🟩 3843 🟩 0.9ミリ秒 🟩 2.4ミリ秒
Memcached 806 1.6ミリ秒 3.2ミリ秒

GETベンチマーク

サーバー QPS(数千QPS) レイテンシ 99% 99.9%
蜻蛉 🟩 3716 1ミリ秒 2.4ミリ秒
Memcached 2100 🟩 0.34ミリ秒 🟩 0.6ミリ秒

Memcachedは、読み取りベンチマークのレイテンシは低かったが、スループットも低下した。

メモリ効率

次のテストでは、コマンドを使用してDragonflyとRedisに〜5GBのデータを埋めました。次に、更新トラフィックの送信を開始し、 "bgsave"コマンドでスナップショットを開始しました。次の図は、両方のサーバーがメモリ効率の面でどのように動作するかを明確に示しています。

debug populate 5000000 key 1024
memtier

トンボはアイドル状態のRedisよりも30%メモリ効率が高かった。また、スナップショットフェーズ中に目に見えるメモリの増加も示されませんでした。一方、RedisはDragonflyと比較してピーク時にほぼx3のメモリ増加に達しました。Dragonflyはまた、スナップショットが開始してからわずか数秒後に、はるかに速くスナップショットを完成させました。Dragonflyのメモリ効率の詳細については、ダッシュ可能なドキュメントを参照してください。

サーバーの実行

トンボはLinux上で動作します。Linuxバージョン5.11以降で実行することをお勧めしますが、古いカーネルでもDragonflyを実行することもできます。

ドッカーの場合:

docker run --network=host --ulimit memlock=-1 docker.dragonflydb.io/dragonflydb/dragonfly

redis-cli PING  # redis-cli can be installed with "apt install -y redis-tools"

--ulimit memlock=-1 が必要なのは、一部の Linux ディストリビューションがコンテナのデフォルトの memlock 制限を 64m として設定し、Dragonfly がさらに多くを必要とするからです。

リリース

x86 および arm64 アーキテクチャ用のバイナリリリースを維持しています。バイナリを実行するにはlibをインストールする必要があります。

libunwind8

ソースからの構築

Ubuntu 20.04以降でビルドするには、依存関係をインストールする必要があります。

git clone --recursive https://github.com/dragonflydb/dragonfly && cd dragonfly

# to install dependencies
sudo apt install ninja-build libunwind-dev libboost-fiber-dev libssl-dev libxml2-dev \
     autoconf-archive libtool cmake g++

# Configure the build
./helio/blaze.sh -release

# Build
cd build-opt && ninja dragonfly

# Run
./dragonfly --alsologtostderr

構成

Dragonfly は、該当する場合、一般的な Redis 引数をサポートしています。たとえば、次のコマンドを実行できます。

dragonfly --requirepass=foo --bind localhost

Dragonflyは現在、次のRedis固有の引数をサポートしています。

  • port
    redis接続ポート、デフォルト:6379
  • bind
    localhostは、ロカホスト接続のみを許可し、パブリックIPアドレスは、そのIPアドレスへの接続を許可します(別名、外部からも)
  • requirepass
    AUTH 認証用のパスワード、デフォルト: ""
  • maxmemory
    database.0 によって使用される最大メモリ (バイト単位) の制限 - は、プログラムが最大メモリ使用量を自動的に決定することを意味します。デフォルト: 0
  • dir
    - デフォルトでは、トンボのドッカーはスナップショットのためにフォルダを使用します。CLIは以下を使用します: "" ドッカーオプションを使用してホストフォルダにマップできます。
    /data
    -v
  • dbfilename
    DBを保存/ロードするファイル名。デフォルト: "ダンプ";

さらに、Dragonfly固有の引数オプションがあります。

  • memcache_port
    - このポートで memcached 互換 API を有効にする。デフォルトでは無効になっています。
  • keys_output_limit
    - コマンドで返されるキーの最大数。デフォルトは 8192 です。 危険なコマンドです。あまりにも多くのキーをフェッチするときにメモリ内の爆発を避けるために、結果を切り捨てます。
    keys
    keys
  • dbnum
    - でサポートされているデータベースの最大数。
    select
  • cache_mode
    - 下記のキャッシュセクションを参照してください。
  • hz
    - キーの有効期限の評価頻度。デフォルトは 100 です。周波数が低いほど、アイドル時のCPU使用量が少なくなり、削除率が遅くなります。
  • save_schedule
    - HH:MM(24時間)と一致するスナップショットを保存するためのUTC時間のグロブ仕様。デフォルト: ""
  • keys_output_limit
    - keysコマンドで出力されるキーの最大数。デフォルト : 8192

ログ管理や tls サポートなどのその他のオプションについては、 を実行します。

dragonfly --help

ロードマップとステータス

現在、Dragonflyは〜185 Redisコマンドと、 以外のすべてのmemcacheコマンドをサポートしています。私たちはRedis 5 APIとほぼ同等です。次のマイルストーンは、基本機能を安定させ、レプリケーションAPIを実装することです。必要なコマンドがまだ実装されていない場合は、問題を開いてください。

cas

トンボネイティブのレプリケーションでは、桁違いに高速な速度をサポートする分散ログ形式を設計しています。

レプリケーション機能の後、API 3-6 から他の Redis コマンドが欠落しているのを続行します。

Dragonflyの現在のステータスについては、API準備のドキュメントを参照してください。

設計上の決定

斬新なキャッシュ設計

Dragonflyには、非常にシンプルでメモリ効率の高い単一の統一されたアダプティブキャッシングアルゴリズムがあります。flagを渡すことでキャッシングモードを有効にすることができます。このモードがオンになると、Dragonflyは将来つまずく可能性が最も低いアイテムを削除しますが、最大メモリ制限に近い場合にのみアイテムを削除します。

--cache_mode=true

相対的な精度での有効期限の期限

有効期限の範囲は〜4年に制限されています。さらに、ミリ秒精度の有効期限 (PEXPIRE/PSETEX など) は、134217727ms (約 37 時間) を超える期限に対して最も近い秒に丸められます。このような丸め誤差は0.001%未満で、広い範囲で許容できることを願っています。それがあなたのユースケースを壊すならば - 私に話すか、問題を開いてあなたのケースを説明してください。

これとRedisの実装のより詳細な違いについては、 ここを参照してください

ネイティブ Http コンソールとプロメテウス互換のメトリック

デフォルトでは、DragonflyはメインのTCPポート(6379)を介したhttpアクセスを許可します。そうです、あなたはRedisプロトコルとHTTPプロトコルを介してDragonflyに接続することができます - サーバーは接続開始時にプロトコルを自動的に認識します。先に進み、ブラウザで試してみてください。現時点では多くの情報はありませんが、将来的には、有用なデバッグおよび管理情報を追加する予定です。URLに移動すると、プロメテウスと互換性のあるメトリックがいくつか表示されます。

:6379/metrics

Prometheus がエクスポートしたメトリックは、Grafana ダッシュボードと互換性があります 詳細はこちらを参照してください

大事な!httpコンソールは、安全なネットワーク内でアクセスすることを目的としています。Dragonfly の TCP ポートを外部に公開する場合は、コンソールを または で無効にすることをお勧めします。

--http_admin_console=false
--nohttp_admin_console

バックグラウンド

Dragonflyは、2022年にインメモリデータストアが設計された場合、どのように見えるかを調べる実験として始まりました。メモリストアのユーザーとして、またクラウド企業で働いていたエンジニアとしての経験から学んだ教訓に基づいて、私たちはDragonflyの2つの重要な特性を保持する必要があることを知っていました:a)すべての操作にアトミック性を保証すること、およびb)非常に高いスループットにわたって低ミリ秒未満のレイテンシを保証すること。

最初の課題は、現在パブリッククラウドで利用可能なサーバーを使用して、CPU、メモリ、およびI / Oリソースを最大限に活用する方法でした。これを解決するには、共有なしアーキテクチャを使用して、スレッド間でメモリストアのキースペースを分割して、各スレッドが独自のディクショナリデータのスライスを管理できるようにしました。私たちはこれらのスライスをシャードと呼んでいます。共有ナッシングアーキテクチャのスレッドとI / O管理を強化するライブラリは、ここでオープンソース化されています。

マルチキー操作のアトミック性保証を提供するために、我々は最近の学術研究からの進歩を利用しました。私たちは、Dragonflyのトランザクションフレームワークを開発するために、「VLL:メインメモリデータベースシステム用のロックマネージャの再設計」という論文を選択しました。シェアード・ナッシング・アーキテクチャと VLL を選んだことで、ミューテックスやスピンロックを使用せずにアトミックなマルチキー操作を構成することができました。これは当社のPoCにとって大きなマイルストーンであり、そのパフォーマンスは他の商用およびオープンソースソリューションよりも際立っていました。

2 つ目の課題は、新しいストアのより効率的なデータ構造を設計することでした。この目標を達成するために、私たちは紙の「ダッシュ:永続メモリ上のスケーラブルなハッシュ」に基づいてコアハッシュテーブル構造を作成しました。この論文自体は永続メモリドメインを中心としており、メインメモリストアとは直接関係ありません。それにもかかわらず、それは私たちの問題に非常に当てはまります。これは、Redisディクショナリに存在する2つの特別なプロパティを維持できるハッシュテーブル設計を提案しました:a)データストアの成長中の増分ハッシュ機能b)ステートレススキャン操作を使用して変更の下でディクショナリをトラバースする機能。これら2つのプロパティに加えて、ダッシュはCPUとメモリではるかに効率的です。Dashのデザインを活用することで、次の機能でさらに革新することができました。

  • TTL レコードの効率的なレコード有効期限。
  • メモリオーバーヘッドゼロでLRUやLFUなどの他のキャッシュ戦略よりも高いヒット率を達成する新しいキャッシュ削除アルゴリズム。
  • 新しいフォークレススナップショットアルゴリズム。

Dragonfly の基盤を構築し、そのパフォーマンスに満足した後、RedisとMemcachedの機能を実装しました。ここまでで、約 185 個の Redis コマンド (Redis 5.0 API とほぼ同等) と 13 個の Memcached コマンドを実装しました。

そして最後に、私たちの使命は、
最新のハードウェアの進歩を利用するクラウドワークロード用の、適切に設計された超高速でコスト効率の高いインメモリデータストアを構築することです。私たちは、現在のソリューションの問題点に対処しながら、製品のAPIと提案を維持するつもりです。