去年の Build で発表されていた Cosmos DB の Burst Capacity ですが、当時は Private Preview に近い形だったのでサインアップが必要で検証をしていなかったのですが、最近何となくドキュメントを確認するとサインアップの記述が消えていたので試しました。
Burst Capacity について簡単に説明すると、各物理パーティションが 5 分間での余った RU/s を貯めておいて、必要なタイミングで貯めておいた RU を上乗せする機能です。貯めておいた RU は物理パーティション単位で最大 3000 RU/s で消費が可能です。
Cosmos DB を使う上で避けられない 429 を Burst Capacity を利用すると、かなりのケースで回避できるようになると期待しています。発表された当時から Burst Capacity を利用するとかなり Cosmos DB の利用コストを最適化出来ると考えていたので、ようやくですが気軽に試せるようになって嬉しいです。
ドキュメントも多少変わっているはずなので、もう一度目を通しておくと良いです。まだ Preview なことには変わりないので、GA の際には動作が変わる可能性がありますし、GA しない可能性もあるかもしれません。
Autoscale は 1 時間単位の課金となってしまうので、Burst Capacity が秒単位の部分をいい感じに埋めてくれると期待しています。今年の Build で GA になって欲しいですね。
どのくらい前からサインアップが不要になっていたのかは把握していませんが、今は Azure Portal の Features に Burst Capacity と Partition Merge が表示されているので、条件が整っていれば自由に有効化出来ます。
当然ながら Provisioned Throughput の場合のみ Burst Capacity は有効になります。Serverless にはアイドル状態の RU という概念が存在しないので当然です。
Autoscale と組み合わせると 10 倍の Autoscale 上限に対して、更に Burst Capacity によって最大 3000 RU/s が上乗せできるため、GA した際には Autoscale + Burst Capacity で RU の調整は必要なくなりそうです。詳細は FAQ に一通りまとまっているので目を通しておくのが良いです。
Burst Capacity の上限は 3000 RU/s となっていますが、実際には物理パーティションが関わってくる点は注意です。1 つの物理パーティション当たり 3000 RU/s 以上のスループットが割り当てられている場合には Burst Capacity は利用されないため、将来的には物理パーティションの分割が最適化で必要になるかも知れません。
説明はこのくらいにして、実際に Burst Capacity を有効化して動作を確認していきます。Azure Portal から Features にある Burst Capacity (Preview) を有効化するだけで使い始めることが出来るので、Cosmos DB SDK のバージョンアップといったようなコード側での変更などは必要ありません。
検証に使用する Container は Provisioned Throughput で 400 RU を割り当てておきました。アクセスが全くない場合には、計算上は 5 分間で貯められるアイドル RU は 120000 RU にもなるはずです。それを最大 3000 RU/s で消費するので最短で 40 秒後には使い切ることになります。
Burst Capacity の有効化と Container の作成が終われば、適当なコードを書いて Cosmos DB に対して書き込み負荷を掛けるだけです。Cosmos DB SDK の Bulk を利用すると効率よく RU を使い切ることが出来ます。
負荷を掛けた後は Azure Monitor を使って RU の消費を確認しますが、Burst Capacity で消費された RU を確認するには "Total Request Units (Preview)" を使う必要があります。このメトリックには CapacityType
が追加されているので、Split すればすぐに把握できます。
まずは軽めに Bulk で書き込みを行った際のメトリックですが、ProvisionedCapacity
よりも BurstCapacity
の方が数倍多く消費されていることが確認出来ます。これは Burst Capacity を有効化していなかった場合は 429 が大量に出ていたことを表しています。
画像は貼りませんが同じ時間帯の 429 の発生を確認したところ 0 となっていました。計算上でも Monitor 上でも Burst Capacity 的にはまだまだ余力があることが分かりますね。
今度はもっと大量のデータを Buk で書き込みを行った際のメトリックです。途中で 429 エラーとなってしまったのでメトリックに 0 の時が出てしまいましたが、時間が経つにつれて BurstCapacity
が減っていき、逆に ProvisionedCapacity
が増えていることが分かります。まだ Preview なので具体的な挙動についての考察はあまり意味がないのですが、Provisioned Throughtput を使い切っていなくても Burst Capacity を利用しているように見えます。この辺りは GA のタイミングでの説明を期待したいですね。
最終的には BurstCapacity
が 0 になり、ProvisionedCapacity
のみとなりました。これは Burst Capacity によって貯めておいた RU が完全に無くなってしまったことを表しています。今回は途中でアイドル状態を作ってしまったので計算が合いませんが、本来なら BurstCapacity
の合計値は 120000 となるはずです。
ここまでの結果から分かるように、Burst Capacity は 3000 RU/s 以下の物理パーティションを持つ Container が存在する場合には、有効にしない方が圧倒的に損するというレベルの機能です。デフォルトで有効化しておいてほしい機能なので、GA の際にはオプトアウトになることを期待したいです。