NIFI源码学习-(四、3 )WAL细节

上篇文章理清楚了NIFI WAL机制实现的大致流程,但是想一想的话,还只是实现了在操作数据之前先写日志,但是每次每次修改都写日志,都得持久化到文件中,那效率这块儿是如何保证的呢?

带着这个疑问,继续跟着上篇文章暂时搁置的 update 方法来一探究竟。

进入到 SequentialAccessWriteAheadLog 成员变量 journal

在checkpoint的时候,会对它进行更新,同时把 streamPool 也传了进去。

这里使用了对象池化技术,因为应该是这个对象创建的时候,还是比较耗时的。

这里只有两个方法,从对象池中获取对象,另一个是把对象还回对象池。

来看下对象池中存放的对象:

 ByteArrayOutputStream  是用来把数据写入类型为字节数组的缓存中

DataOutputStream 可以很方便地让应用把原始的java类型写入输出流。同时可以注意到,这个DataOutputStream 最终也是要写入到ByteArrayOutputStream   的缓存中的。

 接着看update方法,实现选择 LengthDelimitedJournal

 进入红框中的 serializeEdit() 方法,具体的实现选这个:

 

这个方法看着就比较直观了,就是按照顺序往流中写入record的各个部分了,注意到 81-84 的注释

 如果record中有目的连接,那么这个连接就是与这条记录相关联的连接,,启动时,我们将会把这个连接作为flowfile的源连接,因为我们是在把流文件路由到队列之前,对流文件序列化的。所以在写入时候,当流文件 Destination 不为空,日志中序列化的是 Destination 。反序列化的时候,把它作为流文件的 originalQueue ,这样,序列化入文件的队列就能回到界面上它应该在的位置。以下是反序列化的代码:

这样就解答了我们之前的疑问,NIFI初始化的时候是如何让流文件恢复到它所在的位置的。

这个时候,数据写入到了  ByteArrayOutputStream   的字节数组缓存中。

 这个out  指向了journal文件,baos.writeTo(out),最终把数据写入了文件,就是下边这个文件。

这里边还有一个细节:

这个判断,当缓存中的数据大小,超过了设置的阈值的时候,会把后续的内容,写入overflow文件。

所以这里可以看到,WAL把更新日志,顺序地写入了单个日志文件中,单个文件的顺序写操作,肯定要快于对实际数据的随机更新。注释中也有提到,速度是充分利用了磁盘的写入速度的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值