Build 2020 で発表があった Cosmos DB の Serverless がプレビューとして公開されました。Autoscale が 1 時間毎の最大 RU で課金がされるのに対して、Serverless は完全に消費した RU によって課金が行われます。
Cosmos DB チームはブログとドキュメントを頑張っているので、この二つで大体理解できるはずです。
ある程度予想はしていましたが、それなりに制限が多いので使う際には注意したいところです。プレビュー中のみの制約もあると思いますが、気になる点はフィードバックを投げると GA に向けて検討されるようです。
個人的に気になった点と注意した方が良い点をピックアップしておきました。
- 単一のリージョンでのみ利用可能
- Geo Replication は設定できない
- Serverless 専用の Cosmos DB アカウントを作成する必要がある
- GA の時にはこの辺りは変わりそう (Autoscale みたいに変更可能とかになるのでは?)
- SQL API でのみ利用可能
- Change Feed とかはちゃんと使える
- プレビューの期間中の制約っぽい
- Container 単位でキャパシティ上限が決まっている
- 最大 5,000 RU と 50GB のストレージ
- 物理パーティションキーとの兼ね合いが気になる
- RU の単価はリージョンによって異なるが大体 10 倍ぐらい
- 1,000,000 RU 当たりで金額が決まっている
- 1,000,000 RU 当たりの単価とストレージ 1GB の単価が大体一致している
この 5000 RU と 50GB という上限はプレビュー中の制限ではないかと思います。GA では変わりそうです。
ユーザー側で RU の上限が指定できないのは結構怖いですね。Azure Monitor などで使用量をきっちりと把握しておかないと、アプリの不具合などで異常に RU を消費するコードになっていても 5000 RU までは問題なく動いてしまいます。アラートの設定は必要になるでしょう。
実際に Serverless な Cosmos DB を作成して、大量にデータを書き込んで RU の消費と 429 周りの確認をしておきました。メータリングは正しいことが確認できたので安心です。
Serverless 用アカウントを作成する
現在は Serverless 用アカウントは Azure Portal でしか作成できないらしいので、CLI 派の人も諦めて Azure Portal からポチポチ作る必要があります。ARM 側の対応が出来ていないのでしょう。
作成時に Provisioned throughput と Serverless を選べるようになっています。後から変更は出来ません。
あまり関係ないですが、Azure Portal だと作成にどのくらい時間がかかるかを教えてくれるようになっていました。正確さは不明ですが、作成に時間がかかるサービスだと不安になるので安心出来ます。
教えてくれた通り大体 3 分ぐらいで作成完了したので、適当な名前で Database と Container を作成していきます。RU の指定が不要なので、異常にすっきりした UI になりました。
Container 単位での RU とストレージ上限になっているので、上手く TTL と組み合わせつつ使うのが良さそうです。まだ慣れないですが消費した RU で課金されるので、Change Feed の Leases Container を同じ DB に入れる必要は無かったりします。
RU 上限まで書き込みをテスト
作成した Container に対してちゃんと 5000 RU 以上を書き込んでみるために、Cosmos DB SDK の Bulk API を使って大量のデータを短時間に書き込むことにします。
ただし項目のサイズがあまりにも小さい場合は件数が増えてしまって、ネットワークレイテンシの影響が無視できなくなるので大き目のデータを書き込むようにします。
既に Bulk API については以前書いていたのでサンプルコードは載せませんが、10000 件の項目を書き込みつつ 495200 RU を消費することが出来ました。
上限の 5000 RU を超えたため 429 が発生し、Azure Portal には以下のような警告が出ました。429 が出ない世界は難しいですが、最近は SDK が優秀なのであまり問題はないです。
Provisioned throughput の場合は RU を増やすように言われていたと思いますが、Serverless の場合は対応しようがないのでメトリックの確認へ誘導されます。
相変わらず Cosmos DB の画面から確認できるメトリックは分かりにくいので、個人的には Azure Monitor 側から確認するのをお勧めしています。こっちなら合計 RU も簡単に確認できます。
Bulk での書き込みを 2 回行ったので、約 99 万 RU を消費したことが確認できますね。結構な量のように見えますが、実際にいくらぐらい課金されるのか計算してみます。
Serverless の価格について
ドキュメントには価格についての情報があまりないですが、Azure の Pricing の方に Serverless の情報が既に追加されているので、ここから各リージョンの金額を調べることが出来ます。
ちなみに Japan East の Serverless の金額は以下のようになります。日本円にすると 1,000,000 RU で約 32 円ですが、これが高いのか安いのかはこのままだとあまり想像が付きませんね。
1,000,000 Serverless request units (RU) $0.285
比較のために通常の Provisioned throughput と 1 時間当たりの金額を合わせてみることにします。Japan East だと 100 RU/s 当たりの金額は以下のようになります。
100 RU/s single-region account 1 x $0.009/hour
Provisioned throughput は 1 時間当たりの金額なので、100 RU/s の場合は最大で 360000 RU を消費できることになります。ここから Serverless との RU 単価差を計算できます。
Provisioned throughput 360,000 RU = $0.009 Serverless 1,000,000 RU = $0.285 360,000 RU = $0.1026
分かっていたことですが、Serverless は RU の単価だけを見ると 10 倍近く高いです。しかし Serverless は Provisioned throughput とは異なるワークロードに適用されるため、単価だけでの比較は意味がありません。
先ほどの Bulk API での実行でかかった金額を計算してみることにします。Provisioned throughput では 1 秒使っただけでも最低 1 時間分は課金されることに注意が必要です。
Provisioned throughput 5000 (RU) / 100 * $0.009 = $0.45 Serverless 990,000 (RU) / 1,000,000 * $0.285 = $0.28215
実際に消費された RU 分で計算を行うと、Serverless の方が圧倒的に安いことが分かりますね。ストレージ容量は含まれていませんが、これは両方とも同じ金額のようなので省いています。
Provisioned throughput で 5000 RU を設定しているのは、Serverless と同じ時間で処理を完了させるためです。つまり時間方向に処理を平準化すれば、また金額は変わってきます。Serverless はこのバースト性が非常に大きなメリットでもありますね。
ドキュメントでもいくつかの例と共に金額について説明が行われているので、こちらも参照してください。
それぞれの使い分けですが、事前にアプリケーションの要件を理解して設計することがますます重要になってきたという印象です。要件をしっかり理解しないとデータモデリングは出来ないし、適切な課金モデルすら選べないようになってきた感があります。
個人的にはもっと大規模なサービスにも適用できるものを期待していましたが、これはこれで Free Tier と Provisioned throughput の間をきっちり埋めることが出来るのではないかと。