30 秒看懂
Ron Minsky 和 Doug Patti 解释 Concord 如何通过确定性状态机、排序器和可重放的事务日志,为客户提供可靠的交易服务。两人还探讨 Aria 的共享基础设施、跨主题排序、版本管理、权限,以及限流和快照等尚待解决的挑战。
- 1确定性重放Concord 一次处理一条消息,通过重放相同的有序事务日志重建状态。
- 2一个排序器,一种顺序排序器给提议的消息加上序列号并重新发布;重传服务负责填补缺失。
- 3显式状态改善测试应用等待系统询问才提出消息,将待处理意图保存在可检查的状态中,从而能够受控地测试竞态条件。
- 4Aria 作为共享基础设施Aria 保留这一编程模型,同时通过集中管理的基础设施、代理和层级主题支持更多应用。
- 5跨主题排序共享顺序使结合市场数据和订单的决策在重放时能够重现。
- 6快照取决于应用快照可以避免漫长重放,但足以支持一种计算的快照可能无法满足另一种计算。
要点建议
- 确定性状态机可以通过重放相同的有序消息重建状态。
- 序列号和重传机制为不可靠的组播流增加了恢复能力。
- 显式状态和控制反转使竞态条件更容易在测试中重现。
- 单个排序器可以承受相当大的工作负载,但消费者和共享基础设施仍面临性能限制。
- 跨主题的全序使结合多个数据流的决策能够重现。
- 消息版本、代码语义和针对应用的快照使共享系统的恢复更加复杂。
按章节阅读整理后的全文
客户交易与可靠性
Patti 介绍 Concord 面向客户交易的责任。当订单和成交结果必须在故障后保留时,重连和持久性至关重要。
Ron Minsky 介绍 Jane Street 从事分布式系统开发的 Doug Patti。Patti 此前使用 Node.js 和 Ruby 构建 Web 框架与 API;在 Jane Street,他接触了不同的技术,系统也常常围绕交易日组织。
Patti 介绍 Concord:它为与客户的直接交易关系而建。Jane Street 既提供流动性,也提供类似交易所的基础设施。因此,可用性、快速响应和满足监管要求的审计记录都是重要责任。
客户连接并发送订单后,系统尝试将其与交易团队的订单撮合。若撮合成功,成交结果会分别发送给客户、交易团队和监管报告机构。这是对端到端服务的简化描述。
客户发送订单后如果断线,必须能够查明订单是否收到、是否成交。即使一台机器崩溃,系统也必须保留这些信息,并能在几分钟内将进程迁移到另一台机器,而不是等待数小时修复。
Patti 解释,FIX 消息带有序列号。重新连接后,双方可以识别并交换遗漏的消息。Minsky 将其与 TCP 对比:TCP 只在单次连接内保证数据顺序,连接丢失或主机崩溃后,需要额外一层来恢复会话状态。
系统还必须应对异常繁忙的交易日,流量有时比平时高出数个数量级。除了客户订单,监管需求还使系统接收公开交易所的市场数据,从而形成必须高效处理的高负载路径。
状态机与事务日志
确定性消息处理使重放成为可能。组播、序列号和重传共同分发一致的日志。
Concord 使用复制状态机。这里的状态机是一个模块,一次处理一条消息,更新封装的状态,并可能产生动作。每条消息都以同步、确定的方式处理,不会因网络或磁盘请求而阻塞。
有了相同的代码和相同顺序的消息,重启后的进程可以从当天开始重放事务日志,重建此前的状态。Minsky 强调了两个必要条件:确定性的应用,以及可靠、共同的消息顺序。
Concord 使用 UDP 组播分发日志。发送到组播地址的数据包由网络交换机复制给订阅者,高效地将一条消息分发给多个进程。UDP 可能丢包或改变顺序,因此 Concord 增加了自己的可靠性层。
序列号可以显示缺口:进程收到 45、47 和 48 后,可以向重传服务请求 46。Patti 说,即使丢包频繁,包括进程跟不上速度的情况,这也能奏效。重传服务监听并保存排序后的数据流,并可向其他重传服务或排序器请求缺失数据包。
排序与性能
单个排序器为消息提议排序,备用排序器由人工提升。Patti 介绍工作负载的吞吐量和延迟。
任何进程都可以通过组播提出一条消息。一个排序器接收这些提议,分配序列号和时间戳,再重新发布给监听者。这个单一位置将传入消息转换为统一的标准顺序。
如果 Concord 的排序器故障,新消息就会停止。备用排序器可以由人工提升;Patti 说,团队宁愿短暂停顿,检查系统并确认状态可靠后再恢复交易。访谈没有深入讨论共识算法。
单个排序器可能成为瓶颈,但 Patti 说,这一设计适合 Concord 的工作负载。限制包括 10 Gbps 网络、数据包处理能力和磁盘写入。他报告某个交易日的日志超过 400 GB,基准速率超过每秒 10 万条消息,繁忙时则达到数倍。
Minsky 认为,可扩展性应针对实际的有限工作负载来判断。紧凑编码,尤其是对频繁出现的市场数据,有助于让系统维持在能力范围内。Patti 说,应用提出消息、经过排序器再返回的往返时间约为 8 至 12 微秒。
测试与组合
控制反转暴露状态,便于精确测试。较小的状态机可以组合或分布到多个进程。
Concord 也是一个应用框架。确定性的同步状态机让测试更有力:测试可以按选定顺序注入消息,在特定时刻暂停,并重现在生产环境中很难触发的竞态条件。
框架采用控制反转。应用处理消息并记录自己想发送什么,但不会随时自行发送,而是等待系统询问下一条提议。这迫使待处理的意图进入显式状态,而不是隐藏在暂停的控制流中,使测试可以检查它们。
Minsky 将这种方式与使用 select 的事件驱动编程联系起来。线程可以让顺序代码更容易表达,但也会将状态隐藏在栈和程序计数器中,并需要协调。Concord 完整处理一条消息后才处理下一条,将状态暴露在普通数据结构中。
Patti 说,状态机可以由更小的状态机组合而成。运行太慢的进程可以拆分,相关进程也可以合并。由于不同进程看到相同的有序消息并使用确定性代码,它们可以包含同一组件,独立得出相同视图,无须直接查询对方。
Concord 的限制
消费者需要跟上高流量数据流,共享消息类型也使回滚变复杂。独立实例的运营成本很高。
这种设计也有代价。大多数进程必须检查每条消息,即使它们会快速丢弃属于其他子系统的消息。它们必须跟上数据流,优化数据结构和内存分配,有时还要将工作拆分到多个进程以获得更多 CPU 资源。
Concord 庞大的共享消息类型也使版本管理脆弱。如果新消息格式已经写入日志,而团队回滚到无法读取它的代码,恢复就会失败。摘要检查会让不兼容的应用停止,而不是错误解释数据流,因此发布需要仔细协调。
Patti 和 Minsky 区分了这一具体实现与更普遍的约束:任何持久化消息都必须在将来可读,而广播流无法分别与每个消费者协商协议。支持多个版本是可能的,但日志和恢复模型确实带来兼容性要求。
每个 Concord 实例都有自己的排序器、重传服务、配置和硬件。Patti 说,这些开销让部署新实例的管理成本很高,虽然对大型应用来说可能值得,但不适合小型服务。
Aria 与有序主题
Aria 提供共享基础设施和过滤功能。全局顺序使结合多个主题的计算能够重现。
Aria 旨在成为更通用的共享服务。它像 Concord 一样结合了传输机制和控制反转的应用框架,但核心基础设施由 Aria 团队管理。用户只需在机器上运行应用,通过代理连接,而不必部署完整的 Concord 实例。
代理过滤消息,因此小型应用不必处理自己不用的高流量数据流。核心基础设施仍要处理全部流量,但它将消息内容视为不透明的字节;客户端负责内容格式和版本。核心扩展主要涉及移动和存储字节。
Aria 用层级主题组织数据,客户端可以订阅一个子树。关键是跨主题的消息仍保持统一的标准顺序。Patti 举例说,需要将订单与当时的市场数据关联起来:崩溃后重放必须保持两者的相对顺序。
Minsky 将此与他对 Kafka 的理解作对比:Kafka 在分片内保证顺序,而不是跨主题保证顺序。当应用结合多个数据流时,重放时不同的交错顺序可能改变决策。共享全序则允许跨主题进行确定性复制。
版本与权限
不同消息版本和状态机语义带来细微问题。写入控制和尽力而为的读取检查用于管理主题访问。
Aria 允许用户在不同主题上发布不同协议版本,让旧客户端继续消费旧版本。Minsky 指出一个限制:即使每个版本内部的消息顺序不变,它们与无关消息的交错方式也可能不同,因此不同版本不一定产生相同的跨主题行为。
Patti 补充了另一个版本问题:状态机代码本身也会变化。新二进制程序重放相同消息时,可能作出不同解释并得到不同状态。Aria 用户必须谨慎管理配置和语义变更;仅有共同日志并不能保证运行不同代码的副本等价。
Aria 限制谁可以写入主题子树。读取权限更难控制,因为任何能够监听该地址的人都可能收到组播数据包。讨论时,团队正在客户端库中增加基于信任、尽力而为的读取检查,而不是建立严格的组播安全边界。
Minsky 指出,读取限制也能保护抽象:用户不应意外依赖团队预期会更改的内部主题。Patti 说,Aria 将部分自身会话元数据也保存在 Aria 上,因此面临同样的问题。将配置变更写入有序日志,也能让消费者一致地知道新配置何时生效。
限流与快照
过量流量仍可能影响共享基础设施。快照降低重放成本,但必须适合应用的计算方式。
Aria 已在多个区域投入生产,使用团队的数量有意保持有限。Patti 说,新客户会带来新需求,而设计决定的影响会持续很久。一些所需功能当时仍然缺失,包括限流。
没有限流时,故障客户端可能以最快速度反复注入消息。主题过滤可以阻止无关订阅者收到这些消息,但排序器、代理和其他共享基础设施仍必须处理它们;由于每个字节都要保存以供重放,磁盘使用量也是问题。
快照是更难的开放问题。当时,重启的应用必须从当天开始重放所订阅主题。若将会话延长到一周,临近结束时重启可能需要重放数百 GB;快照可以提供某一时刻的状态,让应用从该处继续重放。
Minsky 将此与交易所市场数据流对比:后者提供可靠数据流和缺口恢复,也提供快照。但合适的快照取决于计算内容。例如,当前订单簿可以恢复未完成订单的数量,却无法恢复当天出现过的订单总数。
Patti 介绍了让用户构建适合自身应用的快照服务器,并组合多个主题状态的做法。Minsky 指出,提供方仍可为常见场景提供可复用的快照组件。Patti 将其视为可组合性:客户端可以复用、扩展或压缩组件以满足需求。
推广与模式
早期用户和示例帮助建立编程模型。Patti 希望扩大采用范围,同时扩展共享服务的容量。
Aria 的早期用户主要来自客户技术部门,包括将自动化与人工决策结合的高接触度工作流程系统。核心系统仍在演进时,组织上的接近让协调更容易。Minsky 指出,即使收益值得投入,这种编程模型仍需要时间学习。
Patti 希望记录 Concord 中反复出现的模式,提供示例或具有即时测试反馈的训练营。一种常见模式是注入器,将外部数据转换成流消息。如果排序后没有更新显式状态,一个隐蔽的错误就可能导致它永远重复提出同一条消息。
Minsky 将应用比作问题求解器:当数据流缺少某个外部事实时,它提出一条消息;问题解决后,无论由哪个进程解决,它都会停止提出。Patti 说,抽象可以避免常见错误;例如,基于管道的注入器提供熟悉的接口,使每个元素只排序一次。
展望未来,Patti 希望更多团队使用 Aria,并带来更高带宽需求。团队预计会在需要时改善公平性和扩展共享基础设施,在提前实现功能与投入时间开发其他功能之间取得平衡。
同频道的其他文章
15:33EN → 简体中文
1:48:29EN → 简体中文
1:36:37EN → 简体中文
1:05:45EN → 简体中文
1:25:00EN → 简体中文
1:16:29EN → 简体中文