MongoDB:应用程序生成_id包含国家和序列作为分片键?

时间:2015-04-13 18:19:26

标签: mongodb hash key sharding

我有一些关于分片键的基本问题。
在我们的应用程序中,我们从粗粒度属性创建_id字段 - 国家每个国家单调增加序列号,例如IN_1。根据几个在线参考和书籍(例如http://www.kchodorow.com/blog/2011/01/04/how-to-choose-a-shard-key-the-card-game/),最好有一个复合分片键 - 粗粒度键+搜索键。我们在分片键中也有一个country属性,并且有一个索引。

大多数(如果不是)我们对这些集合的所有查询都将基于国家/地区搜索或基于_id。

什么是分片键的最佳选择

  1. 只是_id - 因为ctry已经被烘焙了 - 它会成功吗? 以ctry slow开头的查询?
  2. {ctry:1,_id:1} - 但我的_id的一部分是单调增加的序列。
  3. {ctry:1,_id:hashed} - 承诺读取局部性和写入分布。这是MongoDB支持吗?
  4. 只是{_id:hashed} - 是否会以ctry slow?
  5. 开头查询

    我倾向于使用选项3-但是可能 - 从MongoDB文档中不是很清楚。

1 个答案:

答案 0 :(得分:1)

  

只是_id - 因为ctry已经被烘焙了 - 它会以ctry slow开始查询吗?

我不推荐这个。 _id单调增加,因此它会将写入集中在单个分片上。如果您还在使用形状进行查询

{ "ctry" : "United States" }

然后他们将广播到所有分片,而不是目标。

  

{ctry:1,_id:1} - 但我的_id的一部分是单调增加的序列。

_id单调递增但是,只要插入包含ctry不同值的分片键值的文档,分片键值就不会单调递增,因此您不会集中写入在一个碎片上。但是,对于给定国家/地区c,所有写入操作都只会包含一个包含ctry = c块的分片。

这似乎是合理的。

  

{ctry:1,_id:hashed} - 承诺读取局部性和写入分布。这是MongoDB支持的吗?

我最喜欢这个。它支持您的查询,提供读取隔离和扩展写入。 MongoDB中的散列分片键构建在单个字段上,但您可以计算自己的散列hashed_id并将其存储在文档上,然后将碎片存储在

{ "ctry" : 1, "hashed_id" : 1 }
  

只是{_id:hashed} - 是否会以ctry slow?

开始查询

单调性问题已经消失,但ctry查询仍然会分散 - 聚集。