HDFS RBF的资源隔离设计

文章目录

  • 前言
  • RBF的资源隔离和FCQ的资源隔离
  • RBF的fairness管控原理
  • 引用

前言


Hadoop社区在HDFS-10467中实现了基于路由的federation功能,此功能比原先传统的HDFS federation+viewfs的方式有了很大的改进,真正做到了基于后端的路由映射,而不是viewfs在客户端做地址解析转发。基于后端来做的话,背后的mount映射管理权就归到了系统管理员身上了。更重要的一点,当想要更换mount信息时,无需向所有客户端推送更新的mapping文件,而是通过简单的管理员命令操作RBF mount table信息即可。形象地比喻,RBF中的Router是架在下游NN和面向Client的一个中间角色。在这套模式下,Router就成了一个关键角色,它的响应快慢将影响到所有Client的请求访问。但这里的Router并不是足够稳定的,比如下游NN响应变慢,进而会反压到Router(Router共用了一个thread pool做调用执行的)。这样其它正常NN的请求就会被block住,于是这里就会有潜在的资源隔离的问题。本文笔者来简单聊聊社区目前对此的一个方案设计,主要原理是通过在Router Client层面对其做fairness的管控,和目前Hadoop的Fair Callqueue还是不太一样的。

RBF的资源隔离和FCQ的资源隔离


当我们经常在说资源isolation的时候,我们免不了会提到fairness的问题。因为没有做到很好的isolation,fairness无法得到保证,而FCQ(Fair Callqueue)就做了这样一个事情。但是注意的是,这里的fairness指的不是绝对意义上的公平,只能说是相对公平,一种按照我们给定的某种程度的公平。

但是FCQ和RBF的资源隔离的问题类型还是有所不同的。FCQ面向的是单一集群内的用户间的影响问题,而RBF里,这个所谓的“用户”则变成了各个cluster的NN。还有在FCQ中,我们可以拿到用户请求的详细信息,而在RBF里,我们只能拿到最基本的NN的信息。

下面我们来了解一下FCQ的原理模型图:

HDFS RBF的资源隔离设计_第1张图片
目前FCQ的fairness策略已经是比较智能化了,包括有根据请求频率定义优先级,然后根据优先级定义权重,最后进行加权轮询调度处理。在每次的iteration内,每类请求能够保证被得到处理。

相对于FCQ面向用户层面比较细粒度的控制,RBF的fairness管控在初期实现只要做到对每个cluster的请求permit控制即可。比方说,在单位时间内,我允许Router向A cluster分派6个请求,而B cluster只允许处理4个请求。通过限制允许请求数来避免下游NN overload导致Router处理变慢的情况。

以下是一个RBF fairness的预想效果图,

HDFS RBF的资源隔离设计_第2张图片

通过RBF fairness manager的介入,handler在逻辑层面被按比例地划分给不同的namespace,注意笔者在这里指的是逻辑层面,不是真的RBF修改了NN Server里的handler处理。

RBF的fairness管控原理


下面笔者来简单聊聊RBF的fairness管控原理。Fairness管控是在Router这个服务里做的,更具体地来说是在Router Client层面做的,这里的Router Client可理解为是Router请求转向实际NN的一个Proxy。

在社区的实现方案中,引入了FairManager的对象,FairManager里包含了fairness的控制策略。目前的一个默认策略是通过为每个namespace设置一个信号量对象Semaphore,来进行请求的限制,相关代码如下:

+  /** Hash table to hold semaphore for each configured name service. */
+  private Map<String, Semaphore> permits;

初始化的时候,通过读取配置中为每个ns指定的permit数,进行Semaphore的设定。

  @Override
  public void assignHandlersToNameservices(Configuration conf) {
  ...
 for (String namenode : namenodes) {
      String[] namenodeSplit = namenode.split("\\.");
      String nsId = null;
      if (namenodeSplit.length == 2) {
        nsId = namenodeSplit[0];
      } else if (namenodeSplit.length == 1) {
        nsId = namenode;
      } else {
        String errorMsg = "Wrong name service specified :" +
            Arrays.toString(namenodeSplit);
        LOG.error(errorMsg);
        throw new PermitAllocationException(
            errorMsg);
      }
      if (nsId != null) {
        int dedicatedHandlers =
            conf.getInt(DFS_ROUTER_FAIR_HANDLER_COUNT_KEY_PREFIX + nsId, 0);
        LOG.info("Dedicated handlers {} for ns {} ", dedicatedHandlers, nsId);
        if (dedicatedHandlers > 0) {
          if (!this.permits.containsKey(nsId)) {
            handlerCount -= dedicatedHandlers;
            // Total handlers should not be less than sum of dedicated
            // handlers.
            validateCount(handlerCount, 0);
            this.permits.put(nsId, new Semaphore(dedicatedHandlers));
            logAssignment(nsId, dedicatedHandlers);
          }
        } else {
          unassignedNS.add(nsId);
        }
      }
 }

当客户端请求调用时,fairness policy会在对应的ns的Semaphore中进行permit的acquire操作,如果获取不到意为当时针对此ns的请求资源未被完全释放,抛Exception异常。这个行为就做到完美想要的资源控制的效果,简接达到Router内的isolation的目的。

@Override
  public void acquirePermit(String nsId) throws NoPermitAvailableException {
    if (!this.permits.get(nsId).tryAcquire()) {
      throw new NoPermitAvailableException(nsId);
    }
  }

  @Override
  public void releasePermit(String nsId) {
    this.permits.get(nsId).release();
  }

请求调用完成后,调用releasePermit方法。一个Sample call如下:

public Object invokeSingle(final String nsId, RemoteMethod method)
     UserGroupInformation ugi = RouterRpcServer.getRemoteUser();
     List<? extends FederationNamenodeContext> nns =
         getNamenodesForNameservice(nsId);
    acquirePermit(nsId, ugi, method.getMethod());
    try {
      RemoteLocationContext loc = new RemoteLocation(nsId, "/", "/");
      Class<?> proto = method.getProtocol();
      Method m = method.getMethod();
      Object[] params = method.getParams(loc);
      return invokeMethod(ugi, nns, proto, m, params);
    } finally {
      releasePermit(nsId, ugi, method.getMethod());
    }
}

RBF的fairness管控原理流程图如下所示:

HDFS RBF的资源隔离设计_第3张图片

当然目前RBF初期fairness的控制策略相比于FCQ来说,它主要通过的预先定义配置的方式做的控制,缺乏了些灵活性。后续的改进可以从动态调整permit值这个方向做改进,并实现新的policy。

引用


[1].https://issues.apache.org/jira/browse/HDFS-14090 . RBF: Improved isolation for downstream name nodes

你可能感兴趣的:(Hadoop,HDFS)