在Flume进行实时数据的采集过程中,可能会出现宕机的情况,再重新工作时不能断点续传,导致数据丢失或数据读取重复而浪费资源。自定义Source可以解决这个问题。
1)写一个类继承AbstractSource抽象类并实现Configurable接口和EventDrivenSource接口。
2)声明自定义source中的参数:filePath(文件路径),offsetPath(存放偏移量文件的路径),interval(文件中没有新内容写入时sleep的参数),charset(字符集编码)。
3)重写Configurable的抽象方法configure,获取source中的参数值。
4)写一个synchronized修饰的start方法,创建线程池、创建实现了Runnerble的接口,将executor放入线程池中,调用其父类的start()方法。
5)写一个synchronized修饰的stop方法,调用其父类的stop()方法,在停止flume时执行一次。
6)写一个静态内部类实现Runnable接口。定义偏移量的初始值0LWie内部类的成员变量。类中是实现Runnable接口方法的构造方法,里面写断点续传逻辑:判断是否有偏移量文件(如果不存在就创建一个);如果存在的话就读取文件中是否记录了偏移量,将偏移量转为Long类型;如果记录了偏移量,就接着偏移量位置读,没有的话就从偏移量的初始值开始读。
7)重写实现Runnable接口类的run方法:定期读取文件,判断是否有新内容,如果有的话将数据封装到Event对象中,发送给Channel,获取最新偏移量值,再更新偏移量;如果日志文件中没有新的内容,就让线程sleep一下。
详细代码如下:
package flume; import org.apache.commons.io.FileUtils; import org.apache.flume.Context; import org.apache.flume.Event; import org.apache.flume.EventDrivenSource; import org.apache.flume.channel.ChannelProcessor; import org.apache.flume.conf.Configurable; import org.apache.flume.event.EventBuilder; import org.apache.flume.source.AbstractSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.charset.Charset; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 自定义source,实现多点续传 */
public class MyFileSource extends AbstractSource implements Configurable,EventDrivenSource { private static final Logger logger