kt.log

Recreation test of Azure Cosmos DB for NoSQL containers

Azure Cosomos DB for NoSQL コンテナーの再作成テスト

きっかけは Stack Overflow における以下のコメント書き込みでした。

https://stackoverflow.com/questions/57539722/how-to-clear-a-cosmos-db-database-or-delete-all-items-using-azure-portal#comment128170605_57544949

Do not delete containers! I’ve just had to create a support request to ask Microsoft to kindly increase the resources in my region because I cannot recreate the container. I spent 30 minutes trying at the end of day yesterday, and 15 minutes at the start of today –

Red

Jun 9, 2022 at 8:15

Stack Overflow における大元の質問は How to clear a Cosmos DB database or delete all items using Azure portal というタイトルで、4 つの回答のうち、2 番目に vote を得ている回答に対して、上記のコメントがついている形です。ちなみにその 2番目の回答の趣旨はコンテナーの再作成です。

この Red 氏のコメントを意訳すると、 「コンテナーを削除したらリージョンのクォータにひっかかったままとなり、コンテナーの新規作成ができなかった。なので、コンテナーを削除してないけない」 ということであると私は理解しました。

まさかそんなことがあるはずないとは思いつつ、それがありえないという悪魔の証明はできません。ここは私の謙虚さと良心に従い、 Red 氏の言い分が真であると仮定します。

まずは原則として、Cosmos DB のコンテナーに関する制約あるいはクォータを以下のページから確認します。

Azure Cosmos DB service quotas | Microsoft Learn

そこから、本件に関する情報として以下の 4点が確認できます。

# Resource Limit
1 Maximum number of containers per database with shared throughput 25
2 Maximum number of containers per account 500 (Provisioned), 100 (Serverless)
3 Maximum containers per subscription (NoSQL, Gremlin, API for Table) 1 (Try Cosmos DB Free)
4 Maximum number of containers in a shared throughput database 25 (Azure Cosmos DB free tier)

ここで、 Red 氏はサポートリクエストを上げたとのことですので、 Try Cosmos DB Free (試用版) のユーザーではなく、3 番の筋はありません。

そこまでは分かるのですが、そこから先は憶測でしか議論ができません。
例えば、クォータ一杯までコンテナーを作成していて、削除が完全に完了してコンテナー数のカウントが減少する前にコンテナーを新規作成しようとしていたのではないかとか、複数人で Cosmos DB アカウントを共用していて、他の方のコンテナー作成により、Red 氏による新規作成時にクォータに達してしまったのではないかとか、あるいは、2022年6月という時期から、特定のリージョンやゾーン (データセンター) におけるサーバーのハードウェアリソースが枯渇していて、Cosmos DB のコンテナー作成に一時的な制約がかかっていた可能性も考えられなくはないとか。これらは全て確証の取りようがない憶測です。 (なお、Stack Overflow 上で Red 氏に質問をするには至りませんでした。)

机上の検討だけでは手詰まりです。そこで、実証主義的なアプローチによって、Red 氏の主張について検証を行いました。

検証

以下を確認する検証を行います。

  • コンテナーの再作成 (削除→作成) が常に可能かどうか
    • すなわち、コンテナーの削除→作成のシナリオにおいて、コンテナーの再作成に失敗するケースを再現できるかどうか
  • クォータの根拠となるコンテナー数のカウント(※)は、コンテナーの削除により減少するかどうか
    • すなわち、作成したコンテナーを削除しても、前述のクォータに達してしまうかどうか
    • ※ 25 (共有スループットのデータベース内におけるコンテナー数の上限), 500 (アカウント内におけるプロビジョニングされたスループットのコンテナー数の上限)

なお、以下については本検証のスコープ外とします。

  • 上記確認事項について、コンテナー内のデータ量との関係性
    • 検証に用いるコンテナーにはアイテムを含めません。
  • 単一のコンテナー名での検証
    • 純粋にコンテナー数のクォータに関する検証を行いたいため、コンテナー名にはある程度ばらつきを持たせます。
  • リージョンやゾーンごとの比較
    • 本検証においてリージョンは Japan East を使用します。そのため、Red 氏が使用したリージョン特有の問題かどうかは確認できません。
  • レースコンディションでの挙動
    • 全ての検証ステップは単一の Azure ユーザーかつ単一プロセスでシーケンシャルに実行します。
  • Azure CLI 以外の手段による検証
    • 今回の検証において最も効率的な手段 (CLI) を選択した結果、Azure Portal, REST API, SDK 等を使用した場合に問題が発生するかどうかは確認しません。

検証環境

macOS Monterey 12.6.3

前提

  • jq がインストールされている
  • Azure CLI がインストールされている
  • az login 実行済み
  • Azure Cosmos DB for NqSQL のアカウントが存在し、その配下にデータベースが作成済み

