为了账号安全,请及时绑定邮箱和手机立即绑定

Flume 实现自己的实时日志(2)

标签:
Java 大数据

目录解读

最近接触到Flume,这里通过一些小案例做一些学习的分享。主要包括以下内容:
1-概念、2-源码编译、3-快速入门:https://www.imooc.com/article/278218
4-源码解读
5-TAILDIR监听日志文件,源码修改,新增系统名称
6-TAILDIR监听日志文件到HDFS的案例
7-TAILDIR监听日志文件到Kafka的案例
8-TAILDIR监听日志文件到ES6.X版本的案例(包括自己实现ES高版本的Sink)
注:本系列所有文章基于Flume 1.7.0
所有分析和注释代码都在:https://github.com/lizu18xz/flume-release-1.7.0

源码解读

通过概念和快速的入门,大体对flume进行了了解。下面让我们一起看一下flume的源码,
方便我们后续的使用。
(1)flume-ng-node
在这个模块下面找到org.apache.flume.node.Application入口类。就可以看到启动
的main函数:

***对我们启动命令的参数进行解析***
CommandLineParser parser = new GnuParser();
CommandLine commandLine = parser.parse(options, args);

***根据命令获取到我们的配置文件***
logger.info("flume加载的配置文件名称:"+commandLine.getOptionValue('f'));
File configurationFile = new File(commandLine.getOptionValue('f'));

***获取配置信息,启动source,channel,sink组件***
if (reload) {
          logger.info("启动PollingPropertiesFileConfigurationProvider进行轮训检查配置文件是否修改!!!!!!");
          EventBus eventBus = new EventBus(agentName + "-event-bus");
          PollingPropertiesFileConfigurationProvider configurationProvider =
          new PollingPropertiesFileConfigurationProvider(
                  agentName, configurationFile, eventBus, 30);
          components.add(configurationProvider);
          application = new Application(components);
          eventBus.register(application);
        } else {
          PropertiesFileConfigurationProvider configurationProvider =
              new PropertiesFileConfigurationProvider(agentName, configurationFile);
          application = new Application();
          application.handleConfigurationEvent(configurationProvider.getConfiguration());
        }

***reload这种情况***
可以看到会初始化一个PollingPropertiesFileConfigurationProvider类,这个类的作用
就是当调用 application.start() 的时候 会启动一个定时的任务检查配置文件是否修改

executorService = Executors.newSingleThreadScheduledExecutor(
            new ThreadFactoryBuilder().setNameFormat("conf-file-poller-%d")
                .build());

    FileWatcherRunnable fileWatcherRunnable =
        new FileWatcherRunnable(file, counterGroup);

    executorService.scheduleWithFixedDelay(fileWatcherRunnable, 0, interval,
        TimeUnit.SECONDS);
        
可以看到FileWatcherRunnable里面的具体实现:
 public void run() {
      LOGGER.debug("Checking file:{} for changes", file);

      counterGroup.incrementAndGet("file.checks");

      long lastModified = file.lastModified();

      if (lastModified > lastChange) {
        LOGGER.info("Reloading configuration file:{}", file);

        counterGroup.incrementAndGet("file.loads");

        lastChange = lastModified;

        try {
          eventBus.post(getConfiguration());//会调用回调函数handleConfigurationEvent
        } catch (Exception e) {
           ...
        } catch (NoClassDefFoundError e) {
           ...
        } catch (Throwable t) {
           ...
        }
      }
    }

