1

Martin Fowler 对 LMAX-disruptor 架构的描述中,他说:

Journaler 的工作是以持久的形式存储所有事件,以便在出现任何问题时可以重播它们。LMAX 不为此使用数据库,仅使用文件系统。他们将事件流式传输到磁盘上。

我很好奇基于文件系统的事件日志在实践中的实现是什么样的。以下答案说它被写入“原始文件”,但我对可能为生产系统实现的实际细节感兴趣。它真的是一个包含不断附加的结构化日志的原始文本文件吗?还是某种二进制格式?系统的这个组件是否有任何关键的设计决策?

4

2 回答 2

2

journaller 只是主应用程序环形缓冲区的另一个消费者。从线路读取消息,添加一个标头(接收到的时间戳等),然后将其馈入环形缓冲区。

消费者分为三种:

  1. 应用程序处理程序(调用业务逻辑)
  2. 复制发件人(将消息复制到辅助服务器)
  3. 日志处理程序

应用程序处理程序在日志记录器完成和来自辅助节点的 ack 上进行门控,确保接收到的消息在辅助节点的环形缓冲区和本地系统页面缓存中,然后再处理应用程序消息。

日志器非常愚蠢 - 消息以有线格式附加到固定长度的日志文件中。该文件是预先分配的,并且使用了各种文件系统挂载选项来最小化写入延迟。最后,我们发现 XFS 是最好的文件系统选项,但前提是没有正在写入的日志文件的并发阅读器。否则 XFS 代码中可能会出现令人讨厌的锁定效果。

如果您对我们如何得出这些结论感兴趣,我将所有这些都写得很详细:

https://epickrram.blogspot.co.uk/2015/05/improving-journalling-latency.html

https://epickrram.blogspot.co.uk/2015/07/seek-write-vs-pwrite.html

https://epickrram.blogspot.co.uk/2015/12/journalling-revisited.html

于 2018-02-09T09:22:30.977 回答
1

建议的日志记录器需要包含两条信息:接收到的事件本身和某种标识符,用于跟踪您在日志中的位置,以便您可以在重播期间从该记录开始选择。

存储格式最终由您决定,但需要考虑以下注意事项:

  • 重播可能不仅需要从系统崩溃触发,还需要从您自己代码中的错误触发。输入消息字节流的操作越少越好。对字节流的任何操作都会引入错误的机会,并使您的重播逻辑与“将字节放回输入缓冲区”非常不同。对我来说,这可能是最大的决定。

  • 重播应该快速且不包含业务逻辑。允许您的存储设备按顺序存储并且不需要来回跳跃的文件格式(例如具有索引的数据库将需要)将更好地提高性能。环形缓冲区输入和存储层之间的层数越多,速度就越慢。

  • 磁盘上的预分配存储(您甚至可以使用 RAW 分区)将允许您从头到尾写入字节,而无需更新文件系统的目录元数据和可用空间跟踪区域。这应该简化并提高性能。只要这种预分配足以在检查点之间保留所有数据,就可以了。随着存储设备的改进,随着时间的推移,这变得不再那么令人担忧。

于 2018-01-24T13:52:02.160 回答