検証スクリプト

以下の内容の検証用シェルスクリプトを用意し、ターミナルで実行しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env bash

RG='rg-CosmosDB-20230225a-JapanEast'
Account='cosmos-20230225a-japaneast-nosql'
DB='testdb'
Container='testcontainer'
PK='/name'

i=0
i_max=502
d=3

retval=0
sleep_sec=5


get_the_number_of_containers() {
length=`
az cosmosdb sql container list \
-g ${RG} \
-a ${Account} \
-d ${DB} \
| jq 'length'
`

echo $length
}


if [ `get_the_number_of_containers` -ne 0 ]; then
echo "ERROR: The number of containers must be zero."
exit 1
fi


date
echo "INFO: cosmos-db-container-recreation-test successfully started."

while [ $i -lt $i_max ]; do
n=`expr $i % $d`
echo "INFO --------------------------------"
echo "INFO i = ${i}, Container = ${Container}${n}"
echo "INFO --------------------------------"

ret=`
az cosmosdb sql container create \
-g ${RG} \
-a ${Account} \
-d ${DB} \
-n ${Container}${n} \
-p ${PK}
`

num=`get_the_number_of_containers`
if [ $num -ne 1 ]; then
echo "ERROR: Container creation ${Container}${n} failed due to the number of containers ${num}."
retval=1
break
fi
echo -n "Create container: Container name is "
echo $ret | jq '.name'
echo " The number of containers is ${num}"


sleep $sleep_sec


az cosmosdb sql container delete \
-g ${RG} \
-a ${Account} \
-d ${DB} \
-n ${Container}${n} \
-y

num=`get_the_number_of_containers`
if [ $num -ne 0 ]; then
echo "ERROR: Container deletion ${Container}${n} failed due to the number of containers ${num}."
retval=1
break
fi
echo "Delete container: finished"
echo " The number of containers is ${num}"


sleep $sleep_sec


i=`expr $i + 1`
done


if [ $retval -eq 0 ]; then
echo "INFO: cosmos-db-container-recreation-test successfully finished."
fi
date
exit $retval

標準出力

標準出力には以下の内容が出力され、コンテナーの作成と削除が 502回実行され、すべて成功したことが確認できました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
[2023-02-25 10:23:41]% time ./cosmos-db-container-recreation-test.sh
Sat Feb 25 10:23:49 JST 2023
INFO: cosmos-db-container-recreation-test successfully started.
INFO --------------------------------
INFO i = 0, Container = testcontainer0
INFO --------------------------------
Create container: Container name is "testcontainer0"
The number of containers is 1
Delete container: finished
The number of containers is 0
INFO --------------------------------
INFO i = 1, Container = testcontainer1
INFO --------------------------------
Create container: Container name is "testcontainer1"
The number of containers is 1
Delete container: finished
The number of containers is 0
INFO --------------------------------
INFO i = 2, Container = testcontainer2
INFO --------------------------------
Create container: Container name is "testcontainer2"
The number of containers is 1
Delete container: finished
The number of containers is 0

(中略)

INFO --------------------------------
INFO i = 499, Container = testcontainer1
INFO --------------------------------
Create container: Container name is "testcontainer1"
The number of containers is 1
Delete container: finished
The number of containers is 0
INFO --------------------------------
INFO i = 500, Container = testcontainer2
INFO --------------------------------
Create container: Container name is "testcontainer2"
The number of containers is 1
Delete container: finished
The number of containers is 0
INFO --------------------------------
INFO i = 501, Container = testcontainer0
INFO --------------------------------
Create container: Container name is "testcontainer0"
The number of containers is 1
Delete container: finished
The number of containers is 0
INFO: cosmos-db-container-recreation-test successfully finished.
Sat Feb 25 21:29:40 JST 2023
./cosmos-db-container-recreation-test.sh 1711.37s user 778.98s system 6% cpu 11:05:53.83 total
1
2
[2023-02-25 21:29:40]% echo $?
0

結論

上記検証により、以下のことが言えます。

  • 本検証の範囲において、コンテナーの再作成は常に可能である
  • クォータの根拠となるコンテナー数のカウントは、コンテナーの削除により減少する
    • よって、作成したコンテナーを削除している限りは、前述のクォータに達することはない

まとめ

Stack Overflow におけるあるコメント書き込みに関して、真偽の程を実証主義的に確認しました。結論としては、Red 氏の主張とは異なり、 コンテナーの再作成 (削除→作成) は可能 であり、 サポートリクエストを使ってリソース数の上限 (=クォータ) を引き上げる必要も無い ことが確認できました。

検証のスコープ外としている項目が数点ありますが、これらに対応しようとすると、問題の重要度や信憑性のわりに検証のコストがかかりすぎてしまいますので、今回はここで筆を置きたいと思います。

See also