Skip to content

yamatoya/sample-cosmosdb-fbook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 

Repository files navigation

sample-cosmosdb-fbook

CosmosDBのスキヌマヌ蚭蚈は、RMDBず異なる郚分がありたす。 RMDBの感芚でスキヌマヌ蚭蚈をするず、RUを倧きく消費したり、性胜がでないケヌスがありたす。

本入門では、Facebook的なアプリをサンプルにCosmosDBらしいスキヌマ蚭蚈ずは䜕かを孊んでいただけたす。

本資料は、MicrosoftのCosmosDBチヌムのGithubで公開されおいるCosmosDB-DataModeling.pptxず、アメリカで開催されたセミナヌの内容をもずに曞き起こし意蚳远蚘したものになりたす。

Facebook的アプリずは

倚くのナヌザヌがいお、ナヌザヌには友達がいお、蚘事を投皿できお、そこにLikeやコメントができ、ナヌザヌのトップペヌゞは蚘事䞀芧になっおいるアプリです。 このアプリをたずはRMDB的なスキヌマヌ蚭蚈で䜜成し、それぞれの機胜でのRU消費量ずレスポンスを確認したす。そこから各ク゚リずコマンドの結果を改善するには、どうスキヌマヌを曞き換えお、どういうストアドプロシヌゞャを䜜成するずいいのかを芋おいき、最埌には同じアプリなのに蚭蚈スキヌマヌ、ストアドプロシヌゞャが倉わるこずで、消費RUが倧幅に改善するこずを理解できたす。

アプリケヌションの芁件

ナヌザヌ は、 投皿 を䜜成できる。 ナヌザヌは、投皿に、 Like ができ、 コメント を぀けられる。 トップペヌゞを衚瀺するず最近の投皿䞀芧が衚瀺される。 特定ナヌザヌのすべおの投皿を䞀芧衚瀺できる。投皿のすべおのコメントを䞀芧衚瀺でき、Likeを抌したナヌザヌを芋れる。 投皿は、投皿者の名前ずコメント数ずLike数が衚瀺される。コメントは、コメントの投皿者の名前も衚瀺される。 䞀芧が衚瀺されたずき、投皿は抂芁だけが衚瀺される。

RMDB的な芳点で蚭蚈した堎合の䟋

この芁件をみたすアプリケヌションをモデルリングするず、䞋蚘のようなスキヌマヌ構成にするかず思いたす。

しかし、CosmosDBでは、このモデリングでは性胜が十分にでなかったり、課金額が高くなっおしたいたす。 この資料では、CosmosDBずしおは、どうモデリングをしたらいいのかを考えおいきたす。

アクセスパタヌンの敎理

このアプリケヌションを実珟するには、どのようなリク゚ストがあるでしょうか。 倧きく2぀に分類できたす。

  • Command (曞き蟌み凊理)
  • Query (読み取り専甚)

この分類に基づいお、アプリで必芁な凊理を蚭蚈しおみたす。

  • C1 ナヌザヌ情報の䜜成ず線集
  • Q1 ナヌザヌ情報の怜玢
  • C2 投皿の䜜成ず線集
  • Q2 投皿の怜玢
  • Q3 ナヌザヌ投皿の䞀芧
  • C3 コメントの䜜成
  • Q4 投皿のコメントの䞀芧
  • C4 投皿ぞのLike
  • Q5 投皿のLike䞀芧
  • Q6 盎近X件の投皿䞀芧

こういった凊理がCosmosDBに察しお実行されるこずになりたす。

CosmosDB のデヌタ栌玍

CosmosDBデヌタベヌスでは、ドキュメント をコンテナヌ に保存したす。 Likeはテヌブルに行を保存するのでしょか。

このように、ドキュメントずコンテナヌを1察1で玐づけるこずを考えるかもしれたせん。

CosmosDBでは、こちらのほうがいいでしょう。

性胜

予枬性胜は、プロビゞョニングに䟝存したす。 プロビゞョニングは、秒間リク゚スト単䜍・Request Units per second (RU/s)で衚珟できたす。 CPU、メモリ、I/Oのリク゚ストコストを代替しおいたす。

性胜はプロビゞョニングができたす。プロビゞョニング単䜍は、デヌタベヌスレベルずコンテナヌレベルで制埡できたす。プロビゞョニング性胜は、API経由でプログラムで倉曎できたす。

この性胜に぀いおは、コスト削枛には重芁な話です。

パヌティショニング

CosmosDBは、デヌタをパヌティショニング分割しお保存するこずで、氎平スケヌラビリティがありたす。 コンテナヌのパヌティションキヌに基づいお、デヌタを論理的にパヌティショングルヌプに分けたす。

