Azure Cosmos DB的重写入分区密钥策略

时间:2020-02-04 21:04:52

标签: azure azure-cosmosdb partitioning database-partitioning

我们在生产环境中使用CosmosDB来存储HTTP请求/响应审核数据。该数据的结构通常如下:

{
    "id": "5ff4c51d3a7a47c0b5697520ae024769",
    "Timestamp": "2019-06-27T10:08:03.2123924+00:00",
    "Source": "Microservice",
    "Origin": "Client",
    "User": "SOME-USER",
    "Uri": "GET /some/url",
    "NormalizedUri": "GET /SOME/URL",
    "UserAgent": "okhttp/3.10.0",
    "Client": "0.XX.0-ssffgg;8.1.0;samsung;SM-G390F",
    "ClientAppVersion": "XX-ssffgg",
    "ClientAndroidVersion": "8.1.0",
    "ClientManufacturer": "samsung",
    "ClientModel": "SM-G390F",
    "ResponseCode": "OK",
    "TrackingId": "739f22d01987470591556468213651e9",
    "Response": "[ REDACTED ],   <— Usually quite long (thousands of chars)
    "PartitionKey": 45,
    "InstanceVersion": 1,
    "_rid": "TIFzALOuulIEAAAAAACACA==",
    "_self": "dbs/TIFzAA==/colls/TIFzALOuulI=/docs/TIFzALOuulIEAAAAAACACA==/",
    "_etag": "\"0d00c779-0000-0d00-0000-5d1495830000\"",
    "_attachments": "attachments/",
    "_ts": 1561630083
}

我们目前正在写大约150,000-200,000份类似于上述一天的文档,其中/PartitionKey是在容器上配置的分区键路径。 PartitionKey的值是C#.net中在0到999之间随机生成的数字。

但是,我们看到每天的热点中,单个物理分区的最高速度可以达到2.5K-4.5K RU / s,而其他物理分区却非常低(大约200 RU / s)。由于需要为最大利用分区分配吞吐量,因此这对成本产生了影响。

第二个因素是我们存储了相当多的数据,接近1TB的文档,并且每天增加几GB。结果,我们目前大约有40个物理分区。

结合这两个因素,我们最终不得不至少提供120,000-184,000 RU / s之间的资源。

我应该提到,我们几乎不需要查询此数据;除了偶尔在Cosmos数据浏览器中进行临时手动构建的查询之外。

我的问题是...通过简单地使用“ id”列作为我们的分区键(或随机生成的GUID),在所需的RU / s和数据分配方面会好很多吗-然后设置合理的TTL,所以我们没有持续增长的数据集?

我知道这将要求我们重新创建集合。

非常感谢。

Max throughput per physical partition

2 个答案:

答案 0 :(得分:0)

尽管使用id或GUID可以提供比今天拥有的随机数更好的基数,但是您运行的任何查询都将非常昂贵,因为它始终是跨分区的,并且涉及大量数据。

我认为一个更好的选择是使用一个综合键,该键结合了多个具有高基数并且还用于查询数据的属性。可以在这里https://docs.microsoft.com/en-us/azure/cosmos-db/synthetic-partition-keys

了解更多信息

就TTL而言,我绝对会为该数据所需的保留时间进行设置。 Cosmos会以未使用的吞吐量关闭TTL数据,因此永远不会成为问题。

最后,您还应该考虑(如果尚未使用)自定义索引策略,并排除任何从未查询过的路径。特别是“响应”属性,因为您说它的长度为数千个字符。在像您这样的写繁重场景中,这可以节省大量RU / s。

答案 1 :(得分:0)

根据我的经验,我发现宇宙倾向于随着新数据而降低。更多数据意味着更多身体参与。因此,您需要分配更多的吞吐量才能分配给它们中的每一个。当前,我们开始将旧数据归档到Blob存储中,以避免此类问题并保持物理分区数不变。我们使用波斯菊作为热存储,然后将旧数据作为blob存储作为冷存储。我们减少了分配给每个物理分区的RU,从而节省了资金。