10

想象一个社交网络应用程序。用户关注其他用户,用户拍照。照片有其他用户的标签。

我正在尝试为该应用程序获取图形的有效 Cosmos db 实现。我提供了一个 SQL Server 版本以及一个基准。

这是图表: 在此处输入图像描述

这是它的表格版本:

在此处输入图像描述

这是 Gremlin 查询:

g.V('c39f435b-350e-4d08-a7b6-dfcadbe4e9c5')
.out('follows').as('name')
.out('took').order(local).by('postedAt', decr).as('id', 'postedAt')
.select('id', 'name', 'postedAt').by(id).by('name').by('postedAt')
.limit(10)

这是等效的 SQL 查询(实际上是 linq):

Follows
.Where(f => f.FollowerId == "c39f435b-350e-4d08-a7b6-dfcadbe4e9c5")
.Select(f => f.Followees)
.SelectMany(f => f.Photos)
.OrderByDescending(f => f.PostedAt)
.Select(f => new { f.User.Name, f.Id, f.PostedAt})
.Take(10)

该用户关注了 136 个用户,他们总共拍摄了 257 张照片。

SQL Server 和 Cosmos db 都位于西欧 Azure 位置。我在法国。我在 Linpad 上做了一些测试。

  • Gremlin Query 运行时间超过 1.20 秒,消耗大约 330 RU。仅供参考,400RU/s 的费用为 20 美元/月。
  • SQL 查询在 70 毫秒内运行。db 为 10 DTU(S0 的 1 个实例)。所以它的成本是 12.65eur / 月

如何使用 cosmos db 更快、更便宜地获取 feed?

注意:为了收取 RU 费用,我使用的是Microsoft.Azure.Graph. 但我也可以使用Gremlin.Net并获得类似的结果。

4

2 回答 2

2

我知道这个问题很老,但这是我的提示,可以帮助您cosmos db以有效的方式使用并RU/s尽可能减少。

330 RU对于这样的查询来说很多,这里让您消耗很多的问题RU是分区,当您将分区添加到数据库时,您告诉您cosmos db通过您提供的分区键对数据进行逻辑分区,所以在您的情况下最好的分区键是用户。

通常,要了解最佳分区键,您应该首先从查询开始,例如写下所有查询并检查过滤查询以获取数据的顶级属性或字段。您选择的属性是分区键。

如果您没有添加分区键,您将告诉cosmosdb搜索用户,并且如果用户在扩展时分布在许多服务器和许多分区上,cosmosdb则将搜索所有分区(服务器),这将花费您很多,所以如果您有例如 6 台服务器,cosmosdb将在 6 台服务器上运行查询,直到找到您的用户,它可能在第一台服务器或第二台服务器中找到它,但也可能在最后一台服务器中找到它,因此这将花费大量时间且无法保证。

第二件事是containers,容器是缩放的单位cosmosdb,所以当cosmosdb想要缩放时,它会缩放容器和容器中的所有数据。所以一个好的做法是在他们自己的容器中添加经常被查询的实体,这样cosmosdb就可以使用分配给每个容器的分区键轻松扩展它们。

也许我帮助你以RU/s不同的方式减少。希望这个答案对面临同样问题的人有所帮助。

于 2020-06-18T20:23:55.957 回答
1

如果你没有注意到,除了关系模型,SQL Server 还有一个图模型,你可以直接在 SQL Server 中使用图查询。

我还看到您没有使用任何分区键,这意味着 Graph 查询会慢很多。

几个月前,对于一种新产品,我们最初进行了几次测试,就像您所做的那样。当记录数较多(几十万的数量级,图遍历次数超过 3 次)时,Cosmos 比 Azure SQL 便宜。

于 2019-05-26T15:33:20.080 回答