我的问题涉及 JVM 应用程序可以在多大程度上利用主机的 NUMA 布局。
我有一个 Akka 应用程序,其中参与者通过将传入数据与已加载到不可变(Scala)对象中的“通用”数据组合来同时处理请求。该应用程序在云中可以很好地扩展,使用许多双核 VM,但在单个 64 核机器上表现不佳。我认为这是因为公共数据对象驻留在一个 NUMA 单元中,并且从其他单元同时访问的许多线程对于互连来说太多了。
如果我运行 64 个单独的 JVM 应用程序,每个应用程序包含 1 个参与者,那么性能又会很好。更温和的方法可能是运行与 NUMA 单元(在我的情况下为 8 个)一样多的 JVM 应用程序,让主机操作系统有机会将线程和内存保持在一起?
但是有没有更聪明的方法可以在单个 JVM 中实现相同的效果?例如,如果我用案例类的多个实例替换我的公共数据对象,JVM 是否有能力将它们放置在最佳 NUMA 单元上?
更新:
我正在使用 Oracle JDK 1.7.0_05 和 Akka 2.1.4
我现在尝试使用 UseNUMA 和 UseParallelGC JVM 选项。在使用一个或几个 JVM 时,两者似乎都不会对缓慢的性能产生任何显着影响。我也尝试过使用 PinnedDispatcher 和 thre-pool-executor,但没有任何效果。我不确定配置是否有效,因为启动日志中似乎没有什么不同。
当我为每个工作人员(约 50 个)使用单个 JVM 时,最大的改进仍然存在。但是,这个问题似乎是在 FailureDector 注册 Akka 集群 JVM 之间“第一次心跳”的成功交换之前有很长的延迟(最多几分钟)。我怀疑这里还有其他一些我尚未发现的问题。我已经不得不增加 ulimit -u 因为我达到了默认的最大进程数(1024)。
只是为了澄清一下,我不是试图获得大量消息,只是试图让许多单独的参与者同时访问一个不可变对象。