在Martin Fowler's write-up of the LMAX-disruptor architecture,他说:
journaler的工作是以耐用的形式存储所有事件,所以 如果出现任何问题,他们可以重播。 LMAX不使用 这个数据库,只是文件系统。他们将事件流入 磁盘。
我很好奇基于文件系统的事件日志的实现在实践中是什么样的。 following answer表示它被写入“原始文件”,但我对可能为生产系统实现的实际细节感兴趣。它是字面上的原始文本文件,包含连续附加到的结构化日志?或者它是某种二进制格式?是否有任何关键的设计决策进入系统的这个组成部分?
答案 0 :(得分:1)
建议的记者需要包含两条信息:收到的事件本身和某种标识符,用于跟踪日记中的位置,以便您可以选择在重播期间从该记录开始。
存储格式最终是您的决定,但以下注意事项适用:
重播可能不仅需要从系统崩溃中触发,还需要从您自己的代码中的错误中触发。输入消息字节流的操作越少越好。对字节流的任何操作都会引发错误,并使您的重放逻辑与“将字节丢弃回输入缓冲区”非常不同。 对我而言,这可能是最大的决定。
重播应该快速且不包含业务逻辑。允许存储设备按顺序存储而不需要来回跳转的文件格式(例如带索引的数据库)将要求性能更好。环形缓冲区输入和存储层之间的层数越多,速度就越慢。
磁盘上的预分配存储(您甚至可以使用RAW分区)将允许您从头到尾编写字节,而无需更新文件系统的目录元数据和自由空间跟踪区域。这应该简化并提高性能。只要这个预分配足以保持检查点之间的所有数据,你就可以了。随着存储设备的改进,随着时间的推移,这变得不再那么令人担忧。
答案 1 :(得分:1)
日志工作者只是主应用程序环缓冲区的另一个消费者。消息从线路读取,添加一个标头(接收时间戳等),然后输入到环形缓冲区。
有三个消费者:
应用程序处理程序在日志程序完成时被门控,而来自辅助程序的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