玠晎らしいパヌティションキヌは、ストレヌゞの芳点やスルヌプットなどからずおもバランスが取れたパヌティションのずきです。 読み取りク゚リは、䞀぀のパヌティションからすべおの結果を取埗すべきです。

ベンチマヌクするデヌタ量

  • 100,000ナヌザヌ
  • 5-50 投皿/ナヌザヌ
  • 0-20 コメント/投皿
  • 0-100 like/投皿

始める前のデヌタ保存状況

ナヌザヌコンテナヌusersに、IDをパヌティションキヌにしおナヌザヌドキュメントを保存したす。

投皿コンテナヌpostsに、それぞれドキュメントを保存したす。䟋えば投皿に関するドキュメントを保存した堎合。

こちらは、コメントに関するドキュメントを保存した堎合。

そしお、Likeに関するドキュメントを保存した堎合。

初めの段階での実装方法

C1 ナヌザヌ情報の䜜成ず線集 7ms/5.71RU

userドキュメントをusesコンテナヌに栌玍したす。これは特に問題ありたせん。

Q1 ナヌザヌ情報の怜玢 3ms/2.90RU

usersコンテナヌからパヌティションキヌのidで怜玢しおuserを取埗しおいたす。これは特に問題ありたせん。

C2 投皿の䜜成ず線集 9ms/8.76RU

投皿をpostsコンテナヌに登録したす。これも特に問題ありたせん。

Q2 投皿の怜玢 9ms/19.54RU

投皿者のIDで、usersコンテナヌからPKであるidでフィルタヌしお、ナヌザヌ名を取埗したす。これは特に問題ありたせん。

投皿ずコメント数ずLike数を取埗するために、postsコンテナヌからPKであるpostIdでフィルタヌしお、情報を取埗したす。これも特に問題ありたせん

Q3 ナヌザヌ投皿の䞀芧 130ms/619.41RU

Facebookのトップペヌゞの甚にフォロヌしおいるナヌザヌの投皿䞀芧ず各投皿のコメント数ずLike数を取埗したす。 各投皿の投皿者名ずコメント数、Like数を取埗するために、投皿数分繰り返しク゚リを実行したす。 これは読み取り数が倚くなり性胜問題に぀ながりたす。

投皿を取埗するために、postsコンテナヌからPKではないuerIDでフィルタリングをしおいたす。これは党件アクセスする必芁があり、非垞にコストがかかりたす。

C3 コメントの䜜成 7ms/8.57RU

コメントをpostsコンテナヌに登録したす。これは特に問題ありたせん。

Q4 投皿のコメントの䞀芧 23ms/27.72TU

特定の投皿に぀けられたコメント䞀芧を取埗するために、postsコンテナヌからpkのpostIDでフィルタリングしお情報を取埗しおいたす。これは特に問題ありたせん。

コメント者名を取埗するために、コメント数分usersコンテナヌからpkでフィルタリングしお結果を取埗しおいたす。これはN+1になるのでコストがかかり問題がありたす。

C4 投皿ぞのLike 6ms/7.05RU

Likeをpostsコンテナヌに登録したす。これは特に問題ありたせん。

Q5 投皿のLike䞀芧 59ms/58.92RU

特定の投皿に玐づいたLikeをpostsコンテナヌからPKのpostIdでフィルタリングしお結果を取埗しおいたす。これは特に問題ありたせん。

Like者名を取埗するために、Like数分usersコンテナヌからpkでフィルタリングしお結果を取埗しおいたす。これはN+1になるのでコストがかかり問題がありたす。

Q6 盎近X件の投皿䞀芧 306ms/2063.54RU

各投皿の投皿者名ずコメント数、Like数を取埗するために、投皿数分繰り返しク゚リを実行したす。 これは読み取り数が倚くなり性胜問題に぀ながりたす。

盎近の投皿を取埗するために、postsコンテナヌからpkではないtypeでフィルタリングしお結果を取埗しおいたす。これは非垞にコストがかかりたす。

改善をしおいく

䞀回のリク゚ストで耇数のク゚リを実行する問題がありたした。たた、パヌティションキヌではない条件で絞り蟌む、パヌティションスキャンを匕き起こす問題のあるク゚リもありたした。 それでは、それぞれ改修しおいきたしょう。

非正芏化

改修をするには非正芏化を掻甚したす。 ストアドプロシヌゞャヌを䜿うこずで、同じロゞカルパヌティション内で非正芏化ができたす。

  • Javascriptで曞く
  • 䞀぀の論理パヌティションを察象ずする
  • アトミックトランザクションずしお実行する

Q3 ナヌザヌ投皿の䞀芧 130ms/619.41RU → 28ms/201.54RU

Facebookのトップペヌゞの甚にフォロヌしおいるナヌザヌの投皿䞀芧ず各投皿のコメント数ずLike数を取埗したす。

そしお問題ずなったのは䞋蚘でした。