***eventBus.post(getConfiguration())***
getConfiguration()非常重要
它会解析我们的配置文件,获取我们配置的具体实现类
 loadChannels(agentConf, channelComponentMap);
 loadSources(agentConf, channelComponentMap, sourceRunnerMap);
 loadSinks(agentConf, channelComponentMap, sinkRunnerMap);
 
 比如loadChannels:
 Channel channel = getOrCreateChannel(channelsNotReused,
            comp.getComponentName(), comp.getType());
 在ChannelType里面定义了所支持的Channel类型和具体的实现类		
 MEMORY("org.apache.flume.channel.MemoryChannel")
 FILE("org.apache.flume.channel.file.FileChannel")
 
 同理loadSources也差不多具体实现跨越深入此方法
 Source source = sourceFactory.create(comp.getComponentName(),
            comp.getType());
 SourceType里面会定义支持的Source类型
 TAILDIR("org.apache.flume.source.taildir.TaildirSource")
 AVRO("org.apache.flume.source.AvroSource")
 
 最后看一下loadSinks会发现也一样
 //获取具体的sink实现
 Sink sink = sinkFactory.create(comp.getComponentName(), comp.getType());
 SinkType里面会定义自带的Sink
 HBASE("org.apache.flume.sink.hbase.HBaseSink")
 HIVE("org.apache.flume.sink.hive.HiveSink")
 注意在获取sink class过程当中
 if (!sinkType.equals(SinkType.OTHER)) {
      sinkClassName = sinkType.getSinkClassName();
 }
 如果没有在SinkType里面配置则需要配置全类名,比如kafka需要配置:
 org.apache.flume.sink.kafka.KafkaSink
 
*** SourceRunner和SinkRunner ***
 SourceRunner和SinkRunner是对我们具体配置source和sink的包装,并且会调用
 具体的方法,比如start,process,stop.(非常重要的两个类,自己查看完整代码)

 sourceRunnerMap.put(comp.getComponentName(),
              SourceRunner.forSource(source));
 source会被包装在SourceRunner里面
 如果实现PollableSource则会初始化PollableSourceRunner,比如TaildirSource
 就是实现   PollableSource
 因此真正启动的时候会执行PollableSourceRunner里面的start方法,
 通过 PollableSourceRunner 然后调用真正source的方法。
 
 sinkRunnerMap.put(comp.getComponentName(),
              new SinkRunner(group.getProcessor()));
 类似SourceRunner,Sink的流程主要在SinkRunner里面控制
 SinkRunner
 runner = new PollingRunner();会执行runner线程的run方法             

***handleConfigurationEvent回调函数***
这个方法会启动我们配置的组件
  @Subscribe
  public synchronized void handleConfigurationEvent(MaterializedConfiguration conf) {
    stopAllComponents();
    startAllComponents(conf);
  }

startAllComponents(conf);//启动组件,按下面的顺序
Starting Channel...
Starting Sink...
Starting Source...
组件的启动都是调用了supervisor.supervise
supervisor.supervise(entry.getValue(),
            new SupervisorPolicy.AlwaysRestartPolicy(), LifecycleState.START);
具体启动的地方在MonitorRunnable监控线程里面
     try {
                  logger.info("启动组件start...... : "+lifecycleAware.getClass().getSimpleName());
                  lifecycleAware.start();
                } catch (Throwable e) {
          }
source和sink实际上是会启动SourceRunner和SinkRunner
LifecycleAware是一个顶级接口,定义了组件的开始,结束以及当前状态,flume中重要组件如source,sink,channel都实现了这个接口

***KafkaSink流程***
通过KafkaSink具体代码实现来看上面的分析
在loadSinks的时候执行configure方法会根据配置设置kafka的配置参数
在startAllComponents里面会启动SourceRunner和SinkRunner
SinkRunner会调用KafkaSink的start方法初始化kafkaProducer
然后执行KafkaSink的process开始从channel中获取数据。

未完待续

5-TAILDIR监听日志文件,源码修改,新增系统名称
6-TAILDIR监听日志文件到HDFS的案例
7-TAILDIR监听日志文件到Kafka的案例
8-TAILDIR监听日志文件到ES6.X版本的案例(包括自己实现ES高版本的Sink)

代码地址

https://github.com/lizu18xz/flume-release-1.7.0
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
6396
获赞与收藏
157

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消