Pen*_*gin 7 jvm scala numa akka
我的问题涉及JVM应用程序可以在多大程度上利用主机的NUMA布局.
我有一个Akka应用程序,其中actor通过将传入数据与已加载到不可变(Scala)对象的"公共"数据相结合来同时处理请求.该应用程序使用许多双核VM在云中很好地扩展,但在单个64核计算机上表现不佳.我认为这是因为公共数据对象驻留在一个NUMA单元中,并且从其他单元同时访问的许多线程对于互连来说太多了.
如果我运行64个单独的JVM应用程序,每个应用程序包含1个actor,那么性能再次良好.一个更温和的方法可能是运行与NUMA单元一样多的JVM应用程序(在我的情况下为8),使主机操作系统有机会将线程和内存保持在一起?
但是有没有更聪明的方法在单个JVM中实现相同的效果?例如,如果我用一个案例类的几个实例替换我的公共数据对象,那么JVM是否有能力将它们放在最佳NUMA单元上?
更新:
我正在使用Oracle JDK 1.7.0_05和Akka 2.1.4
我现在尝试使用UseNUMA和UseParallelGC JVM选项.当使用一个或几个JVM时,似乎都没有对性能降低产生任何重大影响.我也尝试过使用PinnedDispatcher和thre-pool-executor,但没有效果.我不确定配置是否有效,因为启动日志中似乎没有什么不同.
当我为每个工人使用一个JVM(~50)时,最大的改进仍然存在.然而,问题似乎是在FailureDector注册Akka集群JVM之间成功交换"第一个心跳"之前存在很长的延迟(最多几分钟).我怀疑还有其他问题,我还没有发现.我已经不得不增加ulimit -u,因为我达到了默认的最大进程数(1024).
只是为了澄清,我并没有尝试获得大量的消息,只是试图让许多独立的actor同时访问一个不可变的对象.
我认为,如果您确定问题不在消息处理算法中,那么您不仅应该考虑 NUMA 选项,还应该考虑整个环境。配置,从 JVM 版本开始(最新的更好,Oracle JDK 也大多比 OpenJDK 表现更好),然后是 JVM 选项(包括 GC、内存、并发选项等),然后是 Scala 和 Akka 版本(最新的候选版本和里程碑可能会好得多)还有 Akka 配置。
从这里您可以借用所有重要的东西,以便在现代笔记本电脑上为 Akka Actor 提供每秒 50M 条消息的总吞吐量。
从未有机会在 64 核服务器上运行这些基准测试 - 因此我们将不胜感激任何反馈。
ForkJoinPool根据我的发现,当池中线程数量增加时,当前的实现会增加消息发送延迟,这可能会有所帮助。当 Actor 之间的响应请求调用率较高的情况下,例如在我的笔记本电脑上,当将池大小从 4 增加到 64 时,这种情况下 Akka Actor 的消息发送延迟对于大多数执行程序服务而言会增长到 2-3 倍,这是非常值得注意的(Scala 的ForkJoinPool、JDK 的ForkJoinPool)ThreadPoolExecutor。
mvnAll.sh您可以通过将系统变量设置为不同的值来运行来检查是否存在任何差异benchmark.parallelism。
| 归档时间: |
|
| 查看次数: |
898 次 |
| 最近记录: |