Flume LoadBalanceSinkProcessor源码阅读记录

简介

LoadBalanceSinkProcessor是flume实现负载均衡的重要方式,可有效的提高资源利用率,提升数据传输的速度。

配置参数

参数默认值描述
type-load_balance
selectorround_robinround_robin或random
backofffalse若为true,失败的Sink将加入黑名单,时间以指数增长
selector.maxTimeOut30000(ms)黑名单最大时间

配置示例

agent.sinks = s1 s2 s3 s4
agent.sinkgroups.group1.processor.type = failover
agent.sinkgroups.group1.processor.priority.s1 = 90
agent.sinkgroups.group1.processor.priority.s2 = 100
agent.sinkgroups.group1.processor.priority.s4 = 110
agent.sinkgroups.group1.processor.maxpenalty = 10000

LoadBalanceSinkProcessor初始化

  @Override
  public void configure(Context context) {
    Preconditions.checkState(getSinks().size() > 1,
        "The LoadBalancingSinkProcessor cannot be used for a single sink. "
        + "Please configure more than one sinks and try again.");
    //选初始化择器类型,默认为ROUND_ROBIN
    String selectorTypeName = context.getString(CONFIG_SELECTOR,
        SELECTOR_NAME_ROUND_ROBIN);
	//是否配置失败加入黑名单
    Boolean shouldBackOff = context.getBoolean(CONFIG_BACKOFF, false);

    selector = null;

    if (selectorTypeName.equalsIgnoreCase(SELECTOR_NAME_ROUND_ROBIN)) {
      selector = new RoundRobinSinkSelector(shouldBackOff);
    } else if (selectorTypeName.equalsIgnoreCase(SELECTOR_NAME_RANDOM)) {
      selector = new RandomOrderSinkSelector(shouldBackOff);
    } else {
      try {
        @SuppressWarnings("unchecked")
        Class<? extends SinkSelector> klass = (Class<? extends SinkSelector>)
            Class.forName(selectorTypeName);

        selector = klass.newInstance();
      } catch (Exception ex) {
        throw new FlumeException("Unable to instantiate sink selector: "
            + selectorTypeName, ex);
      }
    }
    //把配置的Sink列表加入到选择器中
    selector.setSinks(getSinks());
    selector.configure(
        new Context(context.getSubProperties(CONFIG_SELECTOR_PREFIX)));

    LOGGER.debug("Sink selector: " + selector + " initialized");
  }

选择器类型

1. RandomOrderSelector选择器

RandomOrderSelector,通过随机选择的方式,提供Sink名单。实现方法如下:

  @Override
  public synchronized Iterator<T> createIterator() {
    List<Integer> indexList = getIndexList();

    int size = indexList.size();
    int[] indexOrder = new int[size];

    while (indexList.size() != 1) {
      int pick = random.nextInt(indexList.size());
      indexOrder[indexList.size() - 1] = indexList.remove(pick);
    }

    indexOrder[0] = indexList.get(0);

    return new SpecificOrderIterator<T>(indexOrder, getObjects());
  }
2. RoundRobinOrderSelector选择器

RandomOrderSelector,通过顺序循环的方式,提供Sink名单。实现方法如下:

 @Override
  public Iterator<T> createIterator() {
    List<Integer> activeIndices = getIndexList();
    int size = activeIndices.size();
    // possible that the size has shrunk so gotta adjust nextHead for that
    if (nextHead >= size) {
      nextHead = 0;
    }
    int begin = nextHead++;
    if (nextHead == activeIndices.size()) {
      nextHead = 0;
    }

    int[] indexOrder = new int[size];

    for (int i = 0; i < size; i++) {
      indexOrder[i] = activeIndices.get((begin + i) % size);
    }

    return new SpecificOrderIterator<T>(indexOrder, getObjects());
  }

LoadBalanceSinkProcessor处理数据

 @Override
 public Status process() throws EventDeliveryException {
   Status status = null;
   //从选择器中获取Sink迭代器,此时的Sink处理顺序以由选择器做好
   Iterator<Sink> sinkIterator = selector.createSinkIterator();
   while (sinkIterator.hasNext()) {
     Sink sink = sinkIterator.next();
     try {
       //处理数据
       status = sink.process();
       break;
     } catch (Exception ex) {
       //处理失败,则提示处理器将其加入黑名单
       selector.informSinkFailed(sink);
       LOGGER.warn("Sink failed to consume event. "
           + "Attempting next sink if available.", ex);
     }
   }

   if (status == null) {
     throw new EventDeliveryException("All configured sinks have failed");
   }

   return status;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值