在本文中,我们讨论了在3.0.2中引入的加载数据的新选项。
带有数据的索引由多个组件组成,如字典、文档和命中列表、属性。整个索引不会完全加载到RAM中,因为可能无法容纳,而是以不同的方式读取和加载其组件。
属性
属性默认情况下加载到RAM中,但可以选择是否加载所有属性,仅加载标量类型(整数或浮点数)或将其保留在磁盘上。
属性作为内存映射文件加载。使用mmap()加载属性的优点是比经典的seek&read使用pread()具有更好的性能。它还允许使用少量RAM处理大文件。
在2.x中,属性加载是通过ondisk_attrs处理的。即使我们选择将属性加载到RAM中,使用mmap()读取整个文件也不能保证文件的页面会保留在RAM中,因为操作系统内核可以释放它们(这对应用程序来说不是问题,因为映射文件由磁盘上的文件本身支持)。为了确保属性保持在RAM中,操作系统不会将其交换到磁盘上,需要使用mlock。
在3.0.2中,我们决定进行更改,而不是有一个设置来决定加载哪些属性类型和一个用于mlocking的设置,而是有两个设置,每个设置用于决定属性类型如何加载以及是否应该被锁定。
新的设置是
access_blob_attrs
- 管理可变长度属性(字符串、JSON、MVA) -
和access_plain_attrs
- 管理固定长度属性(uint、bigint、float、timestamp、bool)。可能的值是mmap、mmap_preread和mlock。
从旧指令切换到新指令非常简单:
ondisk_attrs = 0意味着没有属性留在磁盘上,它们在RAM中预读取。这是默认值,mlock=0。这现在等同于access_blob_attrs = mmap_preread和access_plain_attrs= mmap_preread。当所有属性都可以适应RAM时,应使用此模式。为了确保它们不被交换到磁盘,我们可以改用access_blog_attrs = mlock和access_plain_attrs = mlock,相当于ondisk_attrs=0和mlock=1。ondisk_attrs=1意味着所有属性留在磁盘上。使用新选项,您必须指定access_blob_attrs=mmap和access_plain_attrs=mmap。ondisk_attrs=pool意味着将字符串、JSON和MVA属性留在磁盘上。要获得相同的效果,现在需要执行access_blob_attrs=mmap和access_plain_attrs=mmap_preread。
但现在也可以将数值属性保留在磁盘上,而加载可变长度的属性(通过执行access_blob_attrs=mmap_preread/access_plain_attrs=mmap),例如,如果您没有足够的RAM来容纳所有属性,并且您的查询在可变长度属性上执行更多操作(过滤、分组、排序)。
还可以仅对某些属性进行mlocking。例如,我们希望数值属性确保它们保持在RAM中,但其他属性可以在RAM中预读取,但我们接受不锁定它们,以允许释放一些内存空间。
全文索引
索引的全文部分本身包括多个组件。字典组件(.spi)始终加载到RAM中,因为它对全文搜索性能至关重要,并且其大小不大。文档列表(.spd)保存索引单词到文档和字段的引用。该组件通常很大,直到通过使用**pread()**访问。
全文索引的另一个组件是命中列表(.spp),它包含字段中单词的位置。命中列表也可以很大(但不如文档列表大),并且以与文档列表相同的方式访问。从3.0.2开始,这两个组件可以使用mmap()加载,而不是使用
access_doclists
和access_hitlists。该设置接受两个值:file(使用pread()并且是默认值)和mmap。
如何设置内存指令?
默认情况下,全文索引组件使用文件,所有属性使用mmap_preread,这是内存使用和搜索性能之间最平衡的配置。
为了确保加载到内存中的属性数据不会被操作系统丢弃,可以使用mlock。锁定应在有足够内存容纳属性的系统上进行,但也要为文档/命中列表留出足够的内存。当索引可以完全加载/缓存到RAM中时,性能最佳。使用文件方法的文档/命中列表可以通过将其文件发送到/dev/null来预热。
对于需要从第一个查询获得最佳性能的情况,可以使用searchd的--force-preread选项。此选项应谨慎使用,因为守护进程在启动完成之前不会响应传入的查询。对于单个设置,这意味着在此期间不可能进行搜索查询,这可能是不可接受的,具体取决于完成启动所需的时间与在此期间响应的时间。
如果索引大于可用内存,或者可以接受更长的预热时间,则应使用简单的file/mmap。如果索引无法很好地适应RAM,则性能将受到存储性能的影响。在更多内存和更快存储之间的选择取决于每个的成本。更快的存储(如NVMe)将减少内存不足的缺点。拥有足够的内存但存储速度较慢意味着启动或索引重新加载将更慢,性能将受到影响,直到索引加载到内存中。