次に進む前に、GitHub スター ️ を付けることをご検討ください。ありがとう!
その他の言語: 简体中文 日本語 한국어
ウェブサイト • ドキュメント • クイック スタート • コミュニティ Discord • Dragonfly フォーラム • Dragonfly コミュニティに参加する
GitHub ディスカッション • GitHub の問題 • 貢献 • Dragonfly クラウド
Dragonfly は、最新のアプリケーションのワークロード向けに構築されたインメモリ データ ストアです。
Redis および Memcached API と完全な互換性があるため、Dragonfly を採用するためにコードを変更する必要はありません。従来のインメモリ データストアと比較して、Dragonfly は 25 倍のスループット、より低いテール レイテンシでより高いキャッシュ ヒット率を実現し、同じサイズのワークロードで最大 80% 少ないリソースで実行できます。
まず、シングルスレッド アーキテクチャのため、Redis を実行するために一般的に使用されるm5.large
インスタンス上の Dragonfly と Redis を比較します。ベンチマーク プログラムはmemtier_benchmark -c 20 --test-time 100 -t 4 -d 256 --distinct-client-seed
を使用して、同じ AZ 内の別の負荷テスト インスタンス (c5n) から実行されます。
Dragonfly は同等のパフォーマンスを示します。
--ratio 1:0
):レディス | DF |
---|---|
QPS: 159K、P99.9: 1.16ms、P99: 0.82ms | QPS:173K、P99.9:1.26ms、P99:0.9ms |
--ratio 0:1
):レディス | DF |
---|---|
QPS: 194K、P99.9: 0.8ms、P99: 0.65ms | QPS: 191K、P99.9: 0.95ms、P99: 0.8ms |
上記のベンチマークは、垂直方向のスケーリングを可能にする DF 内のアルゴリズム層が、シングルスレッドで実行する場合に大きな負荷を受けないことを示しています。
ただし、もう少し強力なインスタンス (m5.xlarge) を使用すると、DF と Redis の間のギャップが拡大し始めます。 ( memtier_benchmark -c 20 --test-time 100 -t 6 -d 256 --distinct-client-seed
):
--ratio 1:0
):レディス | DF |
---|---|
QPS: 190K、P99.9: 2.45ms、P99: 0.97ms | QPS: 279K、P99.9: 1.95ms、P99: 1.48ms |
--ratio 0:1
):レディス | DF |
---|---|
QPS: 220K、P99.9: 0.98ms、P99: 0.8ms | QPS: 305K、P99.9: 1.03ms、P99: 0.87ms |
Dragonfly のスループット容量はインスタンスのサイズに応じて増加し続けますが、シングルスレッド Redis は CPU でボトルネックとなり、パフォーマンスの点で極大値に達します。
最もネットワーク対応力の高いインスタンス c6gn.16xlarge で Dragonfly と Redis を比較すると、Dragonfly は Redis の単一プロセスと比較してスループットが 25 倍向上し、380 万 QPS を超えました。
Dragonfly のピーク スループットにおける 99 パーセンタイル レイテンシー メトリクス:
オプ | r6g | c6gn | c7g |
---|---|---|---|
セット | 0.8ミリ秒 | 1ms | 1ms |
得る | 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=...
パイプライン モード--pipeline=30
では、Dragonfly は SET 操作で10M QPS 、GET 操作で15M QPSに達します。
AWS の c6gn.16xlarge インスタンスで Dragonfly と Memcached を比較しました。
同等のレイテンシーで、Dragonfly のスループットは、書き込みワークロードと読み取りワークロードの両方で Memcached のスループットを上回りました。 Dragonfly は、Memcached の書き込みパス上の競合により、書き込みワークロードのレイテンシが向上することを実証しました。
サーバ | QPS(千qps) | レイテンシ 99% | 99.9% |
---|---|---|---|
トンボ | ? 3844 | ? 0.9ミリ秒 | ? 2.4ミリ秒 |
Memcached | 806 | 1.6ミリ秒 | 3.2ミリ秒 |
サーバ | QPS(千qps) | レイテンシ 99% | 99.9% |
---|---|---|---|
トンボ | ? 3717 | 1ms | 2.4ミリ秒 |
Memcached | 2100 | ? 0.34ミリ秒 | ? 0.6ミリ秒 |
Memcached は読み取りベンチマークのレイテンシーが低くなりましたが、スループットも低くなりました。
メモリ効率をテストするために、 debug populate 5000000 key 1024
コマンドを使用して Dragonfly と Redis に約 5GB のデータを埋め込み、 memtier
で更新トラフィックを送信し、 bgsave
コマンドでスナップショットを開始しました。
この図は、メモリ効率の観点から各サーバーがどのように動作するかを示しています。
Dragonfly は、アイドル状態では Redis よりもメモリ効率が 30% 高く、スナップショット段階では目に見えるメモリ使用量の増加は見られませんでした。ピーク時には、Redis のメモリ使用量は Dragonfly のほぼ 3 倍に増加しました。
Dragonfly はスナップショットを数秒以内に迅速に完了しました。
Dragonfly のメモリ効率の詳細については、Dashtable のドキュメントを参照してください。
Dragonfly は、該当する場合、一般的な Redis 引数をサポートします。たとえば、次のように実行できます: dragonfly --requirepass=foo --bind localhost
。
Dragonfly は現在、次の Redis 固有の引数をサポートしています。
port
: Redis 接続ポート ( default: 6379
)。bind
: localhost 接続のみを許可する場合はlocalhost
を使用し、その IP アドレスへの接続を許可する場合はパブリック IP アドレスを使用します (つまり、外部からの接続も許可します)。すべての IPv4 を許可するには、 0.0.0.0
を使用します。requirepass
: AUTH 認証のパスワード ( default: ""
)。maxmemory
: データベースによって使用される最大メモリの制限 (人間が判読できるバイト単位) ( default: 0
)。 maxmemory
値0
は、プログラムが最大メモリ使用量を自動的に決定することを意味します。dir
: Dragonfly Docker はデフォルトでスナップショットに/data
フォルダーを使用し、CLI は""
を使用します。 -v
Docker オプションを使用して、ホスト フォルダーにマップできます。dbfilename
: データベースを保存およびロードするファイル名 ( default: dump
)。Dragonfly 固有の引数もいくつかあります。
memcached_port
: Memcached 互換 API を有効にするポート ( default: disabled
)。
keys_output_limit
: keys
コマンドで返されるキーの最大数 ( default: 8192
)。 keys
危険なコマンドであることに注意してください。取得したキーが多すぎる場合のメモリ使用量の爆発を避けるために、結果を切り捨てます。
dbnum
: select
でサポートされるデータベースの最大数。
cache_mode
: 以下の新しいキャッシュ設計セクションを参照してください。
hz
: キーの有効期限評価の頻度 ( default: 100
)。周波数が低いと、アイドル時の CPU 使用量が減りますが、エビクション速度は遅くなります。
snapshot_cron
: 分単位の標準 cron 構文を使用した自動バックアップ スナップショットの cron スケジュール式 ( default: ""
)。以下に cron スケジュール式の例をいくつか示します。この引数の詳細については、ドキュメントを参照してください。
Cron スケジュール式 | 説明 |
---|---|
* * * * * | 毎分 |
*/5 * * * * | 5分ごとに |
5 */2 * * * | 2時間ごとの5分に |
0 0 * * * | 毎日00:00(真夜中) |
0 6 * * 1-5 | 月曜から金曜の06:00(夜明け) |
primary_port_http_enabled
: true
の場合、メイン TCP ポートで HTTP コンソールへのアクセスを許可します ( default: true
)。
admin_port
: 割り当てられたポートでコンソールへの管理者アクセスを有効にします ( default: disabled
)。 HTTP プロトコルと RESP プロトコルの両方をサポートします。
admin_bind
: 管理コンソールの TCP 接続を指定されたアドレスにバインドします ( default: any
)。 HTTP プロトコルと RESP プロトコルの両方をサポートします。
admin_nopass
: 認証トークンを必要とせずに、割り当てられたポート上のコンソールへのオープンな管理者アクセスを有効にします ( default: false
)。 HTTP プロトコルと RESP プロトコルの両方をサポートします。
cluster_mode
: クラスター モードがサポートされています ( default: ""
)。現在、 emulated
のみをサポートしています。
cluster_announce_ip
: クラスターコマンドがクライアントに通知する IP。
announce_port
: クラスターコマンドがクライアントおよびレプリケーションマスターにアナウンスするポート。
./dragonfly-x86_64 --logtostderr --requirepass=youshallnotpass --cache_mode=true -dbnum 1 --bind localhost --port 6379 --maxmemory=12gb --keys_output_limit=12288 --dbfilename dump.rdb
引数は次の方法でも提供できます。
--flagfile <filename>
: ファイルには、キーと値のフラグにスペースの代わりに等号を使用して、1 行に 1 つのフラグをリストする必要があります。フラグ値には引用符は必要ありません。DFLY_x
設定します。ここで、 x
フラグの正確な名前であり、大文字と小文字が区別されます。ログ管理や TLS サポートなどのその他のオプションについては、 dragonfly --help
を実行します。
Dragonfly は現在、約 185 の Redis コマンドとcas
以外のすべての Memcached コマンドをサポートしています。 Redis 5 API とほぼ同等の Dragonfly の次のマイルストーンは、基本機能を安定させ、レプリケーション API を実装することです。必要なコマンドがまだ実装されていない場合は、問題を開いてください。
Dragonfly ネイティブのレプリケーションでは、桁違いの高速化をサポートする分散ログ形式を設計しています。
レプリケーション機能に続いて、Redis バージョン 3 ~ 6 API に不足しているコマンドを追加し続けます。
Dragonfly でサポートされている現在のコマンドについては、コマンド リファレンスを参照してください。
Dragonfly には、シンプルでメモリ効率の高い、単一の統合された適応型キャッシュ アルゴリズムがあります。
--cache_mode=true
フラグを渡すことで、キャッシュ モードを有効にできます。このモードがオンになると、Dragonfly は、 maxmemory
制限に近づいた場合に限り、今後遭遇する可能性が最も低いアイテムを排除します。
有効期限の範囲は最大 8 年に制限されています。
ミリ秒精度の有効期限 (PEXPIRE、PSETEX など) は、 2^28ms を超える期限については最も近い秒に四捨五入されます。誤差は 0.001% 未満であり、大きな範囲でも許容されるはずです。これがお客様のユースケースに適していない場合は、ご連絡いただくか、ケースを説明する問題を開いてください。
Dragonfly の有効期限と Redis 実装の詳細な違いについては、ここを参照してください。
デフォルトでは、Dragonfly はメイン TCP ポート (6379) を介した HTTP アクセスを許可します。そうです。Dragonfly には、Redis プロトコルまたは HTTP プロトコル経由で接続できます。サーバーは、接続の開始時に自動的にプロトコルを認識します。ブラウザで試してみてください。 HTTP アクセスには現在あまり情報がありませんが、将来的には役立つデバッグおよび管理情報が含まれる予定です。
URL :6379/metrics
に移動して、Prometheus 互換のメトリクスを表示します。
Prometheus でエクスポートされたメトリクスは、Grafana ダッシュボードと互換性があります。こちらを参照してください。
重要! HTTP コンソールは、安全なネットワーク内でアクセスすることを目的としています。 Dragonfly の TCP ポートを外部に公開する場合は、 --http_admin_console=false
または--nohttp_admin_console
を使用してコンソールを無効にすることをお勧めします。
Dragonfly は、2022 年にインメモリ データストアが設計された場合にどのようなものになるかを確認するための実験として始まりました。メモリ ストアのユーザーおよびクラウド企業で働いていたエンジニアとしての経験から学んだ教訓に基づいて、私たちは 2 つのデータストアを維持する必要があることを認識していました。 Dragonfly の重要なプロパティ: すべての操作に対してアトミック性が保証され、非常に高いスループットでミリ秒未満の低遅延が保証されます。
私たちの最初の課題は、現在パブリック クラウドで利用可能なサーバーを使用して、CPU、メモリ、および I/O リソースを最大限に活用する方法でした。これを解決するために、シェアードナッシング アーキテクチャを使用します。これにより、スレッド間でメモリ ストアのキースペースを分割できるようになり、各スレッドが辞書データの独自のスライスを管理できるようになります。これらのスライスを「シャード」と呼びます。ここでは、シェアードナッシング アーキテクチャのスレッドと I/O 管理を強化するライブラリがオープンソース化されています。
マルチキー操作のアトミック性を保証するために、私たちは最近の学術研究の進歩を利用しています。 Dragonfly のトランザクション フレームワークを開発するために、論文「VLL: メイン メモリ データベース システムのためのロック マネージャーの再設計」を選択しました。シェアード ナッシング アーキテクチャと VLL の選択により、ミューテックスやスピンロックを使用せずにアトミックなマルチキー操作を構成できるようになりました。これは私たちの PoC にとって大きなマイルストーンであり、そのパフォーマンスは他の商用ソリューションやオープンソース ソリューションよりも際立っていました。
私たちの 2 番目の課題は、新しい店舗のためにより効率的なデータ構造を設計することでした。この目標を達成するために、私たちは論文「Dash: Scalable Hashing on Persistent Memory」に基づいてコアのハッシュテーブル構造を構築しました。この論文自体は永続メモリ ドメインを中心としており、メイン メモリ ストアとは直接関係ありませんが、それでも私たちの問題に最も当てはまります。この論文で提案されているハッシュテーブルの設計により、Redis ディクショナリに存在する 2 つの特別なプロパティを維持することができました。データストアの拡張中の増分ハッシュ機能、ステートレス スキャン操作を使用した変更時のディクショナリの走査機能です。これら 2 つの特性に加えて、Dash は CPU とメモリの使用効率が高くなります。 Dash の設計を活用することで、次の機能をさらに革新することができました。
Dragonfly の基盤を構築し、そのパフォーマンスに満足したら、Redis と Memcached 機能の実装に進みました。これまでに、約 185 個の Redis コマンド (Redis 5.0 API とほぼ同等) と 13 個の Memcached コマンドを実装しました。
そして最後に、
私たちの使命は、最新のハードウェアの進歩を活用して、クラウド ワークロード向けに、適切に設計された超高速でコスト効率の高いインメモリ データストアを構築することです。当社は、製品 API と提案を維持しながら、現在のソリューションの問題点に対処するつもりです。