知识库

控制每个 Lucene 索引创建的文件句柄数量

在较新的 Neo4j 版本(3.4 及以上)中,Neo4j 打开的文件句柄数量与旧版本相比可能会增加。原生索引需要每个索引恒定的文件句柄数量,并且该数量随系统上可用的 CPU 核心数量而变化。

这是因为某些索引实现(例如 lucene+native-1.0)使用了更多的文件描述符,并且对于大量索引(1000+ 多于平均水平),很可能会达到 60K 的文件描述符打开限制。这是因为,为了优化 I/O 性能,我们会打开多个通道连接所有文件。lucene+native 组合会为两种索引引擎创建文件,以便准备好处理两者,即使其中一种未使用。虽然占用的磁盘空间可以忽略不计,但每个索引仍然会使用几个额外的文件描述符。目前无法关闭此功能,但未来纯原生索引选项可能会解决此问题。

基于 Lucene 的索引需要每个索引的文件句柄数量,该数量随与索引交互的开放事务数量而变化。例如,在 72 个 CPU 核心和 100 个原生索引的情况下,每个索引的文件句柄数量最多可达 64 个。首先,确定当前的模式索引数量(CALL db.indexes() 返回的行数)以及当前默认的索引提供者可能会有所帮助。这由 neo4j.conf 中 dbms.index.default_schema_provider 的值设置,例如 lucene+native-1.0 或 native-btree-1.0。

文件描述符的数量很可能在负载较高时飙升,因此即使数据库设法启动,仍可能在运行时因该限制而失败,因此建议在此处保留一定的余量。这是因为索引在事务执行期间会创建许多较小的文件,然后这些文件会在后台线程中合并到一个大文件中。通常,此合并速度快于事务速率,但在这些文件合并之前仍然会有一点延迟,这会暂时增加打开的文件数量。

然而,文件打开数量增加的影响在很大程度上取决于操作系统和硬件。如果需要,可以使用一个未文档化的功能标志调整条带化因子,例如:

-Dorg.neo4j.io.pagecache.implSingleFilePageSwapper.channelStripePower=2

默认值根据可用 CPU 核心数计算得出,并向上取整到上面列出的最接近的数字。上述参数的整数值是 2 的指数。因此,如果 channelStripePower 为 5,您将获得 2^5 = 32 个条带,即每个独立映射文件对应 32 个文件描述符。您可以将其设置为 0,以使每个映射文件只有一个文件描述符。将其设置为 1 将打开 2 个文件描述符,设置为 2 将打开 4 个,设置为 3 将打开 8 个,依此类推。请注意,设置 channelStripePower=0 可能会带来性能损失,这就是它不是默认值的原因。降低此设置可能会影响性能,尤其是在 Windows 上,但在 macOS 等系统上,您可能可以降低它。由于每种硬件都不同,最好尝试使用不同的值,看看哪种设置适用于给定的硬件配置。

参考资料