從只限制在每秒400個RU的Azure Cosmos DB的世界中解放出來

这篇文章是Microsoft Azure Advent Calendar第7天的文章。
是的,我睡着了。对不起。

首先

为了推出今年四月启动的新服务,我们选择了Azure Cosmos DB作为快速实施Proof of Concept(PoC)所需的数据存储。

选择Azure Cosmos DB的原因有三个。

    1. 我以前没有使用过SQL数据库。

 

    1. Azure数据库有MySQL、PostgreSQL,但它们仍处于预览阶段。

 

    我的团队成员有MongoDB的使用经验。

Azure Cosmos DBはMongoDB Write APIを、完全ではないのですが、サポートしています。ですので、どの言語でもMongoDBのドライバからアクセスが可能です。
しかしながら、利用した時点では稼ぎは無かったため、最安価な構成としてRU/s を最小値の400で使ってきました。
特殊な状況かとは思いますが、そういった状況で使い続けてきた中で発見したことをまとめてみようと思います

Azure Cosmos DB (蓝色天空的宇宙数据库)

Azure Cosmos DB是支持多个API的Azure数据库服务。它包括文档数据库的DocumentDB API、MongoDB API,以及可以表示表格API和网络的图形API。此外,目前还提供了Cassandra API的预览版本。

単にNoSQLを提供するサービスというわけではなく、マルチリージョンでの一貫性をサポートしています。例えば、USにあるCosmos DBに書き込まれたデータが、すぐに東日本のCosmos DBから読み書きできるようになります。また一貫性のレベルも選択することができ、要件に応じてプロビジョニング後にも変更することが可能です。
また、性能については、同一リージョン内での通信速度は高いSLAで提供しています。

组成

我々が利用しているAzure Cosmos DBの構成は、少し特殊な構成です。
DocumentDB APIとして作成していますが、接続はMongoDB APIを使っています。
我々はアプリケーションをPHPで開発しています。ですが、PHPのDocumentDB APIライブラリがあるのですが、長くメンテされていない状態であったため、使い慣れているMongoDB APIで接続しています。
素直に、MongoDB APIとしてプロビジョニングすれば良いかと思われるかもしれませんが、他のAzureのサービス、例えばAzure FunctionsのbindingsやAzure DataFactoryなどがDocumentDB APIでの接続をサポートしているため、DocumentDB APIとしてプロビジョニングしました。
つまり、Azureのサービスとの連携と、自分たちの使いやすさの両方を取ることができました。

MongoDB 应用程序编程接口

Azure Cosmos DB支持使用MongoDB Wire Protocol进行连接。

    MongoDB Wire Protocol — MongoDB Manual 3.6

简而言之,只要您可以连接到MongoDB,基本上就可以连接到Azure Cosmos DB。

但是,并不是所有的MongoDB命令都得到支持。在我们今年春天开始使用的时候,聚合相关的命令是无法使用的(最近,似乎已发布为预览版)。有关支持的命令,请参考下面的内容。

    MongoDB に対する Azure Cosmos DB 機能のサポート | Microsoft Docs

基本的にCRUDはサポートされていますが、aggregationのように集計作業に必要なコマンドはサポートされていません。

充值

Azure Cosmos DBの課金は非常にシンプルです。
全てのコレクションが同一の設定とストレージ使用量を持っていると過程した場合、

1時間あたりのコスト = 
  1コレクションあたりの時間課金 * コレクション数 * レプリケーション数 * コレクション辺りのストレージ容量数に応じた金額 
  + 時間あたりのストレージ金額/GB

で算出できます。コレクションによって、使用するディスク容量は異なりますし、必要とするアクセス数もまた異なります。
この式が表すように、全く利用していなくてもコレクションが存在するだけで課金されます。

需求单位

上記のコレクションごとに課金を決める要因が、要求ユニット(RU)です。
ドキュメントによると、RUとは、

要求単位は、要求の処理コストを標準化した測定単位です。 1 つの要求ユニットは、10 個の一意のプロパティ値 (システム プロパティを除く) で構成される 1 KB のアイテムの読み取り (self リンクまたは ID による) に必要な処理能力を表します。
– 要求ユニットとスループットの推定 – Azure Cosmos DB | Microsoft Docs

