flume spoolDirectory Source原生代码流程及其拓展
来源:互联网 发布:eclipse端口号在哪改 编辑:程序博客网 时间:2024/06/08 02:00
最近我们要在flume的基础上做定制开发。我这块主要的开发是,对zip包中的文件做一定的处理后,以avro方式序列化。整个流程参考了flume的spoolDirectorySource的实现,因为主要是对spooldirectorySource中文件解析的部分进行了参考,所以下面的文章将会着重分析文件的解析部分。
特此声明:该文仅做记录和探讨之用,文中没有涉及任何公司业务相关的部分。
1、 spoolDirectorySource简要介绍
SpoolingDirectorySource可以监控指定目录,如果有有新文件出现在指定目录,source会将这个新文件按照配置中的的序列化类型,将文件序列化成一个个event。在文件中的所有的内容都读取到Channel之后(commit),Spooling Directory Source才会对文件进行重命名或者删除,这样就保证了数据不会丢失,虽然可能有一些冗余,但是是在我们接受范围内的。
2、spoolDirectorySource工作流程
下图是根据代码流程画的一个流程图,可能会有些谬误,仅供参考哈。
2.1、 Function--configure
启动spool directory source第一步,configure方法。通过SpoolZipDirectorySourceConfigurationConstants中定义的那些配置,将context 中的相关配置信息提取出来,比如文件输入路径(SpoolZipDirectory);同时在方法里也对一些不能为空的参数族做判断,保证必须参数的存在。
public synchronized void configure(Context context) {SpoolZipDirectory= context.getString(SPOOL_ZIP_DIRECTORY);Preconditions.checkState(SpoolZipDirectory!= null, "Configuration must specify a spooling directory");completedSuffix= context.getString(SPOOLED_FILE_SUFFIX, DEFAULT_SPOOLED_FILE_SUFFIX);deletePolicy= context.getString(DELETE_POLICY, DEFAULT_DELETE_POLICY);fileHeader= context.getBoolean(FILENAME_HEADER,DEFAULT_FILE_HEADER);……}
2.2、Function--start
获取配置信息后,就可以执行start方法启动source。
2.2.1、在start方法中,首先通过ReliableSpoolingFileEventReader.java中的builder类创建了一个ReliableSpoolingFileEventReader对象。
try{reader = new ReliableSpoolingFileEventReader.Builder() .spoolDirectory(directory) .completedSuffix(completedSuffix) .includePattern(includePattern) .ignorePattern(ignorePattern) .trackerDirPath(trackerDirPath)...
Runnable runner = new SpoolZipDirectoryRunnable(reader, sourceCounter);executor.scheduleWithFixedDelay(runner, 0, pollDelay, TimeUnit.MILLISECONDS);
2.3、Thread--run
在线程方法run中,执行ReliableSpoolingFileEventReader对象reader的readEvents方法。批量读取reader中获取的event(在这里,一行数据组织成一个event)。
public void run() {intbackoffInterval = 250;try {while (!Thread.interrupted()) { List<Event> events = reader.readEvents(batchSize);if (events.isEmpty()) {break; }......
2.4.2、在getCandidateFiles方法中,主要利用了java.nio.files.File.walkFileTree方法,程序不断访问目录,一旦有新文件出现在该目录下,就触发执行visitFile方法,将文件加入文件列表,并返回。
public FileVisitResultvisitFile(Path candidate, BasicFileAttributesattrs) throws IOException { String fileName = candidate.getFileName().toString();if(!fileName.endsWith(ReliableSpoolingFileEventReader.this.completedSuffix) && !fileName.startsWith(".") &&ReliableSpoolingFileEventReader.this.includePattern.matcher(fileName).matches() && !ReliableSpoolingFileEventReader.this.ignorePattern.matcher(fileName).matches()) { candidateFiles.add(candidate.toFile());} return FileVisitResult.CONTINUE;}
2.5、Function--openFile
获取到当前文件(cuurentFile)之后,执行openFile方法。在openFile方法中,首先把文件作为参数,创建了ResettableFileInputStream对象in,这个对象主要保存文件的输入流以及文件读取标记。再把in和deserializerType作为参数,创建了EventDeserializer对象deserializer,deserializer根据传入的deserializerType的类型(LINE/AVRO/OTHER),将文件并行序列化为List<Event>,最终调用readEvents读取。
private Optional<ReliableSpoolingFileEventReader.FileInfo>openFile(File file) {……Preconditions.checkState(tracker.getTarget().equals(e), "Tracker target %s does not equal expected filename %s", new Object[]{tracker.getTarget(), e});ResettableFileInputStream in = new ResettableFileInputStream(file, tracker, 16384, this.inputCharset, this.decodeErrorPolicy);EventDeserializerdeserializer = EventDeserializerFactory.getInstance(this.deserializerType, this.deserializerContext, in);return Optional.of(new ReliableSpoolingFileEventReader.FileInfo(file, deserializer));……
publicenumEventDeserializerType { LINE(Builder.class), AVRO(org.apache.flume.serialization.AvroEventDeserializer.Builder.class), OTHER((Class)null);private final Class<? extends org.apache.flume.serialization.EventDeserializer.Builder>builderClass;
public class LineDeserializerimplements EventDeserializer {public Event readEvent() throws IOException {this.ensureOpen(); String line = this.readLine();return line == null?null:EventBuilder.withBody(line, this.outputCharset); }public List<Event>readEvents(intnumEvents) throws IOException {this.ensureOpen();LinkedList events = Lists.newLinkedList();for(inti = 0; i<numEvents; ++i) { Event event = this.readEvent();if(event == null) {break; }events.add(event); }return events; }
3、定制开发ZipSource代码流程图
- flume spoolDirectory Source原生代码流程及其拓展
- Flume Source
- Flume Source
- APM原生代码编译流程
- flume自定义sink source
- flume之Http Source
- 2. Flume Source 详解
- flume自定义source
- flume自定义source
- flume框架 source简介
- 自定义flume-source
- flume之kafka source
- Flume Source 实例
- 二分法及其拓展
- kmp算法及其拓展
- kmp板子及其拓展
- 欧几里得算法及其拓展
- 欧几里得算法及其拓展
- C语言的常用函数
- 本题主要考查指针与数组
- 原生servlet项目启动自动加载一个方法
- x86从实模式到保护模式学习记录之Bochsdbg
- Android Studio 简单设置
- flume spoolDirectory Source原生代码流程及其拓展
- nova 创建qcow2的kernel image的过程
- RrecyclerView自定义点击长按添加删除修改
- removeFromSuperview
- SQliteSQ语句整理及简介
- 《算法入门经典-训练指南》小记(慢慢填。)
- Tomcat JVM内存调优
- python中log日志的使用
- ubuntu下安装nginx依赖库zlib,pcre,openssl