- GarnetはMicrosoft Researchが開発したリモートキャッシュストアで、RESPワイヤプロトコルをベースにしており、既存のRedisクライアントを変更なしで利用できる
- 多数のクライアント接続と小さなバッチにおいて、比較対象となるオープンソースのキャッシュストアよりもスループットとスケーラビリティが高く、Azure VMでAccelerated Networkingを有効にした場合、99.9パーセンタイルのレイテンシがしばしば300マイクロ秒未満になる
- 最新の.NETベースでLinuxとWindows上で動作し、C#でユーザー定義演算・ストアドプロシージャ・モジュールを作成でき、Luaスクリプトもサポートする
- ストレージ層のTsavoriteは、メモリ・SSD・クラウドストレージの階層化、ノンブロッキングチェックポイント、リカバリ、耐久性のための操作ログ、マルチキートランザクション、クラスターモードでのシャーディング・レプリケーション・動的キーマイグレーションをサポートする
- 新機能としてVector Sets PreviewとRange Index Previewが追加され、Garnetの論文はVLDB 2026に掲載予定
Garnetが提供するリモートキャッシュストア
- GarnetはMicrosoft Researchの新しいリモートキャッシュストア
- RESPワイヤプロトコルを出発点として採用し、複数のプログラミング言語の既存Redisクライアントを変更なしで利用できる
- 例としてC#のStackExchange.Redisを利用できる
- 多数のクライアント接続と小さなバッチにおいて、比較対象となるオープンソースのキャッシュストアよりも優れたスループットとスケーラビリティを提供し、大規模アプリやサービスのコスト削減につながる可能性がある
- 一般的なAzure VMでAccelerated Networkingを有効化した場合、99.9パーセンタイルのクライアントレイテンシがしばしば300マイクロ秒未満になる
- 最新の.NET技術を基盤とし、クロスプラットフォーム・拡張可能・モダンな構造を目指している
- 一般的なケースの性能を犠牲にせず、開発と進化を容易にするよう設計されている
- .NETライブラリエコシステムを活用してAPIの幅を広げ、最適化の余地を残している
- LinuxとWindowsの両方で最新水準の性能を達成する
- フルマネージドサービスが必要な場合、Azure Cosmos DB Garnet CacheがGarnetを高可用性、性能保証、インフラ管理不要のエンタープライズ向けキャッシングソリューションとして提供する
最近追加された機能と論文
- Vector Sets Previewは近似最近傍探索を提供する
- DiskANNアルゴリズムとGarnetのTsavoriteストレージエンジンを基盤とする
- 初期結果では、GarnetはQPS、p99レイテンシ、recallで優位な結果を示している
- Range Index PreviewはGarnetのキー上に補助的な範囲・等価インデックスを提供する
- Bf-Treeを基盤とする
- Garnetの論文はVLDB 2026に掲載予定
- 論文名はGarnet: A Next-Generation Cache-Store for Accelerating Applications and Services
- PDFが提供されている
APIと拡張モデル
- GarnetはさまざまなAPIを実装している
- 生文字列: get、set、キー有効期限
- 分析演算: HyperLogLog、Bitmap
- オブジェクト演算: sorted set、listなど
- マルチキートランザクションをサポートする
- クライアント側RESPトランザクション
- C#ベースのサーバー側ストアドプロシージャとモジュール
- ユーザーは生文字列とユーザー定義オブジェクト型の両方に対してユーザー定義演算を作成できる
- C#の利便性と安全性を活用し、カスタム拡張開発の参入障壁を下げる
- Luaスクリプトもサポートする
ネットワーク・セキュリティ・ストレージ層
- Garnetは高速でプラグイン可能なネットワーク層を使用する
- 将来的にカーネルバイパススタックの活用などの拡張を可能にする
- セキュア通信は.NETのSslStreamライブラリを使用してTLSをサポートする
- 基本的なアクセス制御を提供する
- ストレージ層であるTsavoriteは高性能を目的に設計されており、複数のデータベース機能を含む
- スレッドスケーラビリティ
- メモリ、SSD、クラウドストレージを含む階層型ストレージ
- 高速なノンブロッキングチェックポイント
- リカバリ
- 耐久性のための操作ログ
- マルチキートランザクション
- より優れたメモリ管理と再利用
設計構造
- Garnetの設計は、ネットワークパケットの受信からデータベース演算のパース・処理、ストレージとの相互作用まで、キャッシュストアスタック全体を再設計している
- ネットワーク層は共有メモリ設計を基盤とする
- TLS処理とストレージとの相互作用がネットワークIO完了スレッドで実行される
- 一般的なケースではスレッド切り替えのオーバーヘッドを避ける
- 従来のシャッフルベースのネットワーク設計のようにサーバーの適切なシャードへデータを移動する代わりに、CPUキャッシュの一貫性によってデータを処理ロジック側へ持ってくる
- ストレージ設計は、統合操作ログで結び付けられた2つのTsavoriteキー・バリューストアで構成される
- main storeは生文字列演算に最適化され、ガベージコレクションを避けるためにメモリを慎重に管理する
- 任意のobject storeは複雑なオブジェクトとユーザー定義データ型に最適化されている
- object storeはSorted Set、Set、Hash、List、Geoなどの型を含む
- object storeのデータ型は現行実装で.NETライブラリエコシステムを活用している
- オブジェクトはメモリヒープ上では更新が効率的な形で、ディスク上ではシリアライズされた形で保存される
- 将来の保守を容易にするため、統合インデックスとログの利用を検討する予定
- Garnetの差別化要因は、くびれた形のTsavoriteストレージAPIである
- このAPIの上に、大規模で豊富かつ拡張可能なRESP APIサーフェスを実装している
- 読み取り、upsert、削除、アトミックなread-modify-write演算で構成される
- 非同期コールバックにより、各演算中の複数の地点でGarnetのロジックを介入させることができる
- パースとクエリ処理の関心事を、並行性、ストレージ階層化、チェックポイントといったストレージ詳細から分離する
- マルチキートランザクションには2フェーズロックを使用する
クラスターモードと運用上の制約
- Garnetは単一ノード実行に加えてクラスターモードをサポートする
- シャーディングとレプリケーションを備えたデプロイを作成・管理できる
- シャードの再バランスのために効率的で動的なキーマイグレーション方式をサポートする
- ユーザーは標準のRedisクラスターコマンドでGarnetクラスターを作成・管理できる
- ノードはgossipを行い、クラスター状態を共有し発展させる
- Garnetのクラスターモード設計は現在passiveである
- リーダー選出を実装していない
- ユーザーが提供するcontrol planeが発行したクラスターコマンドに応答する
- 関連内容はcontrol planeドキュメントにある
ドキュメントとライセンス
- より詳しい情報とドキュメントはGarnetドキュメントサイトで確認できる
- 始めるにはgetting startedドキュメントを参照できる
- リリース情報はreleasesセクションにある
- プロジェクトはMIT Licenseで提供される
1件のコメント
Hacker Newsのコメント
ベンチマーク性能チャート(https://microsoft.github.io/garnet/docs/benchmarking/results...)を見ると、GETスループットがDragonflyより10倍以上高い
50%レイテンシはDragonflyよりやや高いが、99パーセンタイルはやや低い
GarnetとDragonflyはいずれもスループットとレイテンシがRedisよりはるかに優れており、Redisには相当な性能最適化が必要に見える
最適化が本当に必要かは分からないし、ここにはすでに代替が3つある
ただしGarnetは低い同時実行性と高い同時実行性の両方でRedisを上回る初の代替なので印象的で、早く使ってみたい
DragonflyはC++、RedisはCで書かれている
Garnetのストレージ層であるTsavoriteはオープンソースのFASTERから分岐したもので、スレッドスケーラビリティ、階層型ストレージ(メモリ、SSD、クラウドストレージ)、高速なノンブロッキングチェックポイント、リカバリ、耐久性のためのオペレーションログ、マルチキートランザクション、より良いメモリ管理と再利用といった強力なデータベース機能を含む
https://www.microsoft.com/en-us/research/blog/introducing-ga...
当時取り組んでいた高性能要件の概念実証プロジェクトで、永続化ライブラリとしてかなり有望だと見ていた
ちなみに、どちらのプロジェクトも同じ人物が率いているように見える [1]
[1]: https://github.com/badrishc
Microsoftと.NETチームが、自分たちでインフラをハックするように作っているプロジェクトはかなり印象的
Yarpはリバースプロキシ/APIゲートウェイ/その他必要なものは何でもこなすツールで、今度のGarnetはメモリキャッシュ向け
社内需要が非常に大きく、それを共有しようという意思もあるように見える
Azure App Serviceにこういうものが組み込まれているといいと思う
キャッシュのために必ずリモートサービスを使わなくても済むように、という意味
以前はIISでASP.NETアプリにプロセス外セッション状態ストアを置く方式が一般的だった
Webアプリのプロセスが再起動しても、ユーザーがセッションを失って最初からログインし直さなくて済むようにするためだった
もちろんSQL Serverのような中央ストアに置くこともできるが、そうするとすべてのWebページリクエストが処理前にセッション状態のロードを待つことになる
セッション状態は通常何らかの形でロックされるため、性能上の問題も多い
現在の一般的な解決策はキャッシュとセッション状態にRedisを使うことだが、概ねそれなりに動く
スループットは高いものの、RedisはAzureでは別リソースであり、ばかげたほど高価
こんな単純なものにOracle DB並みの料金を払いたくないし、接続構成もかなり面倒
この記事では300マイクロ秒の応答時間をうたっているが、ゾーン冗長設計ではすべてのAzureロードバランサがランダムなゾーン選択を使うため、あまり意味がない
ランダムなゾーンのWebサーバーが選ばれ、さらにランダムなゾーンのキャッシュサーバーに接続することになる
そのサーバーにキーがなければ、さらに別のランダムなゾーンへ行ってキャッシュデータを取得しなければならないかもしれない
トラフィックがデータセンター間をピンポンし、その結果1〜3msの遅延が生じ、Garnetの宣伝値より最大10倍遅くなる
理想的なシナリオはMicrosoft Service Fabricのreliable collections[1]のようなもの
各ホストノードでローカルに実行され、他の2ノードに複製する
Webアプリは常に同じ物理ホストからキャッシュ値を読める
場合によってはレイテンシが1桁マイクロ秒まで下がり、どれだけ最適化された外部サービスでも単純なロードバランシング方式ならこれより数千倍遅い
Redisより30%速いのではなく、3,000倍速いものが欲しい
[1] https://learn.microsoft.com/en-us/azure/service-fabric/servi...
サービスを常にローカルサービスに向かわせることも、別のルーティングトポロジーに構成することもできる
DNSやアプリケーションキャッシュにとても向いている
レイテンシとスループットのベンチマーク値がかなり印象的なRedis代替品
Azureではないスタックで本番運用するとどう見えるのか気になる
xstreamサポートに関する表示が見当たらない
Garnet being multi-threaded, MSET is not atomic. For an atomic version of MSET, you would need to express it as a transaction (stored procedure).この部分がよく理解できない
なぜ内部でトランザクションに包んでコマンドをアトミックにしないのだろう
また、どんなアトミック性の落とし穴があるのかも気になる
MSETのアトミック性が不要なすべての人にも性能コストが発生し、そのトランザクションをオフにする方法がなくなる逆にRedisのドロップイン代替を目指すなら、Redisはアトミック性を保証するのでこれは問題になる
少なくともドロップイン代替が設計目標なら、互換性と性能のどちらを取るかを選べる設定オプションを用意してもよさそう
確かに印象的
Microsoft Researchは時々すごいプロジェクトを出してくるし、研究開発をしながら給料をもらえるのは楽しそう
大企業には、業界全体の役に立つ研究開発寄りのプロジェクトをもっとやってほしい
Hashicorpが売りに出ているなら、良い会社に買収されてほしい
Microsoft Windows ServerでWSL2に頼らずRedis互換サーバーを直接動かさなければならない人にとっては、とても良いニュース
以前はRedisの移植版[1]があったが、今はアーカイブ状態で、メモリ使用量の問題があり(知る限り主にメモリマップトファイルのため)、もうサポートされていない
C#で書かれている点も個人的にはかなり興味深い
C#が主言語なので、時間を作ってコードを掘ってみたい
[1]: https://github.com/microsoftarchive/redis
これが実際の本番環境でどこに使われているのか見てみたい
「何千ものユニットテストと、Microsoftのファーストパーティチームで数年間Garnetを本番デプロイしてきた後、今こそ公開する時だと感じた」という部分がある
https://microsoft.github.io/garnet/blog
ここのコメントを見ると、もう誰もmemcachedを使っていないように見える
LRUキャッシュが欲しかったのにオプションが複数あり、説明も分かりにくくて、なぜ項目が次々と追い出されるのか分からなかった
Redisに切り替えると設定が簡単で、期待どおりに動いた