つまり、基準となるドキュメント(10個のフィールドを持つ1KB)を処理する時に1秒あたりに必要な処理能力に対して、どれくらい処理能力が必要かをRU/sの値として設定します。

需要注意的是,不是客户端和服务器之间的处理能力,而是托管Azure Cosmos DB的服务器所需的处理能力。例如,考虑下面这个MongoDB的updateMany命令:

db.users.updateMany({}, { $set: { foo: "bar" } })

这意味着我们想要在所有文档中为名为foo的字段赋予值为bar。虽然在服务器和客户端之间交换的信息并不多,但在Cosmos DB上实际上会对所有文档执行添加字段值的操作。 RU/s的配置指定了对这种操作所需的处理能力。

由于这个值很难进行预先估算,所以建议在已知预期文档和数量的情况下试一试,并在运营开始后确认 RU 的消耗量。实际的 RU 消耗量可以通过命令和门户进行确认。

此外,使用MongoDB API时,即使没有预先创建集合,当您尝试将文档保存到集合时,它也会自动创建。请注意,此时会自动设置为1,000 RU/s。最小可设置值为400,所以如果想以最低成本进行操作,需要预先创建集合。然而,MongoDB API没有提供指定RU值来创建集合的命令。因此,您可以使用门户或DocumentDB API来在创建集合时指定该值。指定的值以后可以进行更改。

当超越RU之后会发生什么?

RU在命令执行期间逐渐消耗。如果在1秒内,消耗量超过了指定的RU/s,则处理将被中断并返回错误消息。为了能够处理发生的错误,需要实现应用程序以进行重试。

然而,根据访问负载和集合内文档的数量成比例,RU的消耗也会增加,因此,需要定期检查集合的RU/s,并尝试减少整体消耗量。

增加RU/s

这是最简单的解决方法。
如果您已经知道会消耗很多RU的操作,并且还可以控制该操作的启动,那么您可以临时提高RU/s。
但是,请确保操作按照设置的RU/s进行执行。

创建索引

如上所述,RU是指定 Azure Cosmos DB 所需处理能力的设置。
因此,为提高处理效率,创建索引是一个有效的方法之一。

Azure Cosmos DB默认具有索引设置。但是,此默认设置存在一些问题,

    1. 嵌套文档不会被索引

 

    只会创建用于范围搜索(如>或<=)的索引

关于1,举个例子

{
  "first_name": "Tatsuya",
  "last_name": "Sato",
  "social_accounts": {
     "twitter": "sato_ryu",
     "github" : "satoryu"
  }
}

如果有一个保存像这样的文档集合,那么”first_name”和”last_name”将成为创建索引的目标,但”social_accounts”及其内部的值将不会创建索引。

关于第二点,这意味着即使在查询中写成{ user_name: “sato_ryu” },也不能考虑在内。因此,如果需要考虑等价性,则需要根据需要创建索引。

设定有效期限

处理不再需要的信息,如缓存和会话等,对于处理某一段时间后不再需要的信息非常有效。
虽然有自己准备删除文档的方法,但如前所述,执行删除命令时需要评估整个文档,这将消耗更多的RU。因此,将这个机制交给Azure Cosmos DB来处理。幸运的是,在删除过期文档时消耗的RU似乎很小。

最后

Azure Cosmos DB是一款性能卓越且具有弹性的文档数据库。
除了与RU相关的问题之外,我在使用过程中没有遇到任何其他问题。
然而,随着我开发的应用程序规模变大,

    • 日本国内に限らず各国のリージョンをまたいで提供し、

 

    • 書き込みが多く、その速さも求められ、

 

    そのデータの一貫性も気にしなければいけない

我感觉我们对成本非常敏感,因此我们一直以较低的价格使用RU,而且作为服务的性质,我们只在国内提供,因此很难满足上述任何一个要求。另外,目前我们的服务需要对输入的数据进行聚合处理,而仅仅使用Cosmos DB则非常困难。

我认为我们只是没有找到与Azure Cosmos DB匹配的使用方式,而Cosmos DB本身是一项出色的服务。

希望我在这里写下的经验能够对即将开始使用它们的某人提供帮助。

广告
将在 10 秒后关闭
bannerAds