Java 中的低延迟 FIX 引擎

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 54w+ 字,讲解图 2476+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 1900+ 小伙伴加入学习 ,欢迎点击围观

概述

Chronicle FIX 是我们用于 Java 的低延迟 FIX 引擎和数据库。

它的不同之处在于:

  • 专为 Java 中的超低 GC* 而设计。
  • 以最小化垃圾和开销的方式支持字符串和日期时间。
  • 可自定义以仅包含您期望的字段。
  • 使用二进制解析器和生成器中通常使用的优化,例如一次读/写 4 或 8 个字节以提高效率。
  • 建立在低延迟持久性之上,以最大限度地减少日志记录的延迟。
  • 针对 Solarflare 等低延迟网卡进行了优化。

* 超低 GC 意味着如果您将总垃圾率保持在每小时 1 GB 以下,则它平均每条消息可以产生不到一个字节的垃圾,一个 24 GB 的 Eden 可能需要一整天才能填满,而您什么也得不到次要 GC。每小时产生不到 200 MB,你可以在没有 GC 的情况下运行一周。

但是 Java 不是很慢吗?

Java 可能比 C++ 慢,但编写得好 Java 可以比编写得不好的 C++ 应用程序更快。即仅仅因为某些东西是用 C++ 编写的并不能保证它会更快。

正在测试什么?

“解析器测试”计算在本机内存中解析 214 字节的新订单单个 FIX 消息所需的时间,例如。从 SocketChannel 读取并将所有字段的值设置到一个对象中之后。在此测试中,文本字段设置为字符串,因为这是在 Java 中处理文本数据的更自然的方式。我们有更快的替代方案,例如支持 8 位字符串。

“生成器测试”计算从包含字符串和时间戳的数据生成 214 字节新订单单一 FIX 消息并将其写入本机内存所需的时间。例如准备写入套接字通道。

注意:字符串和时间戳字段是最昂贵的。有 6 个字符串和两个时间戳。

配置为使用 SampleTime 的 JMH 在每个测试中运行 10 分钟。




此图显示了解析和生成中等大小的 FIX 消息的延迟。在解析和生成中, 延迟都小于一微秒,超过 99.9% 的时间。

但是更高的百分位数呢?这些看起来不太好。这是因为我正在使用的机器有一些来自操作系统的噪音,例如我已经最小化但无法关闭的中断。


更高的延迟是由操作系统引起的。大约每毫秒有一次中断,持续约 2 微秒,甚至更罕见的延迟为 5 和 7-8 微秒。在调整得更好的服务器上,我仍然希望有中断,但它们发生的频率会降低。

下一步是什么?

下一步是性能测试与 Chronicle Journal 的集成,以查看持久性的影响。 Journal 是一个专门的 persister,类似于 Chronicle Queue v4,但已针对特定用例进行了调整。在这种情况下,我们需要 Journal 不仅要坚持每条消息 150 纳秒左右,而且要有比 Queue 更高的一致性。虽然 Queue 写入 SSD 的性能非常好,但大约千分之一到 100 分之一的写入会有签名延迟,这反映了您对磁盘子系统的选择。即它直接影响 99.9% 的延迟。我们可以用 Journal 做的是缓冲这种延迟以显着减少影响。

什么是 FIX 数据库?

MongoDB 是一个针对 JSON 消息优化的数据库。 Chronicle FIX 是针对 FIX 消息优化的数据库。它将数据存储在 FIX 中,并支持对 FIX 字段的查询,例如;给我一个客户订单 ID 的所有消息,或者给我一个特定时间发送的所有消息,或者给我传输时间和我们收到它们的时间之间最延迟的消息。

Chronicle-FIX 是 Java 代码最快的 FIX 引擎吗?

我们已经看到了各种 FIX 引擎引用的许多基准统计数据。虽然基准数据可以让您大致了解您处理的数量级,但它们几乎肯定不会让您确切了解代码的运行速度。

任何人都可以很容易地声称他们拥有最快的 FIX 引擎,并有一些基准数据来支持它,但实际上很难进行同类比较。基准将始终进行优化以适应运行它的软件。那么究竟什么才是对所有引擎的公平测试呢?即使你找到了一个每个人都同意的公平测试,你必须对代码进行多少操作和调整才能获得基准?这是用户在编写代码时自然会做的事情吗?

所以问题是,Chronicle-FIX 是最快的 FIX 引擎有点无关紧要。我们当然知道我们在正确的球场。最重要的是,Chronicle-FIX 通过咨询获得许可以确保它针对您的用例进行了优化,我们将与您合作以确保您的代码能够实现我们在基准测试中发布的那种结果。

如何使用 Chronicle FIX?

Chronicle FIX 的源代码位于 github 上,但仅供拥有许可证的人使用。

我们的想法是,如果您需要一个非常快的 FIX 引擎(以亚微秒为单位测量您的时间),我们可以帮助您以最佳方式将其集成到您的软件中。可能是您被绑定到现有的数据模型和代码库中,在这种情况下,我们拥有可以大大降低转换数据成本的技术——事实上,我们甚至没有中间数据模型。在一个未开发项目中,我们可以向您展示如何最好地围绕 Chronicle-FIX 构建您的代码。

结论

Chronicle FIX 很快。虽然 QuickFIX 难以在 50 微秒内解析 + 生成,但 Chronicle FIX 在大多数情况下可以轻松地在 2 微秒内完成这两项工作。

我们将提供更多有关持久性执行方式和数据库工作方式的文档。