Cosmos db 图与 Azure Sql Server - 性能和成本

Posted

技术标签:

【中文标题】Cosmos db 图与 Azure Sql Server - 性能和成本【英文标题】:Cosmos db graph vs Azure Sql Server - Performance and cost 【发布时间】:2018-08-10 11:16:29 【问题描述】:

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

我正在尝试为该应用程序获取有效的 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 查询运行时间超过 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 并获得类似的结果。

【问题讨论】:

只是一个旁注,但 我不断听到和阅读关于 nosql 和 cosmos db 非常棒的消息,所以我想从中受益! -> 这是有史以来最糟糕的原因。您不需要仅仅因为它又热又亮就使用新技术。如果它没有带来真正的好处,请不要打扰。 我同意,也许我没有正确表达自己。多年来我没有打扰。但我知道我的 sql 服务器和地理复制面临问题。欧洲以外的用户抱怨性能。所以我认为是时候看看 cosmos db 了。 我认为很难比较这两者之间的性能。它们就像苹果对橘子。我可以想象,对于数十亿个关系,Graph Api 可能会更快,但您必须设置大量测试才能找到临界点(如果有的话)。 虽然我正在做这一切来比较 sql server 和 cosmos db,但问题是关于如何改进图形和/或查询的具体问题。 您能否在答案中包含哪个 gremlin 客户端?此外 order(local) op 对结果没有影响,因为被迭代的类型是 Vertex 而不是 Collection 或 Map,请参阅 [Order step][tinkerpop.apache.org/docs/3.3.1/reference/#order-step]. 【参考方案1】:

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

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

通常要知道最好的分区键,您应该首先从查询开始,例如,记下您的所有查询并检查您过滤查询以取回数据的***属性或字段。您选择的属性是分区键。

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

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

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

【讨论】:

【参考方案2】:

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

我还看到你没有使用任何partition key,这意味着Graph查询会慢很多。

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

【讨论】:

以上是关于Cosmos db 图与 Azure Sql Server - 性能和成本的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 LINQ 针对 Azure Cosmos Document DB SQL API 有效地进行动态查询?

Azure 函数:如何将 http 触发器函数的查询字符串参数绑定到 Cosmos DB 的 SQL 查询

Azure 流分析输出到 Azure Cosmos DB

无法使用 Microsoft.EntityFrameworkCore.Cosmos 连接到 Azure Cosmos Db 帐户 - 响应状态代码

Cosmos db 使用 Java SDK 部分更新 SQL api

Cosmos DB 更改源触发 Azure 函数:租赁丢失异常