PHONE APPLI Engineer blog

エンジニアブログ

CosmosDBで大量のデータを書き込む時にToo Many Requestsが出てしまった場合

リサーチデベロップメントの たかはしとし( @doushiman_jp ) です。

最近、部屋のサボテンが枯れました。

CosmosDB で少しハマったことがあったんですが、大量のデータを書き込もうとしたときにToo Many Requests が表示されてしまうことがありました。

RU の上限値は理論上足りているはずなのに、Too Many とはなんぞ? と。

おかしいな?? と思って調べているとドンピシャっぽいドキュメントが。

CosmosDB への要求率の問題らしいと。要求率?

ドキュメントに従いスループットを確認すると、まさにこのスクリーンショットの状態でした。

どうやらホットパーティションが発生しているようです。

CosmosDB は通常、パーティションごとに分散して処理が実行されるのですが、このパーティション( = PartitionKeyRangeID )はその名の通り、パーティションキーに依存しています。

ここは僕の勘違いなのですが、大量の書き込み処理が発生した場合、CosmosDB 側がいい感じに物理ーパーティション内で処理を分散してくれるものと思っていました。

論理パーティション、物理パーティションに関してはこちらを参照

データの構造的には、同一のパーティションキーを持つレコードが、大量に存在(1万レコード以上)している状態だったのですが、この場合、処理は分散されず、一つの論理パーティションにのみ集中してしまっていたことから(実際、一つのユニットはRU が100% 消費され、それ以外は全て0%になっていました)、処理が多すぎる!となっていたと思われます。

論理パーティションごとに処理が割り振られることを知らなかった、ということですね。

解決法としては、単純にRU の上限値を増やす、も必要ですが、今回のケースの場合上限値は適切と考えられるため、処理を分散させてやればいい、となります。

物理パーティションを分けてあげる必要があるため、パーティションキーを変更して明示的に処理を分散させる方法を取りました。

今までは同一のパーティションキーに大量のレコードがぶら下がっていたため、合成パーティションキーを作成してみます。 参照記事

元々、各レコードは、ユニークな値を持っていたので「固定のID + テーブル内ユニークな値」でパーティションキーを作成しました。

これで処理が分散されて、エラーが発生しなければ成功ですが・・・結果は

無事、処理が分散されていることが確認できました。(まだ遊んでる子はいますが・・・(笑))

コンソールを見てもエラーは出ていないため、対応としては正解だったかと思います。

CosmosDB で 大量のデータを書き込む場合に、パーティションの構成に気をつけたほうがいい場合があるよ、というお話でした。

ではでは。


PHONE APPLIについて

phoneappli.net
phoneappli.net