让我们想象一个假设的 Java 中的 HFT 系统,需要(非常)低延迟,由于不变性(Scala?),有许多短命的小对象,每秒数千个连接,以及大量消息在事件驱动架构(akka 和 amqp?)。
对于那里的专家来说,(假设)什么是 JVM 7 的最佳调优?什么类型的代码会让它开心?Scala 和 Akka 会为这种系统做好准备吗?
注意:有一些类似的问题,比如这个,但我还没有找到一个涵盖 Scala 的问题(它在 JVM 中有自己的特殊足迹)。
让我们想象一个假设的 Java 中的 HFT 系统,需要(非常)低延迟,由于不变性(Scala?),有许多短命的小对象,每秒数千个连接,以及大量消息在事件驱动架构(akka 和 amqp?)。
对于那里的专家来说,(假设)什么是 JVM 7 的最佳调优?什么类型的代码会让它开心?Scala 和 Akka 会为这种系统做好准备吗?
注意:有一些类似的问题,比如这个,但我还没有找到一个涵盖 Scala 的问题(它在 JVM 中有自己的特殊足迹)。
在 Java 中实现非常好的性能是可能的。但是,问题需要更具体才能提供可信的答案。您的主要延迟来源将来自以下非详尽列表:
您创建了多少垃圾以及 GC 收集和推广垃圾的工作。根据我的经验,不可变设计不适合低延迟。GC 调优需要重点关注。
预热 JVM 以便加载类并且 JIT 有时间完成它的工作。
将您的算法设计为 O(1) 或至少 O(log2 n),并进行性能测试来证明这一点。
你的设计需要是无锁的,并且遵循“单写原则”。
需要付出巨大的努力来理解整个堆栈并在其使用中表现出机械的同情。
将您的算法和数据结构设计为缓存友好。如今,缓存未命中是最大的成本。这与进程亲和性密切相关,如果设置不正确,可能会导致严重的缓存污染。在某些情况下,这将涉及对操作系统甚至一些 JNI 代码的同情。
确保您有足够的内核,以便任何需要运行的线程都有可用的内核,而无需等待。
我最近写了一篇关于这种练习的案例研究的博客。
在我的笔记本电脑上,Akka 2.3.7 参与者之间 ping 消息的平均延迟约为 300 纳秒,这比由于 JVM 上的 GC 暂停而预期的延迟要小得多。
英特尔酷睿 i7-2640M 上 Akka 和其他参与者的代码(包括 JVM 选项)和测试结果。
PS 你可以在 Dmitry Vyukov 的网站和 Martin Thompson 的博客中找到许多低延迟计算的原则和技巧。
您可能会发现使用环形缓冲区进行消息传递将超过 Akka 所能做的。人们在 JVM 上用于金融应用程序的主要环形缓冲区实现是一种称为 Disruptor,它针对效率(两倍大小的幂)、JVM(无 GC、无锁)和现代 CPU(无虚假共享缓存行)。
这是从 Scala 的角度来看的介绍演示http://scala-phase.org/talks/jamie-allen-sdisruptor/index.html#1,最后一张幻灯片上有指向原始 LMAX 内容的链接。