gpt4 book ai didi

MongoDB 分片键

转载 作者:可可西里 更新时间:2023-11-01 10:39:16 24 4
gpt4 key购买 nike

我们有一个大型 MongoDB 集合,我们希望开始分片。该集合有 3.4B 条记录,大小约为 14.6TB(磁盘上压缩了 5.3TB)。该集合通常每小时写入约 5M,但我们预计这一数字将逐年增长。该集合的索引大小约为 220GB。

所有记录都有一个 feedId,所有查询都将针对属于特定 feedId 的记录。目前大约有 200 个独特的 feedId 值,但每个值的分布是高度非线性的。在低端,一些 feedId 每天可能只能看到几十条记录。另一方面,前 5 个 feedId 约占数据集的 75%。

记录也有一个时间戳,查询将始终针对给定的日期范围。 timestamp 字段或多或少是单调的。

feedIdtimestamp 上已经存在复合索引。

这个集合的典型工作集只是最近几周的数据,因此只占实际数据的很小一部分。对该数据的查询必须非常快,对历史数据的较慢查询是可以接受的。因此,我们计划使用“标签”和/或“区域”将较旧的数据移动到具有更大 HDD 的节点,并将具有 SSD 的节点用于“热”数据。

基于这些因素,使用分片键{feedId: 1, timestamp: 1}是否合理?我的感觉是,由于 feedId 的非线性和 timestamp 的单调性,它可能会导致“热”节点。向 key 添加“散列”字段会使它变得更好/更坏吗?

最佳答案

所以让我们一点一点地来吧!

The collection has 3.4B records and is ~14.6TB in size (5.3TB compressed on disk)

分片的性质决定了在第一次通过时就做好这一点很重要。我将在这里详细介绍,但 TL;DR 是:

  • 将数据集的一部分(例如使用 mongodump --query)提取到暂存集群(例如使用 mongorestore)
  • 将示例工作负载指向暂存集群以模拟您的生产环境
  • 测试一个或多个分片键组合。根据需要转储/重新加载,直到您对性能感到满意为止。

现在,让我们深入研究:

There are currently ~200 unique feedId values, but the distribution across each value is highly non-linear. On the low end, some feedId's may only see dozens of records per day. On the other hand, the top 5 feedId's make up ~75% of the dataset.

因此,支持大量查询的一个字段的频率非常低。如果您只是在此字段上进行分片,您肯定会看到热点 1

Records also have a timestamp and queries will always be for a given date range. The timestamp field is more-or-less monotonic.

所以另一个字段支持您的大部分查询,但也不适合分片 2

Records also have a timestamp and queries will always be for a given date range. The timestamp field is more-or-less monotonic.

这对我来说有点暗示您要查询的主要字段是时间。在给定的时间 内,给我具有指定 feedID 的文档。您还将获得有针对性的查询,因为您经常查询分片键(例如,在某个时间范围内,或者在某个时间范围内 + feedId)。 3

这也支持你的分区想法:

As such, we're planning to use "tags" and/or "zones" to move older data to nodes with larger HDD's and use nodes with SSD's for the "hot" data.

通过分区,您可以使用分片键中的任何键,只要您包含指向该键的整个 前缀即可。所以 { feedId: 1, timestamp: 1 } 将主要支持 feedId 时间戳上的区域,这不是您想要的。 4

仅基于这一点,我敢说 { timestamp : 1, feedId : 1 } 会是一个不错的选择。您的测试需要研究的是是否添加低频场到单调递增场提供良好的 block 分布。

现在,就散列而言:

Would adding a "hashed" field to the key make it better/worse?

如果您的意思是,您的文档已经有一些散列字段,那么您绝对可以添加它只是为了随机性。但如果您谈论的是散列分片键,那就另当别论了。 5

区域和散列分片键不能一起玩。散列分片键的性质意味着 block 范围(因此区域)代表散列分片键值。因此,即使您有两个文档的值彼此非常接近,它们也很可能以完全不同的 block 结束。因此,在一系列散列分片键值上创建区域可能不会执行您想要的操作。您可以做一些事情,比如使用带散列分片的区域将整个集合移动到集群中的分片子集,但这不是您想要做的。 6

现在您可能会遇到一个关键问题 - 您有一个庞大 集合。您选择的分片键可能会导致 MongoDB 尝试将您的数据分成 block 的初始拆分问题。请查看我们文档中的以下部分:Sharding an Existing Collection .那里有一个公式供您使用来估计您的分片键可以支持配置的 block 大小(默认为 64MB)的最大集合大小。我猜测您最初需要将 block 大小增加到 128MB 或 256MB。这仅是初始 分片过程所必需的。之后,您可以将 block 大小减小回默认值,让 MongoDB 处理其余部分。

请注意,这会对性能产生影响。您将有 block 在分片之间迁移,加上实际 block 拆分的开销。我建议您发布到我们的 Google Group在此处获取更具体的指导。

关于MongoDB 分片键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49671158/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com