问题说明
近期项目中用到实时抽取ActiveMQ中的爬虫数据到HIVE表中,但是在持久化数据到HDFS的时候,发现FSDataOutputStream.hsync()不能实时持久化,只能持久化第一条数据。
从一些文章中了解到,只有当HDFS中的block达到128M时,才可以使block处于completed状态,即持久化显示查到,故在代码测试中如果将流close掉,即可实现持久化,但是与业务场景不服;
拓展HDFS的hflush,hsync和close区别
hflush: 语义是保证flush的数据被新的reader读到,但是不保证数据被datanode持久化。
hsync: 与hflush几乎一样,不同的是hsync保证数据被datanode持久化。
close: 关闭文件,除了做到以上2点,还保证文件的所有block处于completed状态,并且将文件置为closed。
解决方法
查看源码,发现FSDataOuputStream中有一个方法getWrappedStream(),返回DFSOutputStream对象;
在DFSOutputStream中有一个方法:hsync(EnumSet syncFlags);
从方法说明中可以了解到,决定是否更新block的长度标识(即持久化);
自己建一个EnumSet 参数放进去,其中SyncFlag中含有一个

在将ActiveMQ中的爬虫数据实时抽取到HIVE表并写入HDFS时,发现FSDataOutputStream的hsync()方法无法实时持久化数据。问题在于HDFS的block只有达到128M时才会完成持久化。对比了hflush、hsync和close的区别,了解到hsync能确保数据在datanode上持久化。为解决此问题,深入源码,通过DFSOutputStream的hsync()方法配合特定参数实现了数据的正确持久化。

1867

被折叠的 条评论
为什么被折叠?



