×

Azure Cosmos DB を使ってみる 【初心者の備忘録】

目次 [隠す]

Cosmos DB ロゴ
出典:Microsoft Docs

概要

10年以上システム開発のブランクがあります。
ただいま趣味でスマホアプリを開発中です。
アプリの詳細はリリースできたらあらためて書きたいと思います。

今回は、そのアプリでデータの永続化先として「Microsoft Azure Cosmos DB」を使うことにしたので、色々調べたりしたことの備忘録です。

Microsoft Azureとは

公式

Azure とは — Microsoft クラウド サービス | Microsoft Azure

世界規模のデータセンター ネットワークを介してインテリジェントなアプリケーションの構築、デプロイ、管理ができるクラウド サービスである Microsoft Azure を利用して、新しいソリューション

blog card

Cosmos DBとは

公式

Azure Cosmos DB の概要 | Microsoft Docs

Azure Cosmos DB について説明します。 このグローバルに分散されたマルチモデル データベースは、少ない待ち時間、柔軟なスケーラビリティ、高可用性を実現し、NoSQL データのネイティブ

blog card

この度もっともお世話になった記事

Azure Cosmos DB入門

Azure Cosmos DB入門(目次) - ryuichi111stdの技術日記

「Azure Cosmos DB入門」目次 DocumentDB が Azure Cosmos DB としてリニューアルされたので、改めてこのサービスの全体像を整理したコンテンツ(ブログ)を「Cosm

blog card

経緯

ガッチガチの業務システムしか経験がなくリレーショナルDBしか知らなかったわたくしです。

「コンシューマ向けスマホアプリだとDBは何がいいのだ?」から始まり、
「NoSQL」とは??、
「なんかいっぱいある!?」を経て、
「.NET開発経験者(10年以上のブランクあるけど)にやさしそう」ということで「Cosmos DB」をいっちょ使ってみようとなった次第です。

わたしにとって「やさしそう」といのはあくまで他のサービスと比較して、ドキュメントのサンプルがC#だったりするぐらいの話しです。

Azure?、NoSQL?、DocumentDB?、Partition?、RU?、と登っていく階段は非常に多くあります。

とりあえず、公式のドキュメントを読み込み、上記リンク先の「ryuichi111stdの技術日記」さんのAzure Cosmos DB入門を読破することでようやくCosmos DBの入口に立てた気がします。

Azure上にCosmos DBの内容や実際に構築する手順は上記に貼った、公式、Azure Cosmos DB入門に詳しくあるのでそちらをご参照ください。

この記事では、上記リンク先に載っていなかった個人的に調べたことなどをまとめます。

本編

Azure Cosmos DB の料金

使ってみたいと思ったものの、いったいどのぐらいの費用がかかるのか気になるわけです。

Cosmos DBは主に下記の項目に対して課金されます。(2020年1月17日時点)

  • データストレージ - (1GBあたり ¥31.640/月)
  • 予約済みの要求ユニット数(RU) - (100RU/秒あたり ¥735.84/月)
  • 追加リージョン - (上記項目 x 追加リージョン数が課金され、RUについては係数がかかる場合有り)

これらは下記サイトで「リージョン:東日本」、「通貨:日本円」、「単位:月」を選択した際のものとなります。

価格 - Azure Cosmos DB | Microsoft Azure

フル マネージドの NoSQL データベースである Azure Cosmos DB の価格情報を入手して、最新のアプリ開発を行いましょう。初期費用不要.従量課金制。無料試用版。

blog card

データストレージはわかります。
で、RUとは何か。

RUについて

要求ユニット (RU) とは、Azure Cosmos DB におけるスループットの単位です。 1 RU のスループットは、1 KB のドキュメントを取得するスループットに相当します。

とあります。

そして、RUは「予約済み」の分が課金対象となります。

つまり、使った分だけ課金系とは異なり、1秒間で処理できる計算量を予め登録し、実際にその計算量を使うかどうかに関わらず課金とのこと。

