flume-ng源码浅析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a040600145/article/details/76080837
1.架构


Source 负责产生数据,将数据传入channel,一旦写入channel成功,source就认为数据已经可靠的传输。

Sink    sink不停的从属于自己的channel(此处有点类似于消息队列的消费者了)中获取数据,并且将数据写入到相应的后端中,如果数据写入失败则需要将相应的状况通知channel,让channel知道数据传输失败,下次获取时可以继续获取到这些数据;

Channelflume的架构中,channel负责对数据提供可靠性保证。任何一种channelmemoryfile)都需要提供相应channeltransaction,保证实现如下几个操作:

         doBegin       事务开始;在source准备写入数据或sink准备读取数据之前调用;

         doPut                     数据写入(生产者);由channelprocessorprocessEventprocessEventBatch调用(rootcaller实际上是各种各样的source);

         doTake                  数据读出(消费者);消费端(sink)调用,然后将数据做后端存储或转发处理;

         doCommit:      数据操作(写入或读出消费)成功;

         doRollback  数据操作(写入或读出消费)失败,回滚;

         doClose       关闭事务;

主要类图如下图:

 2.初始化

 

Abstractconfigurationprovider.getconfiguration代码
  1. public MaterializedConfiguration getConfiguration() {  
  2.   MaterializedConfiguration conf = new SimpleMaterializedConfiguration();  
  3.   FlumeConfiguration fconfig = getFlumeConfiguration();  
  4.   AgentConfiguration agentConf = fconfig.getConfigurationFor(getAgentName());  
  5.   if (agentConf != null) {  
  6.     Map<String, ChannelComponent> channelComponentMap = Maps.newHashMap();  
  7.     Map<String, SourceRunner> sourceRunnerMap = Maps.newHashMap();  
  8.     Map<String, SinkRunner> sinkRunnerMap = Maps.newHashMap();  
  9.     try {  
  10.       loadChannels(agentConf, channelComponentMap);  
  11.       loadSources(agentConf, channelComponentMap, sourceRunnerMap);  
  12.       loadSinks(agentConf, channelComponentMap, sinkRunnerMap);  
  13.       Set<String> channelNames = new HashSet<String>(channelComponentMap.keySet());  
  14.       for (String channelName : channelNames) {  
  15.         ChannelComponent channelComponent = channelComponentMap.get(channelName);  
  16.         if (channelComponent.components.isEmpty()) {  
  17.           LOGGER.warn(String.format("Channel %s has no components connected" +  
  18.               " and has been removed.", channelName));  
  19.           channelComponentMap.remove(channelName);  
  20.           Map<String, Channel> nameChannelMap =  
  21.               channelCache.get(channelComponent.channel.getClass());  
  22.           if (nameChannelMap != null) {  
  23.             nameChannelMap.remove(channelName);  
  24.           }  
  25.         } else {  
  26.           LOGGER.info(String.format("Channel %s connected to %s",  
  27.               channelName, channelComponent.components.toString()));  
  28.           conf.addChannel(channelName, channelComponent.channel);  
  29.         }  
  30.       }  
  31.       for (Map.Entry<String, SourceRunner> entry : sourceRunnerMap.entrySet()) {  
  32.         conf.addSourceRunner(entry.getKey(), entry.getValue());  
  33.       }  
  34.       for (Map.Entry<String, SinkRunner> entry : sinkRunnerMap.entrySet()) {  
  35.         conf.addSinkRunner(entry.getKey(), entry.getValue());  
  36.       }  
  37.     } catch (InstantiationException ex) {  
  38.       LOGGER.error("Failed to instantiate component", ex);  
  39.     } finally {  
  40.       channelComponentMap.clear();  
  41.       sourceRunnerMap.clear();  
  42.       sinkRunnerMap.clear();  
  43.     }  
  44.   } else {  
  45.     LOGGER.warn("No configuration found for this host:{}", getAgentName());  
  46.   }  
  47.   return conf;  
  48. }  

 3.source的事务是通过

Channelprocessor.processevent代码
  1. public void processEvent(Event event) {  
  2.   
  3.   event = interceptorChain.intercept(event);  
  4.   if (event == null) {  
  5.     return;  
  6.   }  
  7.   
  8.   // Process required channels  
  9.   List<Channel> requiredChannels = selector.getRequiredChannels(event);  
  10.   for (Channel reqChannel : requiredChannels) {  
  11.     Transaction tx = reqChannel.getTransaction();  
  12.     Preconditions.checkNotNull(tx, "Transaction object must not be null");  
  13.     try {  
  14.       tx.begin();  
  15.   
  16.       reqChannel.put(event);  
  17.   
  18.       tx.commit();  
  19.     } catch (Throwable t) {  
  20.       tx.rollback();  
  21.       if (t instanceof Error) {  
  22.         LOG.error("Error while writing to required channel: " + reqChannel, t);  
  23.         throw (Error) t;  
  24.       } else if (t instanceof ChannelException) {  
  25.         throw (ChannelException) t;  
  26.       } else {  
  27.         throw new ChannelException("Unable to put event on required " +  
  28.             "channel: " + reqChannel, t);  
  29.       }  
  30.     } finally {  
  31.       if (tx != null) {  
  32.         tx.close();  
  33.       }  
  34.     }  
  35.   }  
  36.   
  37.   // Process optional channels  
  38.   List<Channel> optionalChannels = selector.getOptionalChannels(event);  
  39.   for (Channel optChannel : optionalChannels) {  
  40.     Transaction tx = null;  
  41.     try {  
  42.       tx = optChannel.getTransaction();  
  43.       tx.begin();  
  44.   
  45.       optChannel.put(event);  
  46.   
  47.       tx.commit();  
  48.     } catch (Throwable t) {  
  49.       tx.rollback();  
  50.       LOG.error("Unable to put event on optional channel: " + optChannel, t);  
  51.       if (t instanceof Error) {  
  52.         throw (Error) t;  
  53.       }  
  54.     } finally {  
  55.       if (tx != null) {  
  56.         tx.close();  
  57.       }  
  58.     }  
  59.   }  
  60. }  

 的processEventBatch或processEvent的调用实现的

4.sink事务的控制是在各自的process中实现

Loggersink代码
  1. public Status process() throws EventDeliveryException {  
  2.     Status result = Status.READY;  
  3.     Channel channel = getChannel();  
  4.     Transaction transaction = channel.getTransaction();  
  5.     Event event = null;  
  6.   
  7.     try {  
  8.       transaction.begin();  
  9.       event = channel.take();  
  10.   
  11.       if (event != null) {  
  12.         if (logger.isInfoEnabled()) {  
  13.           logger.info("Event: " + EventHelper.dumpEvent(event, maxBytesToLog));  
  14.         }  
  15.       } else {  
  16.         // No event found, request back-off semantics from the sink runner  
  17.         result = Status.BACKOFF;  
  18.       }  
  19.       transaction.commit();  
  20.     } catch (Exception ex) {  
  21.       transaction.rollback();  
  22.       throw new EventDeliveryException("Failed to log event: " + event, ex);  
  23.     } finally {  
  24.       transaction.close();  
  25.     }  
  26.   
  27.     return result;  
  28.   }  

 

猜你喜欢

转载自blog.csdn.net/a040600145/article/details/76080837