我正在尝试对需要非常高的写入吞吐量和合理的读取吞吐量的数据库进行建模。我有一组分布式系统将“事件”数据添加到数据库中。
目前,事件记录的 id 是 Guid。我一直在读到 guid 不倾向于创建很好的索引,因为它们的随机分布意味着最近的数据将分散在磁盘中,这可能会导致分页问题。
所以这是我要验证的第一个假设:我假设我不想选择创建正确平衡树的 _id,例如自动编号。这将是有益的,因为最近的 2 个事件在磁盘上基本上彼此相邻。这是一个正确的假设吗?
假设 (1) 是正确的,那么我正在尝试找出生成此类 id 的最佳方法。我知道 Mongo 本身就支持 ObjectId,这对于可以将数据绑定到 Mongo 的应用程序很方便,但我的应用程序不是这样。由于有多个系统产生数据,模拟“自动编号”字段有点问题,因为 mongo 不支持服务器端的自动编号,所以生产者必须分配 id,如果他们不这样做很难不知道其他系统在做什么。
为了解决这个问题,我正在考虑使 _id 字段成为 { localId, producerId } 上的复合键,其中本地 id 是生产者可以生成的自动编号,因为 producerId 将使其唯一。ProducerId 是我可以在生产者之间协商的东西,以便他们可以提出唯一的 ID。
所以这是我的下一个问题:如果我的目标是从所有生产者那里获取最新数据,那么 { localId, producerId } 应该是首选的键排序,因为 localId 将是右派,而 producerId 将是一个小集群,我宁愿两个最近的事件彼此保持本地。如果我颠倒该顺序,那么我对树最终外观的推理将类似于以下内容:
root
/ | \
p0 p1 p2
/ | \
e0..n e0..n e0..n
其中 p# 是生产者 ID,e# 是一个事件。这似乎会将我的索引分割成 p# 数据集群,并且新事件不一定彼此相邻。我对首选排序的假设应该(请验证)看起来像这样:
root
/ | \
e0 e1 e2
/ | \
p0..n p0..n p0..n
这似乎使最近的事件彼此靠近。(我知道 Mongo 使用 B 树作为索引,但我只是想在这里简化视觉效果)。
我可以看到对 { localId, producerId } 的唯一警告是,用户的常见查询是按生产者列出最近的事件,{ producerId, localId } 实际上会处理得更好。为了让这个查询与 { localId, producerId } 一起工作,我想我还需要将 producerId 作为一个字段添加到文档中,并为其编制索引。
为了明确我的问题到底是什么,我想知道我是否正确地考虑了这个问题,或者是否有明显更好的方法来解决这个问题。
谢谢