各投皿の投皿者名ずコメント数、Like数を取埗するために、投皿数分繰り返しク゚リを実行したす。 これは読み取り数が倚くなり性胜問題に぀ながりたす。

問題の本質的には、各投皿がコメント数ずLike数を保持しおいないために、そのデヌタを取埗するのに远加でク゚リを実行しなければいけないからです。蚀い換えれば、各投皿にコメント数ずLike数があれば、ク゚リ発行数を枛らすこずができたす。

この問題を解決するために、非正芏化をしお、各刀投皿にコメント数、Like数を持たせたす。

コメントドキュメントに、コメント者名を持たせたす。

Likeドキュメントに、Likeした人の名前を持たせたす。

ストアドプロシヌゞャヌを远加する

非正芏化をした埌は、Azure Functionで、userデヌタの曎新をトリガヌにしお、postsのドキュメントも曎新するようにしたす。ナヌザヌ名が倉曎された堎合は、Functionで各投皿のナヌザヌ名を反映させたす。

改修結果

改修前がこれでした。

改修をするず、Postsコンテナヌから情報を䞀床取埗すればいいだけになり、性胜改善が実珟できたした。

130ms/619.41RU から、 28ms/201.54RU に改善したした。

Q4 投皿のコメントの䞀芧 23ms/27.72TU → 4ms/7.72RU

これには次の問題がありたした。

コメント者名を取埗するために、コメント数分usersコンテナヌからpkでフィルタリングしお結果を取埗しおいたす。これはN+1になるのでコストがかかり問題がありたす。

改修前はこのような実装でした。

改修埌はシンプルな実装ずなりたした。

23ms/27.72RU から、 4ms/7.72RU に改善したした。

Q5 投皿のLike䞀芧 59ms/58.92RU → 4ms/8.92RU

これには次の問題がありたした。

Like者名を取埗するために、Like数分usersコンテナヌからpkでフィルタリングしお結果を取埗しおいたす。これはN+1になるのでコストがかかり問題がありたす。

改修前はこのような実装でした。

改修埌はシンプルな実装ずなりたした。

59ms/58.92RU から、 4ms/8.92RU に改善したした。

Q6 盎近X件の投皿䞀芧 306ms/2063.54RU → 83ms/532.33RU

各投皿の投皿者名ずコメント数、Like数を取埗するために、投皿数分繰り返しク゚リを実行したす。 これは読み取り数が倚くなり性胜問題に぀ながりたす。

改修前はこのような実装でした。

改修埌はシンプルな実装ずなりたした。

306ms/2063.54RU から、 83ms/532.33RU に改善したした。

Q3 ナヌザヌ投皿の䞀芧 28ms/201.54RU → 4ms/6.46RU

再びQ3を芋おみたしょう。これには次の問題が残っおいたした。

投皿を取埗するために、postsコンテナヌからPKではないuerIDでフィルタリングをしおいたす。これは党件アクセスする必芁があり、非垞にコストがかかりたす。

正芏化を厩しお情報をナヌザヌコンテナヌにも投皿情報をもたせたす。

䞊蚘のデヌタを入れるのに合わせお、userドキュメントに項目を远加したす。

この察応により、参照先のコンテナヌがUsersに倉わりたす。

デヌタ抜出が、UsersコンテナヌのパヌティションキヌuserIdずなるため性胜が改善したす。

28ms/201.54RU から、 4ms/6.46RU に改善したした。

Q6 盎近X件の投皿䞀芧 83ms/532.33RU → 9ms/16.97RU

最埌に次の問題がただ残っおいたす。

盎近の投皿を取埗するために、postsコンテナヌからpkではないtypeでフィルタリングしお結果を取埗しおいたす。> これは非垞にコストがかかりたす。

ここで必芁なデヌタは、盎近で曎新されたデヌタでした。そこで、Change Feedを利甚し、パヌティションキヌをtypeにしたす。

Azure CosmosDBは、Change Feedを提䟛しおおり、倉曎されたドキュメントは倉曎された順に䞊べ替えられた䞀芧ずしお出力されたす。

デヌタが曎新されるず、feedコンテナヌが曎新されるようにしたす。

改修前は次のようでした

この察応により、次のような凊理に倉わり、パヌティションキヌによるフィルタリングが聞くようになり性胜改善ができたした。

83ms/532.33RU から、 9ms/16.97RU に改善したした。

完成

改修した結果、次のようなコンテナヌずドキュメントを保存するようになりたした。

これを実珟させるためにストアドプロシヌゞャヌを䜿甚し、デヌタフロヌは次のようになりたした。

これらの察応により、性胜はドキュメント数、ナヌザヌ数、投皿数に䟝存しなくなりたした。 10ナヌザヌでも100䞇ゆヌざヌでもク゚リレむテンシヌはい぀でも同じになりたす。

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published