RUについては、公式だけではいまいち理解しきれなかったので、Azure Cosmos DB入門の(2)の解説がとても助かりました。

リージョンについて

Cosmos DBは、Azureが世界30か所以上に展開する各地域の拠点にレプリケーションが可能であり、これを使用した場合に追加拠点分が、課金に掛かるとのこと。

日本国内のリージョンを選択し国内向けにサービスする分には必要ないかな。

ただ海外ユーザを視野に入れた場合、バックエンドで各リージョンに同期してくれたり、ユーザが近いリージョンを利用することでネットワークの遅延を回避できたりなど素晴らしいサービスが用意されているのは心強い。

Azure Cosmos DB でデータをグローバルに分散させる | Microsoft Docs

グローバル分散型のマルチモデル データベース サービスである Azure Cosmos DB のグローバル データベースを使用した、地球規模の geo レプリケーション、マルチリージョン書き込み、フェ

blog card

Azure Cosmos DB Free レベル

ざっと料金体系を記してみましたが、実際にわたしが必要とするストレージやRU予約枠はどのぐらいなのかが見通せていないのが現状です。

そんなわたしのような小規模運用者やテスト利用をしたい方向けに「Free レベル」という枠が設けられています。

Azure Cosmos DB Free レベルを使用できるようになりました | Azure の更新情報 | Microsoft Azure

新しい Azure Cosmos DB Free レベルでは、Microsoft サービスの使用をこれまで以上に簡単に開始できます。これを使用して、アプリケーションの開発とテスト、小規模なワークロード

blog card

新規にAzure Cosmos DBのリソースを作成する画面に、「Free レベル割引の適用」という項目があるので、これを「適用」にすることで、「毎月 400 RU/秒のプロビジョニング スループットと 5 GB のストレージ」を無料で使用することができます。

ちなみに、FreeレベルのCosmosDBアカウントは、1 Azure サブスクリプションに 1 つまでしか作成できません。

Freeレベルを選択すれば無料!というわけではなく、いくつか設定で注意が必要です。
下記サイトに注意点がわかりやすく説明されています。
Azure Cosmos DB の無償枠 (Free Tier) の注意点

また、Azureアカウントをこれから作成する方には、無料サービスが付いているので参考までリンクを貼っておきます。

Azure の無料アカウントを今すぐ作成しましょう | Microsoft Azure

200 米国ドルのクレジットで 12 か月の無料サービスの利用を開始できます。Microsoft Azure の無料アカウントを今すぐ作成しましょう。

blog card

Azure Cosmos DB サーバーレス (プレビュー)

料金の話ばっかり長くなっていますが、大切なことなのでもう少し。

わたしのような最弱小規模デベロッパーにとってはありがたい課金モデルがプレビューで公開されています。

Azure Cosmos DB の従量課金ベースのサーバーレス プラン | Microsoft Docs

Azure Cosmos DB の従量課金ベースのサーバーレス プランの詳細について説明します。

blog card

上記で説明した、RUという処理能力を予約する課金モデルではなく、制限がかかるが使った分だけの従量課金となります。

現時点ではまだプレビューとのことで、一般提供時にどのような条件になるかわかりませんが、わたしはおそらくこちらで十分な予測をしています。

今後、あたらしい情報があれば追記します。

エミュレータのこと

お金の話ばっかりですみません、と言いつつ節約に関連しての話しとなります。

課金体系は理解できつつも、これからいざ実装に向けてテスト使用をするにあたり、マイナスからスタートのわたしは余裕でFreeレベル突破してしまうのではないかと不安になります。

でもだいじょうぶ。エミュレータがあるもの。

Azure Cosmos DB Emulator を使用したローカルでのインストールと開発 | Microsoft Docs

Windows、Linux、macOS、および Windows Docker 環境に Azure Cosmos DB Emulator をインストールして使用する方法について説明します。 エミュレータ

blog card

これは本当に助かりました。

実際にDocumentDBとはどんなものかを探りながら、いくら叩いても無料ですし。

