dremio RuleBasedEngineSelector 简单介绍

dremio 提供了一个空的默认RuleBasedEngineSelector 实现,主要实现基于规则的引擎选择

接口定义以及默认空实现

public interface RuleBasedEngineSelector {
 
  public String resolveAndUpdateEngine(ResourceSchedulingContext queryContext);
 
  /**
   * NO_OP implementation
   */
  public static final RuleBasedEngineSelector NO_OP = new RuleBasedEngineSelector() {
 
    @Override
    public String resolveAndUpdateEngine(ResourceSchedulingContext queryContext) {
      // 返回为空,不做操作
      return null;
    }
  };
 
}

使用此服务的地方

SabotNode(测试了不包含ui 的执行框架),ForemenWorkManager(foreman 管理的),AttemptManager(管理所有fragement)
主要使用的还是SabotNode 以及AttemptManager
AttemptManager 对于RuleBasedEngineSelector使用的处理(主要是将查询的规则附加到)

 
String ruleSetEngine = ruleBasedEngineSelector.resolveAndUpdateEngine(queryContext);
ResourceSchedulingProperties resourceSchedulingProperties = new ResourceSchedulingProperties();
resourceSchedulingProperties.setRoutingEngine(queryContext.getSession().getRoutingEngine());
resourceSchedulingProperties.setRuleSetEngine(ruleSetEngine);
final GroupResourceInformation groupResourceInformation =
  maestroService.getGroupResourceInformation(queryContext.getOptions(), resourceSchedulingProperties);
queryContext.setGroupResourceInformation(groupResourceInformation);
 
 

对于具体的使用是由BasicResourceAllocator进行具体的资源分配处理,但是很不好的是官方的实现没有直接使用此功能
反而使用的是基于队列的处理
参考代码

 
public ResourceSchedulingResult allocate(final ResourceSchedulingContext queryContext,
                                           final ResourceSchedulingProperties resourceSchedulingProperties,
                                           final ResourceSchedulingObserver resourceSchedulingObserver,
                                           final Consumer<ResourceSchedulingDecisionInfo> schedulingDecisionInfoConsumer) {
 
    final ResourceSchedulingDecisionInfo resourceSchedulingDecisionInfo = new ResourceSchedulingDecisionInfo();
    final QueueType queueType = getQueueNameFromSchedulingProperties(queryContext, resourceSchedulingProperties);
    resourceSchedulingDecisionInfo.setQueueName(queueType.name());
    resourceSchedulingDecisionInfo.setQueueId(queueType.name());
    resourceSchedulingDecisionInfo.setWorkloadClass(queryContext.getQueryContextInfo().getPriority().getWorkloadClass());
    schedulingDecisionInfoConsumer.accept(resourceSchedulingDecisionInfo);
 
    resourceSchedulingObserver.beginQueueWait();
    final Pointer<DistributedSemaphore.DistributedLease> lease = new Pointer();
    ListenableFuture<ResourceSet> futureAllocation = executorService.submit(() -> {
      lease.value = acquireQuerySemaphoreIfNecessary(queryContext, queueType);
 
       // update query limit based on the queueType
      final OptionManager options = queryContext.getOptions();
      // 此处基于了队列进行资源控制,但是没有利用上边的默认RuleBasedEngineSelector
      final boolean memoryControlEnabled = options.getOption(BasicResourceConstants.ENABLE_QUEUE_MEMORY_LIMIT);
      // TODO REFLECTION_SMALL, REFLECTION_LARGE was not there before - was it a bug???
      final long memoryLimit = (queueType == QueueType.SMALL || queueType == QueueType.REFLECTION_SMALL) ?
        options.getOption(BasicResourceConstants.SMALL_QUEUE_MEMORY_LIMIT):
        options.getOption(BasicResourceConstants.LARGE_QUEUE_MEMORY_LIMIT);
      long queryMaxAllocation = queryContext.getQueryContextInfo().getQueryMaxAllocation();
      if (memoryControlEnabled && memoryLimit > 0) {
        queryMaxAllocation = Math.min(memoryLimit, queryMaxAllocation);
      }
      final UserBitShared.QueryId queryId = queryContext.getQueryId();
      final long queryMaxAllocationFinal = queryMaxAllocation;
 
      final ResourceSet resourceSet = new BasicResourceSet(
        queryId,
        lease.value,
        queryMaxAllocationFinal,
        queueType.name());
 
      return resourceSet;
    });
    Futures.addCallback(futureAllocation, new FutureCallback<ResourceSet>() {
      @Override
      public void onSuccess(@Nullable ResourceSet resourceSet) {
        // don't need to do anything additional
      }
 
      @Override
      public void onFailure(Throwable throwable) {
        // need to close lease
        releaseLease(lease.value);
      }
    }, executorService);
 
    final ResourceSchedulingResult resourceSchedulingResult = new ResourceSchedulingResult(
      resourceSchedulingDecisionInfo,
      futureAllocation
    );
    return resourceSchedulingResult;
  }

说明

RuleBasedEngineSelector 功能设计上主要是一个接口定义,对于资源分配需要依赖的可以直接使用,但是目前开源版本的比较弱

参考资料

https://docs.dremio.com/software/advanced-administration/jobs/

posted on 2022-03-11 21:34  荣锋亮  阅读(46)  评论(0编辑  收藏  举报

导航