在一台机器上托管多个 Neo4j 实例
本文列出在同一台物理主机上托管多个 Neo4j 实例时需要考虑的一些要点。
虽然允许使用多个实例,但在实际中并不常见。作为规划的起点,应理想地对每个计划共存的 Neo4j 实例在生产环境中进行约 1‑2 周的监控,关注以下指标:
-
峰值内存使用率及其出现时间
-
峰值 CPU 使用率及其出现时间
-
峰值与平均值之间的标准差
-
空闲时的内存和 CPU 使用率
随后需要考虑以下 Neo4j 的特定需求
-
堆的初始和最大大小分配(默认情况下应相同)
-
页面缓存分配
-
操作系统预留 2‑3 GB
-
最大打开文件数限制 (https://docs.oracle.com/cd/E19623-01/820-6168/file-descriptor-requirements.html)
-
数据库当前大小、大小的标准波动以及通过导入等方式的可预见增长
-
查询类型(读写),执行这些查询的周期性作业以及相应的资源使用情况
在对上述内容进行估算/剖析后,我们可以考虑预期增长,并判断主机是否足以容纳额外实例(同样需要对其进行估算),若可行,则可以继续添加实例。
下面我们以一台示例机器为例,其规格如下
-
总内存(RAM) = 200GB
-
CPU 总数 = 12
-
CPU 主频 = 2.5GHz
以下是该机器上已运行的单个 Neo4j 实例的示例参数设置
-
数据库总大小 = 12GB
-
页面缓存 = 15GB
-
堆内存 = 12GB
以下是上述单实例在 6 个月期间的 CPU 与内存使用概况示例
我们可以看到 CPU 偶尔会峰值达到 30%,如果在该主机上再添加第二个实例,这一数值看起来相当低。
可以看到内存使用率经常峰值超过 90%,而在某些时候约为 50%。
假设在我们的示例中,Neo4j 是唯一的生产应用(也是主要的内存使用者),我们需要观察在内存使用率达到 50% 以及超过 90% 时执行的事务,同时将第二个实例的预期工作负载计入,从而估算出机器所需的内存。
理想情况下,应尽可能将数据库的大部分放入页面缓存(以减少磁盘访问),同时考虑存储大小、索引以及预期增长。经验法则是:存储大小 + 预计增长 + 10%。例如,存储为 12GB,且预计在下一年会翻倍,则理想的分配为 12GB + 12GB + 1.2GB = 25.2GB。再次强调,这主要取决于预期的增长。堆内存大多数情况下 8GB‑12GB 是一个合适的默认值,但最终仍取决于实际执行的事务类型。
依据上述计算,每个实例大约需要 25.2GB(页面缓存)+ 12GB(堆)+ 3GB(操作系统)≈ 40GB 的内存。由于假设主机拥有 200GB 内存,这应当足够,但在实际剖析时,需要关注每个实例在生产环境中 1‑2 周的峰值内存使用情况。
此外,需要注意的是,若实例 1 的峰值 CPU 使用率始终不超过 X%,实例 2 的峰值不超过 Y%,且 X+Y(峰值)始终低于总 CPU 的 90%,则在该机器上托管第二个实例通常是可行的。
CPU 方面的另一个重要考虑是总 CPU 同时能够处理多少线程以及 CPU 主频是多少。超线程核心据称能够处理两倍的线程(但实际上它们只是更高效地利用线程等待时间来处理其他线程)。因此,最保守的假设是最大同时线程数等于核心数,即本例中的 12。读写查询提交事务的方式以及线程处理能力(CPU 主频)将决定每个 Neo4j 实例在峰值时占用的 CPU 百分比。最佳的估算方式是通过实际的长期剖析。
还需考虑每个实例随时间变化的存储大小和事务日志增长,以防磁盘空间不足。每个实例的峰值预期增长总量绝不能超过可用磁盘空间(以下是关于事务日志增长和轮转的良好参考:/docs/operations-manual/current/configuration/transaction-logs/)。
最后,在配置多个实例时,需要注意端口分配、可用性和冲突,尤其是与其他 Neo4j 实例使用的端口。若这些实例需要组成集群,集群成员之间通过端口/IP 的通信必须在每个成员的配置中正确设置。
此页面有帮助吗?