ArangoDB的内存使用情况

时间:2014-06-24 06:48:25

标签: arangodb

我试图了解Arangodb的限制是什么以及理想设置是什么。根据我的理解,arango将所有收集数据存储在虚拟内存中,理想情况下,您希望将其放入RAM中。如果集合增长并且无法容纳在RAM中,它将被交换到磁盘。

所以我的第一个问题。如果我的数据库增长,我需要调整交换分区/文件以容纳db?

由于arango也将数据同步到磁盘,这是否意味着数据将始终位于RAM和磁盘中?所以,如果我有一个1.5GB的数据库,而我的RAM是1GB,我需要至少拥有0.5GB的交换磁盘和1.5GB的常规磁盘空间?

我对arango如何使用虚拟内存感到有些困惑。现在我有7个实际上是空的集合。我有1GB的RAM和1GB的交换磁盘。 管理员报告arango正在使用4.5GB的虚拟内存。如果交换磁盘是1GB,这怎么可能?它目前使用80MB的RAM。如果每个集合的日志大小为32MB,那么这不应该是224MB吗?

关于期刊大小与收藏规模的建议是什么?随着集合的增长,这可以动态调整吗?

如果在磁盘是SSD时大量使用交换磁盘,预计会有什么样的性能?如果交换磁盘使用了很多,那么性能与使用更传统的数据库(如mysql)类似?

1 个答案:

答案 0 :(得分:40)

ArangoDB将所有数据存储在内存映射文件中。 每个集合可以包含0到n个数据文件,每个文件大小为32 MB(请注意,此文件大小可以全局调整,也可以按集合级别调整)。空集合(从未有任何数据)将没有数据文件。第一次写入集合将创建数据文件,每当数据文件已满时,将自动创建一个新文件。

默认情况下,集合以32 MB的块分配数据文件。如果你有很多但很小的集合,这可能会浪费一些内存。如果您只有很少但很多大集合,那么潜在的浪费(数据文件末尾的可用空间)可能并不重要。

每当ArangoDB操作从内存映射数据文件读取数据或将数据写入内存映射数据文件时,操作系统将首先将偏移量转换为文件中的页码。这是因为每个数据文件被隐式拆分为特定大小的页面。页面的大小取决于平台,但我们假设页面的大小为4 KB。因此,具有默认文件大小的数据文件将具有8192页。

操作系统将偏移量转换为文件到页码后,将确保请求页面的数据存在于物理RAM中。如果页面尚未在物理RAM中,操作系统将发出页面错误以触发从磁盘加载请求的页面或交换到物理RAM。这最终会使整个页面在RAM中可用,并且在此之后可能会对页面数据进行任何读取或写入。

所有这些都是由操作系统的虚拟内存管理器完成的。操作系统可以自由地将数据文件中的多个页面映射到RAM中,因为它认为是好的。 例如,当顺序访问内存映射文件时,操作系统可能会很聪明并且预读许多页面,因此它们在实际访问时已经在物理RAM中。

操作系统也可以自由地换出数据文件的部分或全部页面。如果没有足够的物理RAM可以同时保留RAM中所有数据文件的所有页面,它可能会换出页面。它还可以交换暂时未使用的页面,以使RAM可用于其他操作。它可能会使用一些LRU算法。

操作系统的虚拟内存管理器如何在各种平台和实现之间完全不同。大多数系统还允许配置VM子系统。例如,here are some parameters for Linux's VM subsystem

因此,很难说ArangoDB实际上会为给定数量的集合及其数据文件使用多少物理内存。如果根本没有访问集合,那么使用内存映射的数据文件可能几乎不使用RAM,因为操作系统可能已完全或至少部分地交换了集合。如果集合大量使用,操作系统可能会将其数据文件完全映射到RAM中。但在这两种情况下,内存都计为内存映射。这就是你可以拥有比物理RAM更高的虚拟内存使用率。

如前所述,操作系统在访问不在RAM中的页面时必须做很多工作,并且如果可能的话,您希望避免这种情况。如果您经常使用的集合的总大小超过物理RAM的大小,则操作系统别无选择,只能在您访问这些集合时将页面交换出来。使用SSD进行交换可能比使用旋转HDD更好,但仍然比RAM访问慢得多。简而言之:如果可能,您的活动集合(数据文件加索引)的数据应该适合物理RAM,否则您将看到大量的磁盘活动。

除此之外,ArangoDB不仅为集合数据文件分配虚拟内存,而且还启动了一些V8线程(V8是ArangoDB中的JavaScript引擎),它们也使用虚拟内存。此虚拟内存不受文件支持。

在空的ArangoDB V8中占据了大部分虚拟内存使用量。例如,在我的64位计算机上,V8线程消耗大约5 GB的虚拟内存(但ArangoDB总共仅使用140 MB RAM),而在我的32位计算机上使用较少的RAM,V8线程使用大约600 - 700 MB虚拟内存。在您的情况下,使用4.5 GB VM,我怀疑V8也是原因。

V8线程的虚拟内存使用量显然与启动的V8线程数相关。例如,增加启动参数--server.threads的值将启动更多线程并为V8使用更多虚拟内存,并且降低该值将启动更少的线程并使用更少的虚拟内存。