# Indexes load at startup

在本文中，我们将讨论索引如何在启动时加载，以及这对传入查询和搜索实例管理的影响。



在较早的Sphinx版本中，如果设置了preopen选项，索引会被预读并加载到内存中。在此期间，守护进程将拒绝接受任何传入连接。对于小索引来说，这并不是大问题，因为它们加载得很快。但对于需要加载数十甚至数百GB的巨大索引来说，这确实是个问题，因为加载完成可能需要几分钟甚至更长时间。

从Sphinx 2.3版本开始，这一情况发生了变化，因为索引文件现在是通过**内存映射**（mmap）的方式加载，而不是简单地读取并加载到内存中。使用mmap时，守护进程的一个影子线程（而非主线程）会先为每个页面读取一个字节，然后继续读取其余数据，逐步将所有内容加载到RAM中，同时允许访问数据。简而言之，这是对索引文件的延迟加载。

通过这种方式，守护进程可以在启动后立即接受连接。如果某个查询需要访问尚未加载到内存中的随机数据，它将从磁盘读取。这也意味着查询的执行速度可能比平时慢（具体取决于存储性能），但至少守护进程可以返回结果。更进一步，一旦某个索引的文件加载完成，守护进程就可以为其提供“全速”响应，即使其他索引仍在加载中。

虽然这对大多数用户来说是个好消息，但对某些用户而言，“延迟”加载可能并非最佳选择。例如，使用简单策略（随机或轮询）的负载均衡器，这些策略不测量响应时间，会在守护进程启动后立即将重启的实例加入集群。由于查询需要直接从磁盘读取数据，实例的响应时间将比平时更高，甚至高很多，这并非理想情况。相反，如果可能的话，最好在守护进程完成索引加载后，再将实例添加到集群中。

为了解决这种情况，自2.3版本起，[searchd](https://docs.manticoresearch.com/latest/html/command_line_tools_reference/searchd_command_reference.html)提供了一个选项，但遗憾的是直到最近才被记录：'**--force-preread**'。使用此选项时，守护进程仍会通过mmap加载索引文件，但预读操作会成为阻塞操作（就像旧版本一样），searchd将不会响应，直到所有内容都加载到内存中。