SDK Version.3について

C#とVisualStudio大好きマンなので、Xamarin Formsです。

Azure Cosmos DB入門ではCosmos DBのSDKはVersion2で説明が載っていますが、現時点ではVersion3がリリースされています。

最初、Ver.2で開発し、途中でこちらの記事を発見しVer.3に書き換えたのですが、クラス名などは異なるものの、CRUDを行う部分についてはそれほど違いはありませんでした。

Azure Cosmos DB .NET SDK v3 GA 記念チートシート - しばやん雑記

5 月の Build で月末 GA が発表されていた Azure Cosmos DB の .NET SDK v3 ですが、昨日ついに正式版がリリースされました。特に Public Preview の時

blog card

Singleton推奨

公式にパフォーマンスに関するTipsが掲載されています。

ClientインスタンスはSingletonでの実装が推奨されています。

アプリケーションの有効期間中はシングルトン Azure Cosmos DB クライアントを使用する 各 CosmosClient インスタンスはスレッドセーフであり、直接モードで動作しているときには効率的な接続管理とアドレスのキャッシュが実行されます。 効率的な接続管理と SDK クライアントのパフォーマンス向上を実現するために、アプリケーションの有効期間中は、AppDomain ごとに単一のインスタンスを使用することをお勧めします。

またこんな記事も。

Cosmos DB を利用する上で最初にはまった部分のメモ - しばやん雑記

Twitter でおーみさんに Cosmos DB についていろいろ聞いたので、忘れないようにメモっておきます。kyrt.in に書いてあればみんな幸せになりそうなんですが、いつ書いてくれるかわからな

blog card

時間はUniversalTime推奨

Cosmos DB の DateTime 文字列に推奨される形式は、ISO 8601 UTC 標準に準拠した yyyy-MM-ddTHH:mm:ss.fffffffZ です

とのことです。

C#であれば、書き込み時に ToUniversalTime() 、読み込んだら ToLocalTime() をする必要があります。

SQLでいろいろできる

現在開発中のアプリでは、ある日付項目の年と月をDistinctして取得したい箇所があります。

その項目の全レコードを取得してから加工するのと、どちらが課金・パフォーマンス的に良いのかまだわかっていないのですが、こんなSQLを書いて取得することもできたよという例です。

var utcOffset = TimeZoneInfo.Local.BaseUtcOffset.TotalHours;

// クエリを作成
var sb = new StringBuilder();
sb.Append(@"SELECT DISTINCT");
sb.Append(@" DateTimePart(""yyyy"", DateTimeAdd(""hour"", @utcOffset, c.TargetDate)) AS Year");
sb.Append(@",DateTimePart(""mm"", DateTimeAdd(""hour"", @utcOffset, c.TargetDate)) AS Month");
sb.Append(@" FROM c");

var query = new QueryDefinition(sb.ToString())
    .WithParameter("@utcOffset", utcOffset);

var queryRequestOptions =
        new QueryRequestOptions
        {
            PartitionKey = new PartitionKey(userId.Value.ToString()),
        };

var iterator = container
    .GetItemQueryIterator(
        query,
        requestOptions: queryRequestOptions);

ポイントは、TargetDate というカラムの年と月を取得する箇所です。

まずDateTimeAdd関数で hour を @utcOffsetでローカルタイムにし、DateTimePart関数で YYYY(年) および mm(月)を取得しています。

Distinct は普通に使えます。

  DateTimePart(""yyyy"", DateTimeAdd(""hour"", @utcOffset, c.TargetDate)) AS Year

DateTimePart(""mm"", DateTimeAdd(""hour"", @utcOffset, c.TargetDate)) AS Month
  

最後に

参考になる方がいるかわかりませんが、個人的に調べて回ったことをざっとまとめてみました。

まだ色々と勉強している段階なのでわかったことがあれば追記します。

間違っている点や、情報などありましたらコメントまたはTwitter (@h_neputa)で教えていただければありがたいです。

長文失礼しました。

Comments

0 件のコメント :