优化随机读取

Optimizing for random reads

首先,我使用的是 MongoDB 3.0 和新的 WiredTiger 存储引擎。还使用 snappy 进行压缩。

我试图从技术角度理解和优化的用例如下;

我有一个相当大的集合,大约有 5 亿份文档,包括索引在内大约需要 180 GB。

示例文档:

{
  _id: 123234,
  type: "Car",
  color: "Blue",
  description: "bla bla" 
}

查询包括查找具有特定字段值的文档。像这样;

thing.find( { type: "Car" } )

在这个例子中,type 字段显然应该被索引。到目前为止,一切都很好。但是,此数据的访问模式将是完全随机的。在给定时间,我不知道将访问哪些范围的文档。我只知道它们会在索引字段上被查询,一次最多 returning 100000 个文档。

在我看来,这意味着 MongoDB/WiredTiger 中的缓存几乎没有用。唯一需要放入缓存的是索引。估计工作集即使不是不可能也很难?

我正在寻找的主要是有关使用何种索引以及如何为此类用例配置 MongoDB 的提示。其他数据库会更好吗?

目前我发现 MongoDB 在有限的硬件(16 GB RAM,非 SSD 磁盘)上工作得很好。在合适的时间查询 return,如果结果集已经在缓存中,显然会立即查询。但如前所述,这很可能不是典型情况。查询快如闪电并不重要,更重要的是它们是可靠的,并且数据库将以 stable 的方式 运行。

编辑:

我想我遗漏了一些重要的事情。该数据库将主要用于存档目的。因此,数据从另一个来源批量到达,比如每天一次。更新将非常罕见。

我使用的示例有点做作,但本质上这就是查询的样子。当我提到多个索引时,我指的是该示例中的 typecolor 字段。因此,将使用这些字段查询文档。就像现在一样,我们只关心 return 具有特定 typecolor 等的所有文档。自然地,我们的计划是只查询我们有的索引。因此临时查询已关闭 table。

目前,索引大小非常易于管理。对于 5 亿份文档,这些索引中的每一个都约为 2.5GB,很容易放入 RAM。

关于一个操作的平均数据大小,我目前只能推测。据我所知,典型操作 return 大约 20k 文档,平均对象大小在 1200 字节范围内。这是 db.stats() 报告的统计数据,所以我猜这是针对磁盘上的压缩数据,而不是它在 RAM 中实际占用的数据量。

希望这些额外的信息对您有所帮助!

基本上,如果您在 type 上具有一致的随机读取率(这就是我正在采取的

I have no idea what range of documents will be accessed

意思),那么你会从数据库中看到稳定的性能。幸运的是,它将从缓存中读取一些稳定的比例,并通过从磁盘读取另一个稳定的比例,特别是如果文档的数量和大小在不同 type 值之间大致相同。我认为除了更好的硬件之外,没有特殊的索引或任何东西可以帮助您。索引应该保留在 RAM 中,因为它们会经常被使用。

我想更多信息会有所帮助,因为您只提到了 type 上的一个简单查询,但随后又谈到了让多个索引担心保留在 RAM 中的问题。平均运行多少数据return?您是否关心过 return 某些 type 或所有文档的子集?对此集合的插入和更新是什么样的?

此外,如果正在读取的文档在数据集上确实是完全随机的,那么工作集就是所有数据。