Flink读取HDFS中的xml(二)——Flink XmlInputFormat读取xml

Flink官方和社区没有给出读取xml文件流的方式,或许是因为以xml文档格式本身不适合做为流数据的记录。
在我的项目遇到需要读取大量xml文件的问题,具体描述为以下几点:

  1. xml文件按照一定时间周期提供
  2. 文件以zip方式压缩,分两类大文件和小文件
  3. 大的几百M,小的几百KB到10几M
  4. 小文件很多,每一批有4万左右
  5. 只需要xml文件中极少个指定标签名称的数据

一开始,我们选择了将zip解压后上传的HDFS,然后读取xml文件使用SAX方式完成解析,思路如下:
实际上是参考了Flink-WikipediaEditCount的方法

  1. 自定义XmlInputFormat,实现按指定开始标签和结束标签分段读取xml文件。
  2. 在后续的map方法中使用SAX方式对读取的xml片段进行解析。

Flink-WikipediaEditCount基础上,我们添加了对文件名的记录、过滤等改动。
这里重点说一下,XmlInputFormat的实现:
它继承自TextInputFormat,重写了createRecordReader方法返回一个XmlRecordReader对象。而XmlRecordReader继承自RecordReader,运行时Flink通过判断RecordReader.nextKeyValue方法的返回值判断是否还有数据待读取,然后通过getCurrentKey和getCurrentValue方法获取读取的数据。具体的读取过程如下:

  1. XmlRecordReader初始化时指定开始标签和结束标签
  2. 一直读取,直到读取到开始标签
  3. 一直读取,变读取边记录数据到buffer中,直到读取到结束标签或者文件结束
  4. 读取到结束标签时,将buffer中的数据赋值到value,清空buffer,在nextKeyValue方法中返回true标识完成读取且读取到了数据

本文记录的方法解决了Flink从HDFS读取xml的方法,解决了大xml文件的解析问题,但是大量小xml文件解压后上传HDFS后在还存在:解压操作耗时、小文件造成HDFS空间浪费、打开大量文件耗时的问题。
参考链接:
Flink-WikipediaEditCount
org.apache.mahout.text.wikipedia.XmlInputFormat

你可能感兴趣的:(Flink读取HDFS中的xml(二)——Flink XmlInputFormat读取xml)