MongoDB分片键

3

我一直在考虑为我的数据选择最佳的分片键(通过复合索引),并认为将文档创建日期与客户编号(或发票编号)相结合会是一个不错的组合。如果MongoDB将客户编号视为字符串反向存储,那么:

90043 => 34009
90044 => 44009
90045 => 54009
etc.

在创建日期上建立索引可以确保相对较新的数据保存在内存中,而反向客户编号将帮助MongoDB在集群中分布数据/负载。

这个假设是正确的吗?如果是,我需要将客户编号反转才能按照我预期的方式进行分配吗?

3个回答

1
关于你的具体问题“我需要将客户编号反转以使其按照我期望的方式进行分发吗?”,不用-你不需要这么做。
即使您列出的客户编号值相对较窄,如果在您的复合键中使用customerNumber, MongoDB将把数据分解为块并相应地分配这些块。只要与customerNumber相关联的数据相对均匀分布(例如,一个用户不会主导整个系统),您将获得所需的分片平衡。
我认为你最初的选择(去除字符串反转)或丹(Dan)的选择(使用内置的ObjectId而不是时间戳)都是复合键的好选择。

假设我的MongoDB集群中的节点只能包含3个客户端,我期望数据分片会根据客户端编号的方向而有所不同...这个假设是否错误?正向 节点1: 80073 80074 80075 - 节点2: 90073 90074 90075 反向 节点1: 37008 37009 47008 - 节点2: 47009 57008 57009“反向”客户端编号似乎避免了无法分配的热点问题。 - Jacob
Balancer负责将分片集合的块放置在适当的位置,因此可以自行决定。我不确定您是否可以限制或指定任何特定模式,例如“每个仅3个客户”。关于前向/后向,只要值是离散的,值的范围/分布对Balancer没有影响。 - SethO
“每个仅限3位客户”只是举例而已。 “离散值”是什么意思? 在谈论范围时,需要进行排序。 反转客户编号(将其视为字符串)对字段中的值进行排序会产生重大影响...我只是不明白为什么它不会影响数据分片的方式? - Jacob
“离散”是指不同的。反转字符串确实会影响数据如何被分片,以及配置服务器如何将数据分成块。如果您对客户号进行哈希处理,情况也是如此。但是,与保持字段不变相比,两者都不会影响群集的性能。亲自试试:在本地机器上设置一个示例分片系统,注入大量数据,并观察平衡器如何移动块(查询配置服务器)。尝试使用不同的分片键再次尝试。 - SethO

0
根据我在文档中所读到的,MongoId已经是基于时间的。因此,您可以将_id添加到复合键中,如(_id,customerid)。如果您的应用程序不需要日期,则可以删除该字段,这样可以节省一些存储空间。
MongoDB会将最近使用的数据集存储在内存中。集合的索引始终尝试存储到RAM中。
当索引太大无法放入RAM时,MongoDB必须从磁盘中读取索引,这比从RAM中读取要慢得多。请记住,当服务器具有可用于索引的RAM和其余工作集时,索引适合RAM。
希望这可以帮助您。
祝好,丹

我确实需要创建日期、_id和客户编号。虽然客户编号可以作为客户的唯一标识符,但它将以人类可读的格式出现在网站、电子邮件等中。 - Jacob

0

我认为你的问题在于,你认为节点1比节点2更快。除非硬件有很大的不同,否则节点1和节点2的访问速度应该是相等的,因此反转字符串并不能帮助你解决问题。

我看到的主要问题与系统中的客户数量有关。这可能会导致单调分片,其中最后一个分片总是被访问,这可能会导致过多的拆分和迁移。如果您有大量的客户,则没有问题,否则您可能需要在客户ID和日期字段之上添加另一个键来更均匀地划分内容。我听说过有人使用随机标识符、哈希_id或使用GUID来解决这个问题。


我相信节点1和节点2的性能是相同的,这就是为什么我希望新客户能够均匀地分布在这些节点上...请参考我在SethO评论中的示例。如果使用正向客户编号,所有新客户都将位于同一节点上。我期望反向客户编号会更好地扩展。 - Jacob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接