天天看点

FSDataOutputStream中的hsync()不起作用?

最近在做一个demo,用flume收集实时日志到hdfs,然后用spark来读,写入spark用的的FSDataOuputStream,写入的格式是avro格式的。计划是在append数量到了1000条的时候就flush一次,结果发现调用hflush后,只有第一次的时候文件大小才会变化,根据这个接口说明,一旦hflush后,reader能可以看到最新的数据,于是,写了个reader去读,真的能读到。但是用spark去加载,发现只能加载到第一次hflush的数据,后面hflush的数据是加载不到的,除非调用close把写入流关了才行。于是百度一下,改用hsync,发现还是不行。接着继续百度,发现了一个线索,有人说要hsync的时候要传入sync标记,可我一看FSDataOuputStream的定义,根本没有带这个标记的hsync方法,找了好久,发现DFSOutputStream中有一个这样的方法,于是调试了一下,发现FSDataOuputStream中有一个属性“wrappedStream”,刚好在运行时是DFSOutputStream对象,FSDataOuputStream实际是调用DFSOutputStream的hsync方法(不带参数的),DFSOutputStream的hsync方法中又调用了带参数的hsync(EnumSet<SyncFlag> syncFlags)方法,只是传入的默认值,就是空的sync标记,难怪文件大小不会刷新,于是先调用FSDataOuputStream中的getWrappedStream把这个DFSOutputStream对象拿出来,调用它的hsync(EnumSet<SyncFlag> syncFlags)方法,自己建一个EnumSet<SyncFlag> 参数放进去,我用的是“UPDATA_LENGTH”,进行测试,发现成功了,每一次hsync都会发现文件的大小在变化。

继续阅读