hadoop 中的DRF算法

DRF算法主要目的是按按照主资源进行公平分配

考虑一个有9个cpu和18GB的系统,有两个用户:用户A的每个任务都请求(1CPU,4GB)资源;用户B的每个任务都请求(3CPU,1GB)资源。如何为这种情况构建一个公平分配策略?

假设A任务分配X个实例,B任务分配Y个实例,有
X+3Y \leq 9
4X+Y \leq 18

A任务每个实例需要的cup占总资源的比例为1/9,内存占总资源的比例为4/18,4/18>1/9,所以A的主资源为内存,同理可得B的主资源为CPU,现在让A任务分配的主资源内存和B任务分配的主资源CPU 公平,则由:
\frac {4X} {18}=\frac {3Y} 9

通过三个方程,解得X=3,Y=2
即A类任务可以启动3个 ,占用资源为(3,12)
B类任务可以启动2个,占用资源为(6,2)

hadoop对DRF的应用

hadoop 2.7 中使用DominantResourceCalculator实现了cup、memory这两种主资源的公平调度
代码如下

  /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
  * regarding copyright ownership.  The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  package org.apache.hadoop.yarn.util.resource;
  
  import org.apache.hadoop.classification.InterfaceAudience.Private;
  import org.apache.hadoop.classification.InterfaceStability.Unstable;
  import org.apache.hadoop.yarn.api.records.Resource;
  
  /**
   * A {@link ResourceCalculator} which uses the concept of  
   * <em>dominant resource</em> to compare multi-dimensional resources.
   *
   * Essentially the idea is that the in a multi-resource environment, 
   * the resource allocation should be determined by the dominant share 
   * of an entity (user or queue), which is the maximum share that the 
   * entity has been allocated of any resource. 
   * 
   * In a nutshell, it seeks to maximize the minimum dominant share across 
   * all entities. 
   * 
   * For example, if user A runs CPU-heavy tasks and user B runs
   * memory-heavy tasks, it attempts to equalize CPU share of user A 
   * with Memory-share of user B. 
   * 
   * In the single resource case, it reduces to max-min fairness for that resource.
   * 
   * See the Dominant Resource Fairness paper for more details:
   * www.cs.berkeley.edu/~matei/papers/2011/nsdi_drf.pdf
   */
  @Private
  @Unstable
  public class DominantResourceCalculator extends ResourceCalculator {
    
    @Override
    public int compare(Resource clusterResource, Resource lhs, Resource rhs) {
      
      if (lhs.equals(rhs)) {
        return 0;
      }
      
      if (isInvalidDivisor(clusterResource)) {
        //除数为0,cup和memory一大一小
        if ((lhs.getMemory() < rhs.getMemory() && lhs.getVirtualCores() > rhs
            .getVirtualCores())
            || (lhs.getMemory() > rhs.getMemory() && lhs.getVirtualCores() < rhs
                .getVirtualCores())) {
          return 0;
        } else if (lhs.getMemory() > rhs.getMemory()
            || lhs.getVirtualCores() > rhs.getVirtualCores()) {
          return 1;
        } else if (lhs.getMemory() < rhs.getMemory()
            || lhs.getVirtualCores() < rhs.getVirtualCores()) {
          return -1;
        }
      }
      //比较主资源
      float l = getResourceAsValue(clusterResource, lhs, true);
      float r = getResourceAsValue(clusterResource, rhs, true);
      
      if (l < r) {
        return -1;
      } else if (l > r) {
        return 1;
      } else {
        //主资源相等,比较副资源占比
        l = getResourceAsValue(clusterResource, lhs, false);
        r = getResourceAsValue(clusterResource, rhs, false);
        if (l < r) {
          return -1;
        } else if (l > r) {
          return 1;
        }
      }
      
      return 0;
    }
  
    /**
     * Use 'dominant' for now since we only have 2 resources - gives us a slight
     * performance boost.
     * 
     * Once we add more resources, we'll need a more complicated (and slightly
     * less performant algorithm).
     */
    protected float getResourceAsValue(
        Resource clusterResource, Resource resource, boolean dominant) {
      // Just use 'dominant' resource
      return (dominant) ?
          Math.max(
              (float)resource.getMemory() / clusterResource.getMemory(), 
              (float)resource.getVirtualCores() / clusterResource.getVirtualCores()
              ) 
          :
            Math.min(
                (float)resource.getMemory() / clusterResource.getMemory(), 
                (float)resource.getVirtualCores() / clusterResource.getVirtualCores()
                ); 
    }
    
    @Override
    public int computeAvailableContainers(Resource available, Resource required) {
      return Math.min(
          available.getMemory() / required.getMemory(), 
          available.getVirtualCores() / required.getVirtualCores());
    }
  
    @Override
    public float divide(Resource clusterResource, 
        Resource numerator, Resource denominator) {
      return 
          getResourceAsValue(clusterResource, numerator, true) / 
          getResourceAsValue(clusterResource, denominator, true);
    }
    
    @Override
    public boolean isInvalidDivisor(Resource r) {
      if (r.getMemory() == 0.0f || r.getVirtualCores() == 0.0f) {
        return true;
      }
      return false;
    }
  
    @Override
    public float ratio(Resource a, Resource b) {
      return Math.max(
          (float)a.getMemory()/b.getMemory(), 
          (float)a.getVirtualCores()/b.getVirtualCores()
          );
    }
  
    @Override
    public Resource divideAndCeil(Resource numerator, int denominator) {
      return Resources.createResource(
          divideAndCeil(numerator.getMemory(), denominator),
          divideAndCeil(numerator.getVirtualCores(), denominator)
          );
    }
  
    @Override
    public Resource normalize(Resource r, Resource minimumResource,
                              Resource maximumResource, Resource stepFactor) {
      int normalizedMemory = Math.min(
        roundUp(
          Math.max(r.getMemory(), minimumResource.getMemory()),
          stepFactor.getMemory()),
        maximumResource.getMemory());
      int normalizedCores = Math.min(
        roundUp(
          Math.max(r.getVirtualCores(), minimumResource.getVirtualCores()),
          stepFactor.getVirtualCores()),
        maximumResource.getVirtualCores());
      return Resources.createResource(normalizedMemory,
        normalizedCores);
    }
  
    @Override
    public Resource roundUp(Resource r, Resource stepFactor) {
      return Resources.createResource(
          roundUp(r.getMemory(), stepFactor.getMemory()), 
          roundUp(r.getVirtualCores(), stepFactor.getVirtualCores())
          );
    }
  
    @Override
    public Resource roundDown(Resource r, Resource stepFactor) {
      return Resources.createResource(
          roundDown(r.getMemory(), stepFactor.getMemory()),
          roundDown(r.getVirtualCores(), stepFactor.getVirtualCores())
          );
    }
  
    @Override
    public Resource multiplyAndNormalizeUp(Resource r, double by,
        Resource stepFactor) {
      return Resources.createResource(
          roundUp(
              (int)Math.ceil(r.getMemory() * by), stepFactor.getMemory()),
          roundUp(
              (int)Math.ceil(r.getVirtualCores() * by), 
              stepFactor.getVirtualCores())
          );
    }
  
    @Override
    public Resource multiplyAndNormalizeDown(Resource r, double by,
        Resource stepFactor) {
      return Resources.createResource(
          roundDown(
              (int)(r.getMemory() * by), 
              stepFactor.getMemory()
              ),
          roundDown(
              (int)(r.getVirtualCores() * by), 
              stepFactor.getVirtualCores()
              )
          );
    }
  
  }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容