如何配置Apache Flume以删除被ignorePattern属性忽略的文件

时间:2018-07-25 18:16:09

标签: flume flume-ng data-ingestion

我有数据进入spooldir,我正在使用水槽将其拾起并进一步转发以进行一些处理。

有些文件不是必需的,因此我在flume中使用igonorePattern属性以避免被拾取。

但是问题是,我收到的请求和不需要的文件数量相等,并且无法控制传入的数据,因此我必须接受进入spooldir的所有内容。

由于我有很多这些不需要的文件,因此我没有足够的磁盘空间来长时间存储它们。因此,我想知道是否有一种方法可以使flume像所有.COMPLETED文件一样自动删除这些文件(是的,我正在删除由flume拾取的文件)

1 个答案:

答案 0 :(得分:0)

水槽后台处理目录源无法删除忽略的文件。它将立即/从不删除仅处理的文件。

有三种方法可以解决此问题。

首先,您可以显式解决该问题(使用Shell脚本或任何其他可以找到忽略了模式的文件的小程序并将其删除)。我认为这不是一个好方法。

第二,您可以通过实现Flume Source Interface来编写自己的自定义假脱机目录源。对于这种小问题,需要大量的精力和艰巨的挑战。

第三种滥用解决方案,您可以使用Morphline Interceptor。在Flume用户指南的this部分中提到了Morphline拦截器。另外,您可能还想看看Morphline Reference

拦截器从源获取事件,进行一些处理,最后将其转发到您所知道的通道。

如果选择第三个解决方案,则必须使用kite-sdk。您必须使用 flume-env.sh 将Cloudera的Kite Morphlines Core依赖项添加到您的 FLUME_CLASSPATH 或只需将jar添加到 $ APACHE_FLUME_HOME / lib

在此解决方案中,您的Flume配置示例将为:

a1.channels = ch-1
a1.sources = src-1
a1.sinks = k1
a1.sources.src-1.interceptors = morph

a1.sources.src-1.type = spooldir
a1.sources.src-1.channels = ch-1
a1.sources.src-1.spoolDir = /spool/dir
a1.sources.src-1.fileHeader = true
a1.sources.src-1.ignoredPattern = 'whatever'

a1.sources.src-1.interceptors.morph.type = org.apache.flume.sink.solr.morphline.MorphlineInterceptor$Builder
a1.sources.src-1.interceptors.morph.morphlineFile = /etc/flume-ng/conf/morphline.conf
a1.sources.src-1.interceptors.morph.morphlineId = morphline1

a1.sinks.k1.type = file_roll
a1.sinks.k1.channel = ch-1
a1.sinks.k1.sink.directory = /roll/dir

然后,您可以创建一个自定义的morphline拦截器文件,该文件为 $ APACHE_FLUME_HOME / conf / morphline.conf

在此conf文件中,您可以根据需要进行处理,只是要注意将记录对象返回给子进程。

这也不是一个好的解决方案,但是您可以编写Java代码以在Flume交易期间进行任何处理。在每次事件中,您都可以检查目录,如果不需要该文件,则可以将其删除。 (您必须确保正在运行Java进程的用户对此目录具有权限)

morphlines : [
  {
    id : morphline1
    importCommands : ["org.kitesdk.**"]
    commands : [
      {
        readJson { }
      }
      {
        java {
          imports : """
            import java.io.File;
            import java.io.IOException;
          """
          code : """
            try {
                // This code from my flume agent, you may want to use it, but it is not necessary
                // JsonNode rootNode = (JsonNode) record.getFirstValue(Fields.ATTACHMENT_BODY);    

                // You can traverse in the relevant directory
                // and find the ignored pattern manually
                // then you can delete it with java code

                //Second part of my code
                //String rootNodeStr = rootNode.toString();
                //record.put("rootNodeStr", rootNodeStr.getBytes(StandardCharsets.UTF_8));
              }
            } catch (IOException e) {
              logger.error("So sad",e);
            }
            return child.process(record);
          """
        }
      }
      {
        setValues {
          _attachment_body : "@{rootNodeStr}"
        }
      }
    ]
  }
]

我希望这会有所帮助。