选择有利于读取性能的MongoDB分片密钥

选择有利于读取性能的MongoDB分片密钥,mongodb,sharding,Mongodb,Sharding,我在很多地方读到过,选择时间戳是一个糟糕的切分键选择,因为它会在插入时创建热点。如果我向Shard键添加另一个或两个属性,它将创建一个更均匀的分布,但唯一有意义的其他属性不是用于查询的属性。这对于压缩最大的读取性能有多重要 示例文档 { _id: <ObjectId>, user_id: <ObjectId>, _p: <6-10 possible values>, ts: <UNIX timestamp>, a: 'l

我在很多地方读到过,选择时间戳是一个糟糕的切分键选择,因为它会在插入时创建热点。如果我向Shard键添加另一个或两个属性,它将创建一个更均匀的分布,但唯一有意义的其他属性不是用于查询的属性。这对于压缩最大的读取性能有多重要

示例文档

{
  _id: <ObjectId>,
  user_id: <ObjectId>,
  _p:  <6-10 possible values>,
  ts:  <UNIX timestamp>,
  a:   'lorem ipsum',
  b:   <Array of ObjectId, can be null/empty>,
  ...,
  z:   'xyz'
}


感谢您的帮助。

如果您的数据中的时间戳很少更改,那么碎片密钥中的时间戳可能就可以了。

你可以阅读。好主意-用于分片关键字段,以“确保MongoDB能够在分片之间均匀分布数据”。然后在时间戳上创建索引。如果您的时间戳字段经常更改(使用新的时间戳插入数据),那么将其用于shard key是个坏主意,因为mongo无法正常分发您的数据。

第一次尝试仅由用户共享数据。如果这还不够,请添加。当我们谈论切分时,试着想象一个有多个建筑物的图书馆。想想你怎么能把所有的书放在所有的建筑物里。我认为时间戳不是这项工作的最佳解决方案。通过这些字段查找不可变数据(例如,您在创建docunet时设置了一次数据)并切分。

时间戳本身(或任何单调递增的值,如ObjectID)是切分键的一个非常糟糕的选择。这将导致“热分片”性能问题,当新数据到达时,所有数据都以最高的时间戳值写入分片。MongoDB 2.4+有一个可用于统一分配值的组件,但这是以分配写入和读取为代价的。
{
  user_id:     1,
  timestamp:   1
}
{
  user_id:    1,
  _p:         1,
  timestamp:  1
}
{
  _p:         1,
  timestamp:  1
}