最近做了一个基于flume 1.7 的sink,用于写hdfs orc文件,中间遇到了几个坑,下面把思路和遇到的问题一一记录下来。
1. 开发思路
首先的实现场景是这样的:从channel拿数据-->sink拿到数据后做分类-->分类后将数据写入对应的orc文件->文件关闭。技术要点是这样:
1.1 线程池管理hdfs操作
在分类写orc文件这环节,我开了两个线程池,一个用来管理每类文件的hdfs操作,创建/写入/关闭hdfs上的orc文件;一个用来管理文件的滚动,在某一个时机,例如文件写入条数到达某个上限或者文件闲置到达一定时间,将当前文件关闭并创造新文件。
这个是hdfs操作线程池的代码逻辑:
//创建一个线程池,线程执行对象
callTimeoutPool = Executors.newFixedThreadPool(threadsPoolSize,
new ThreadFactoryBuilder().setNameFormat(timeoutName).build());
//callTimeoutPool执行线程任务,任务继承于callable,执行后返回Future对象
private <T> T callWithTimeout(final CallRunner<T> callRunner)
throws IOException, InterruptedException {
Future<T> future = callTimeoutPool.submit(new Callable<T>() {
...
}
}
//任务内