首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >独立WAL (先写日志)实现

独立WAL (先写日志)实现
EN

Software Engineering用户
提问于 2017-05-21 13:52:48
回答 1查看 1K关注 0票数 2

我正在探索如何构建一个预写日志。我的用例用于如下操作:

  • 记录消息(信息、调试等)
  • 文件上传

在这里,我会将代表日志消息或文件上传的一些信息写入WAL,然后尝试将该消息刷新到它的最终目的地。实际上,我想要的是一个持久的队列。我认为WAL适合这里,并且应该很容易实现而不需要额外的依赖关系,也许我错了,因此反馈是值得赞赏的,因为我的应用程序应该能够在电源故障或其他崩溃的情况下继续/恢复。

在这种情况下,我的设备是一台Kiosk,所以它基本上是世界上唯一的一台,它只是在嗡嗡作响,直到一些不好的事情发生:例如,有人不小心打开了它,它最终恢复了供电。我认为WAL适合在应用程序启动时恢复的场景。

为此,我认为System.IO.MemoryMappedFiles.MemoryMappedFile是一种潜在的实现解决方案。

到目前为止,我所勾画的是运行2 mmap的手柄。

  1. 沃尔
  2. 沃尔指数

索引的头将存储当前头和当前提交。我在这里使用COMMIT的意思是“是的,到目前为止,所有事情都已经成功地解决了”

HEAD和COMMIT之后的每个索引点都会将WAL数据的位置存储在WAL文件中。

因此,索引看起来类似于(每个索引条目表示一个4字节int):

代码语言:javascript
复制
Head        Commit      Index 0     Index 1
v           v           v           v
00 00 00 02 00 00 00 01 00 00 00 00 00 00 00 58

日志条目0从WAL文件中的字节0开始。

日志条目1从WAL文件中的字节88开始。

因此,从WAL读取条目将是读取索引N以获得范围的开始,然后读取索引N+1以获得结束(也就是下一个开始)。

在幕后,我会有一些时间来运行检查点,清理索引和WAL。这个问题的主要目的是得到天气方面的反馈--这甚至是个好主意,如果是的话,如果使用MemoryMappedFile作为WAL和WAL索引是最好的处理方法。

在像捕获日志消息这样的情况下,可能会在短时间内发生相当多的写作。

EN

回答 1

Software Engineering用户

回答已采纳

发布于 2017-05-21 19:48:15

“最佳”在很大程度上取决于使用场景和“最佳”概念的标准。

如果您正在编写仅在重新启动/恢复期间读取的日志,那么我认为普通缓冲写入仅追加的文件最好。

对于只编写本身为数据库的附加日志,并且可能经常读取旧的更新记录,内存映射的概念可能会更好。

除此之外,还有一些其他的事情要说:

在日志中更新记录的体系结构上:我可能会将更新的内容与索引信息集成起来,如果它们仅在恢复中进行串行处理的话。update记录具有一个标题,它引用上一个更新记录、内容,然后带有一个散列或校验和,以便以后对更新进行验证,以及对更新记录开始的引用。另一方面,如果某些消费者使用随机读取更新,那么索引可能会有所帮助。

我认为,一般来说,只使用附加的文件对SSD来说比更新文件的第一个字节和每个附加的字节更友好,因为这样会减少不连续的写入。

在使用内存映射文件时,如果要附加到内存映射文件,则需要使用比当前文件更大的大小映射到内存中:这用于保存附加的内容。当您到达映射大小的末尾时,您必须重新映射文件(更大),因为windows不允许在执行过程中扩展映射。所以,我要做的是用大量的松弛映射文件,然后将文件截断到适当的长度。当然,如果我没有空闲时间,我仍然准备重新映射该文件。

Windows在页面中映射文件,并且它不跟踪实际的EOF (用松弛的方式映射文件的行为会改变文件的EOF),因此维护EOF是应用程序的责任:在取消文件映射之后,可以在优雅的应用程序关闭时修复EOF。然而,如果应用程序或系统崩溃(例如停电),该文件可能会有更多的页面远远超过预期的EOF。因此,我要做的是从文件的EOF中查找最后的更新记录(这里是散列帮助验证的地方)。

票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/349362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档