首先,我正在使用MongoDB 3.0和新的WiredTiger存储引擎。还使用snappy进行压缩。针对随机读取进行优化
我想从技术角度来理解和优化的用例如下;
我有一个相当大的集合,大约有5亿个文档需要大约180 GB(包括索引)。
实施例的文档:
{
_id: 123234,
type: "Car",
color: "Blue",
description: "bla bla"
}
查询包括与特定字段值查找文档的。像这样;
thing.find({ type: "Car" })
在这个例子中,type
字段显然应该被索引。到现在为止还挺好。然而,这个数据的访问模式将是完全随机的。在特定时间,我不知道将访问哪些文档范围。我只知道他们将在索引字段中被查询,一次返回最多100000个文档。
这意味着在我心中,MongoDB/WiredTiger中的缓存几乎没有用处。唯一需要适应缓存的是索引。如果不是不可能的话,对工作集的估计很难?
我在找什么主要是使用什么类型的索引以及如何为这种用例配置MongoDB的技巧。其他数据库会更好吗?
目前我发现MongoDB在硬件有限的情况下工作得很好(16 GB RAM,非SSD盘)。如果结果集已经存在于缓存中,查询将在体面时间内返回,显然会立即返回。但如前所述,这很可能不是典型的情况。查询的速度并不是很关键,更重要的是它们是可靠的,并且数据库能够以稳定的方式运行。
编辑:
想我遗漏了一些重要的事情。数据库将主要用于存档目的。因此,数据来自另一个来源,例如每天一次。更新将非常罕见。
我使用的例子有点人为设计,但实质上这就是查询的样子。当我提到多个索引时,我的意思是该例中的type
和color
字段。因此,将使用这些字段查询文档。现在,我们只关心返回具有特定的所有文档type
,color
等等。自然,我们的计划是只查询我们有索引的字段。所以临时查询不在桌面上。
现在索引大小非常易于管理。对于5亿个文档,这些索引中的每一个大约为2.5GB,并且很容易放入RAM中。
关于操作的平均数据大小,我只能在这一点上进行推测。据我所知,典型的操作返回大约20k个文档,平均对象大小在1200字节范围内。这是由db.stats()
报告的统计数据,所以我想这是针对光盘上的压缩数据,而不是实际需要多少内存一次。
希望这一点额外的信息帮助!