我有数据进入spooldir,我正在使用水槽将其拾起并进一步转发以进行一些处理。
有些文件不是必需的,因此我在flume中使用igonorePattern属性以避免被拾取。
但是问题是,我收到的请求和不需要的文件数量相等,并且无法控制传入的数据,因此我必须接受进入spooldir的所有内容。
由于我有很多这些不需要的文件,因此我没有足够的磁盘空间来长时间存储它们。因此,我想知道是否有一种方法可以使flume像所有.COMPLETED
文件一样自动删除这些文件(是的,我正在删除由flume拾取的文件)
答案 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}"
}
}
]
}
]
我希望这会有所帮助。