しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Hack Azure! #2 Ask the Geeks - Cosmos DB 編フォローアップ

先週の木曜に "Hack Azure! #2 Ask the Geeks - Cosmos DB 編" と題して、Microsoft Corp の勇さん・ちょまどさん・Azure MVP の三宅さん・大平さんと自分の 5 人で Cosmos DB について話す会を行いました。

今後も #HackAzure ということで Synapse Analytics や Azure AD B2C、App Service / Azure Function など定期的に開催できれば嬉しいなと思っています。

クローズドな場ではなくオープンな場で開催し Q&A やライブコーディングなどを行って、楽しく情報を共有していくことに意義があると思っているのでお気軽に参加ください。

今回は Teams Live Event の Q&A 機能を使って、都度質問は簡単なものは横浜さんが回答しつつも、それ以外は Q&A コーナーで全員で話すという形を取りましたが、全てを拾い切れたわけではないのと時間切れなどで端折った部分もあるので、その辺りのフォローアップを行っておきます。

既に動画は公開されていますが、Teams Live Event での Q&A のまとめにはもう少しかかる予定です。

Twitter まとめと YouTube アーカイブ


パーティションキーの変更

Cosmos DB はコンテナーを作成した時に設定したパーティションキーからは変更できない仕様になっているので、後からパーティションキーの設計を変えるのは非常に大変です。

とは言え完全に方法がないわけではなく、公式で以下のようなツールが公開されています。

Azure Data Factory を使ってデータをコピーする方法もあります。

結局のところは新しいコンテナーを作成してデータを全てコピーするだけですが、手間であることには変わりないので事前に PoC などで検証しておいた方が良いです。

Backup & Restore 機能が PITR と同時に予定されているので、多少は簡単になるかもしれません。

とは言え、後からの変更は苦労するだけなので出来るだけ避けたいところです。

消費された RU の確認

Cosmos DB で消費された RU はレスポンスに含まれているので、該当のプロパティを参照すれば簡単に確認できます。設定を有効にすれば統計情報も返ってくるので、極端に重いクエリの調査にも有用です。

実際に稼働しているアプリケーションで RU をモニタリングする場合には、Application Insights にメトリックとして値を送信してしまうのが割とおすすめです。

もしくは Log Analytics へ Cosmos DB のログを書き出すように設定して、KQL で後からクエリを書いて RU を調べるという方法もあります。

現時点ではこのログが一番確実な RU の確認方法のようです。Azure Portal で確認できる値は怪しいです。

Cosmos DB SDK v3 の Preview 機能

.NET 向け Cosmos DB SDK v3 は #if PREVIEW で囲まれた機能は -preview サフィックスの付いたバージョンで利用可能になっています。

Change Feed の Pull Model が代表的ではありますが、今後も新機能はまず Preview として出る可能性が高いので知っておいて損はありません。

Subpartitioning や JSON Patch 対応などは Preview のうちに試しておきたくなる機能です。

Table Storage と Cosmos DB

Table Storage と Cosmos DB について Twitter でちょいちょい見ましたが、もはや Table Storage は Cosmos DB の一部ぐらいの扱いになっていて、しばらく前から Table Storage SDK の公開は行われなくなりました。

現在はドキュメントでも Cosmos DB ベースの SDK を使うように紹介されています。

確かに価格が安いのでシンプルな Key-Value ストレージとして使いたくなりますが、もう今後はアップデートされないのではないかと思っています。*1

v3 SDK でのパフォーマンス Tips

ライブ中に Changelog をいくつか紹介しましたが、公式ドキュメントにもパフォーマンスを改善するためのヒントが結構まとめられています。

v3 SDK からは Stream バージョンの API*2 や Bulk Operation も実装されているので、v2 よりパフォーマンス改善が行いやすいです。

Change Feed の設計パターン

例によって公式ドキュメントが神がかっているので紹介しておきます。大体は Cosmos DB のユースケースとして紹介されている図でも、最近は大体 Change Feed を当たり前のように使っています。

パーティションキー内での順序保証がされるのと、現時点ではデータが残っている限りはリプレイが可能という大きな特徴を持っているので、有効活用していきましょう。

Change Feed の保持期間と制限

Twitter で Change Feed の変更が保持される期間などに制限があるのかという質問が出ていましたが、公式ドキュメントにそういった制限はないことが明記されています。

You can read the change feed for historic items (the most recent change corresponding to the item, it doesn't include the intermediate changes), for example, items that were added five years ago. You can read the change feed as far back as the origin of your container but if an item is deleted, it will be removed from the change feed.

Working with the change feed support in Azure Cosmos DB | Microsoft Docs

Changes can be synchronized from any point-in-time, that is there is no fixed data retention period for which changes are available.

Working with the change feed support in Azure Cosmos DB | Microsoft Docs

コンテナー作成時から遡って Change Feed でデータを扱えるので、整合性を保ったまま新規にインデックスや読み取り用 DB の構築を行うことも簡単です。

具体的には StartTime を過去の値(例えば DateTime.MinValue)にしてしまえば全ての変更を扱えます。

Change Feed の Pull Model (Preview)

Change Feed Processor や Azure Functions の CosmosDBTrigger では変更があった時に、設定したデリゲートや Function が実行されるという Push 型になっていますが、新しく Pull 型の API が v3 SDK の Preview として提供されています。

Change Feed の先のサービスが障害などで書き込めなくなった時に、Circuit Breaker や Exponential Backoff などで回復を待つ処理を柔軟に書けるので、個人的にはかなり有用ではないかと思っています。

Cosmos DB を ASP.NET Core のセッションに使う

最近はセッション自体を使うことが無くなってきたのですが、v3 SDK ベースの IDistributedCache 実装が提供されているので、Redis と比べて信頼性の高いストレージを利用できます。

実際に使う場合には Consistency の設定には注意が必要なので、README をよく読んでおきましょう。

具体的には Session Affinity が有効になっている場合は Session を、それ以外は Bounded staleness や Strong を選ぶという話です。

おまけ : NuGet パッケージのインストールが早い

Core i9-10940X / Optane SSD 900P / 11ax (Wi-Fi 6) という構成のつよつよマシンでお送りしました。

Optane SSD は単価と消費電力が高いですが、現実世界の I/O ワークロードに強いので便利です。

*1:廃止されることは絶対にないが、機能改善などのアップデートはされなさそう

*2:レスポンスを .NET の Stream として返してシリアライズコストを下げる