本文将介绍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不足以容纳所有属性且查询在可变长度属性上执行更多操作(过滤、分组、排序)时。
也可以仅锁定某些属性。例如,我们希望确保数值属性保留在RAM中,但其他属性可以在RAM中预读,但我们接受不锁定它们以允许释放一些内存空间。
全文索引
全文索引部分本身包含多个组件。字典组件(.spi)始终加载到RAM中,因为它对全文搜索性能至关重要,且其大小不大。文档列表(.spd)保存索引词到文档和字段的引用。此组件通常较大,以前通过 pread() 访问。
全文索引的另一个组件是命中列表(.spp),其中包含字段中词的位置。命中列表也可以很大(但不如文档列表大),以前以与文档列表相同的方式访问。从3.0.2版本开始,这两个组件都可以使用 mmap() 而不是 pread() 加载,通过
access_doclists
和 access_hitlists。该设置接受两个值:file(使用 pread(),这是默认值)和 mmap。
如何设置内存指令?
默认情况下,全文索引组件使用 file,所有属性使用 mmap_preread,这在内存使用和搜索性能之间是最平衡的配置。
为了确保加载到内存中的属性数据不会被操作系统丢弃,可以使用 mlock。锁定应在系统内存充足以容纳属性但同时留有足够内存给文档/命中列表的系统上使用。当索引可以完全加载/缓存到RAM中时,性能最佳。使用 file 方法的文档/命中列表可以通过将它们的文件发送到 /dev/null 进行预热。
在需要从第一个查询就获得最佳性能的情况下,可以使用 searchd 的 --force-preread 选项。此选项应谨慎使用,因为守护进程在启动完成之前不会响应传入的查询。对于单机设置,这意味着在启动完成之前无法执行搜索查询,这可能根据启动所需时间与在此期间响应查询所需时间的权衡而不可接受。
如果索引大于可用内存或可以接受较长的预热时间,应使用简单的 file/mmap。如果索引无法很好地适应RAM,则性能将受到存储性能的影响。在更多内存和更快存储之间做出选择取决于每种资源的成本。更快的存储(如 NVMe)将减少内存不足的缺点。拥有足够的内存但较慢的存储意味着启动或索引重新加载将更慢,性能将在索引加载到内存之前受到影响。