【问题标题】:MongoDB shard by date on a single machineMongoDB 在单台机器上按日期分片
【发布时间】:2015-06-20 15:34:09
【问题描述】:

我们从一个 mongodb 开始,但没有一个集合增长到 ~300GB。该集合包含具有日期字段的对象。但大多数情况下,我们只需要查询比历史更近的对象。所以我的问题是:是否可以通过日期字段在一台服务器上分割这个集合?更明确地说,我想将较新的对象分片到一个节点中,将较旧的对象分片到另一个节点中。而不是将所有对象平均分布在 n 个分片上。

是否有教程如何将现有的单个数据库(没有任何副本集)分片到分片集群中?

【问题讨论】:

  • ...暗示在某个时候,“旧”数据会从一台服务器迁移到另一台服务器?
  • 为什么要分片?您仍然需要在所述日期字段上建立索引,以防您需要访问旧值并且您会通过施加不必要的开销来减少可用 RAM 的数量。如果您真的不需要旧数据,只需将其删除或(如果您想节省宝贵的 RAM,但保留旧数据)将其移动到索引较少的集合中
  • @Markus W Mahlberg 通常的行为是只有索引在使用中的 ram 中。因此,由于我们通常查询较新的数据,因此较新的索引位于 ram 中。是的,当有广泛的查询时,我们会进行资源竞争,但这可能每周发生两次。
  • 你说的是工作集?是的,但我仍然看不到单台机器上的分片在哪里可以帮助你。您至少有两个额外的 mongod 实例需要 RAM 和 IO 却没有任何好处,因为我们仍然会访问同一个集合。

标签: mongodb sharding


【解决方案1】:

从技术上讲,您不需要对内容进行分片,只需要为您的字段编制索引。是的,您可以在日期字段上创建索引,并且可以通过访问查询计划 db.collection.explain("executionStats")

看到这一点。

但是,选择分片键非常重要。选择分片键时需要考虑的事项很少

- Write scaling (high cardinality, Randomization)
- Query Isolation. (read)

选择日期字段实际上给出了非常高的基数,但是它无法进行随机化,因此所有文档都存储在单个分片中,因此它限制了系统的写入容量。出于同样的原因,不鼓励将 ObjectId 用作分片键。

http://docs.mongodb.org/manual/core/sharding-shard-key/ 以上链接的内容.. “MongoDB 在创建文档时生成 ObjectId 值以生成对象的唯一标识符。但是,此值中的最高有效位数据表示时间戳,这意味着它们以规则且可预测的模式递增。即使这个值有很高的基数,当使用这个、任何日期或其他单调递增的数字作为shard key时,所有的insert操作都会将数据存储到一个chunk中,因此是一个shard。因此,写入容量这个分片将定义集群的有效写入容量。”

【讨论】:

  • 我们在日期字段上有一个索引,但它很快就不再适合 ram。但 90% 的查询是关于较新的数据,只有少数查询跨越了广泛的历史范围。分片还应该拆分索引,并且由于“历史”节点不会经常被查询,因此该节点不会永远将索引保存在 ram 中,并为更新的节点释放资源(我希望如此)。
  • 我怀疑在分片集群中是否只有部分索引会加载到 RAM 中。索引始终在 RAM 中,无论您的查询被路由到哪个分片。你为什么不做这两件事中的任何一个。 1)使用水平缩放并增加机器(我认为这在时间戳字段的情况下可能没有帮助)2)考虑删除旧的和冗余的记录。
【解决方案2】:

从您的描述看来,您可能不需要分片,而只是按日期将大集合拆分为较小的集合。因此,实时集合仅包含最近的数据,而较旧的数据会定期移动到其自己的存档集合中。假设您不一起查询新旧数据,这将起作用。

【讨论】:

  • 这将是计划 b,但由于我们对所有范围都有查询(只是不经常),这不是首选方式。
猜你喜欢
  • 2016-07-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 2019-01-19
  • 2015-01-03
  • 2013-11-25
  • 1970-01-01
  • 2017-10-22
相关资源
最近更新 更多