优化随机读取
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 的方式 运行。
编辑:
我想我遗漏了一些重要的事情。该数据库将主要用于存档目的。因此,数据从另一个来源批量到达,比如每天一次。更新将非常罕见。
我使用的示例有点做作,但本质上这就是查询的样子。当我提到多个索引时,我指的是该示例中的 type
和 color
字段。因此,将使用这些字段查询文档。就像现在一样,我们只关心 return 具有特定 type
、color
等的所有文档。自然地,我们的计划是只查询我们有的索引。因此临时查询已关闭 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
或所有文档的子集?对此集合的插入和更新是什么样的?
此外,如果正在读取的文档在数据集上确实是完全随机的,那么工作集就是所有数据。
首先,我使用的是 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 的方式 运行。
编辑:
我想我遗漏了一些重要的事情。该数据库将主要用于存档目的。因此,数据从另一个来源批量到达,比如每天一次。更新将非常罕见。
我使用的示例有点做作,但本质上这就是查询的样子。当我提到多个索引时,我指的是该示例中的 type
和 color
字段。因此,将使用这些字段查询文档。就像现在一样,我们只关心 return 具有特定 type
、color
等的所有文档。自然地,我们的计划是只查询我们有的索引。因此临时查询已关闭 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
或所有文档的子集?对此集合的插入和更新是什么样的?
此外,如果正在读取的文档在数据集上确实是完全随机的,那么工作集就是所有数据。