Yarn SLS(Scheduler Load Simulator)模擬調度器


一、調度壓力模擬器介紹

最近在調研Yarn調度性能問題,考慮到線上集群規模已達到5k+台,在線上環境實驗是不太可行的,因此必須在線上有一套環境來驗證調度器的性能,才能把有效的優化策略推廣到線上環境。在線下環境搭建一套和線上規模相同的集群是不太合理的,需要耗費大量物理資源,成本耗費非常高。因此,需要有一個調度器的壓力模擬器,在不需要大量物理機資源的條件下,能夠模擬Yarn的調度過程。

Hadoop社區提供了開源調度器的壓力模擬工具——Scheduler Load Simulator。

yarn調度壓力模擬器

此圖是基於美團對架構改造后的方案圖,左側是開源SLS的架構圖,整個服務都在一個進程中,ResourceManager模塊有一個用線程模擬的Scheduler,APPlication(APP)和NodeManager(NM)都是由線程模擬,作業資源申請和NM節點心跳都是采用方法調用。美團考慮到開源架構的性能問題,對架構進行了改造,從SLS中剝離Scheduler Wapper的模擬邏輯,用真實的ResourceManager代替,SLS僅模擬作業的資源申請和節點的心跳匯報。改造代碼參考: YARN-7672
 
在對Yarn調度壓力進行調研時,我們也是基於美團點評改造的方案,但SLS環境的使用基本是一致的,下面先對SLS展開介紹。

二、SLS使用

2.1 SLS介紹

SLS的功能實現主要在 /share/hadoop/tools/sls/ 中,SLS文件夾包括四個文件夾:bin,html,sample-conf,sample-data。

  • bin: 包含了sls的運行腳本,也就是啟動命令
  • html:包含html、css、js文件,來實現實時追蹤和web顯示。
  • sample-conf:sls的配置文件
  • sample-data:提供了一個rumen trace的示例文件,可以用來作為sls的輸入。

2.2 SLS參數

SLS默認參數在 /share/hadoop/tools/sls/sample-conf/sls-runner.xml 文件中。主要包括:任務提交參數、NM相關參數、APP相關參數、Container分配參數及運行指標參數(運行指標參數不單獨介紹,用真實RM的健康指標即可)。

任務並發提交與任務並行運行相關參數:

yarn.sls.runner.pool.nm.size
模擬NodeManager的執行線程數量,越大執行效率越高,對RM的壓力也越大。
 
yarn.sls.runner.pool.am.size
模擬ApplicationMaster的執行線程數量。
 
yarn.sls.am.parallel.max-num
在YARN上並行運行的最大App數量。
 
yarn.sls.nm.heartbeat.interval.ms
NodeManager心跳間隔時間,控制NodeManager向ResourceManager的心跳周期。
 
yarn.sls.am.submit.interval.ms
yarn.sls.am.submit.interval.count
此兩個參數控制作業提交速度。當前值分別為每10秒鍾提交100個作業。相當於每秒10個。
 
模擬資源相關參數:
yarn.sls.nm.memory.mb
yarn.sls.nm.vcores
每個NM節點模擬多少資源(內存與核心)。所有NM都是同樣的資源數。
 
yarn.sls.container.memory.mb
yarn.sls.container.vcores
每個container申請多少資源(內存與核心)。所有container都是同樣的資源數。

2.3 SLS環境運行

SLS支持兩種類型的input files:rumen traces和sls traces。slsrun.sh腳本負責運行sls。
$ cd opt/cloudera/parcels/CDH/share/hadoop/tools/sls/
$ bin/slsrun.sh
    --input-rumen|--input-sls=<TRACE_FILE1,TRACE_FILE2,...>
    --output-dir=<SLS_SIMULATION_OUTPUT_DIRECTORY> [--nodes=<SLS_NODES_FILE>]
    [--track-jobs=<JOBID1,JOBID2,...>] [--print-simulation]

參數介紹: 

--input-rumen: 輸入是rumen trace文件,示例為/share/hadoop/tools/sls/sample-data/2jobs2min-rumen-jh.json.

--input-sls: 輸入是sls自己的格式文件,sls file。sls提供了一個工具來將rumen traces文件轉換為sls trace:rumen2sls.sh(/share/hadoop/tools/sls/bin/)。

--output-dir: 輸出監控數據和日志的目錄

--nodes: 集群的拓撲結構,默認情況下,sls采用input json file中的拓撲,用戶也可以指定一個新的拓撲結構。

--track-jobs: 在模擬器運行過程中跟蹤的特定任務,由逗號分隔。

--print-simulation: 該參數決定了是否在模擬器運行前打印仿真信息,包括每個應用程序的節點、應用程序、任務和信息的數量。如果需要,只需要添加上該參數即可。

 
運行案例:sls-jobs.json為input-sls文件輸入類型,sls-nodes.json是模擬的NM節點信息(運行rumen2sls.sh 腳本轉換 rumen traces 生成)。
$ cd opt/cloudera/parcels/CDH/share/hadoop/tools/sls/
// sls traces輸入
$ bin/slsrun.sh --input-sls=/root/cdh/sls/sls-jobs.json --nodes=/root/cdh/sls/sls-nodes.json --output-dir=/root/cdh/sls/output1 --print-simulation
// rumen traces輸入
$ bin/slsrun.sh  --input-rumen=/opt/cloudera/parcels/CDH/share/hadoop/tools/sls/sample-data/2jobs2min-rumen-jh.json --nodes=/root/cdh/sls/sls-nodes.json --output-dir=/root/cdh/sls/output2

為了兼容 rumen traces 文件類型的輸入,社區提供了一個腳本支持 rumen traces 轉換為 sls traces,使用方式如下:

$ cd opt/cloudera/parcels/CDH/share/hadoop/tools/sls/
$ bin/rumen2sls.sh
    --rumen-file=<RUMEN_FILE>
    --output-dir=<SLS_OUTPUT_DIRECTORY>
    [--output-prefix=<SLS_FILE_PREFIX>]

運行案例:

$ bin/rumen2sls.sh --rumen-file=/opt/cloudera/parcels/CDH/share/hadoop/tools/sls/sample-data/2jobs2min-rumen-jh.json  --output-dir=/root/cdh/sls/

 運行sls環境過程中踩過的坑:https://www.cnblogs.com/walker-/p/13331255.html

三、大規模集群環境模擬

在真實的線上環境,APP數量和NM數量都是大規模量級的,因此我們需要自定義APP任務請求及NM節點規模,trace.big.json 是我們從線上環境導出的job信息,有6w+ jobs,nodes_10000.json 是人工構造的10k台NM節點信息。運行方式如下:
$ cd opt/cloudera/parcels/CDH/share/hadoop/tools/sls/
$ bin/slsrunForRealRM.sh  --input-rumen=/data/kwang/rumentrace/trace.big.json --nodes=/data1/kwang/nodes/nodes_10000.json  --output-dir=/data1/kwang/rumentrace/output2

3.1 如何生成大量jobs文件?

Hadoop社區提供了一個針對MR任務設計的日志分析工具Hadoop Rumen,SLS里可以用這個工具解析MR jobhistory server的日志,來生成模擬提交任務的數據。Hadoop Rumen的組件TraceBuilder(軌跡生成器)可以將MR歷史日志轉換成易解析的json格式文件。使用方式如下:
hadoop jar \
/opt/cloudera/parcels/CDH/share/hadoop/tools/lib/hadoop-rumen-2.6.0-cdh5.14.4.jar \
org.apache.hadoop.tools.rumen.TraceBuilder \
-recursive \
file:///var/lib/hadoop-hdfs/rumentrace/job-trace.json \ # 輸出trace文件
file:///var/lib/hadoop-hdfs/rumentrace/job-topology.json \ # 輸出NM的拓撲文件
hdfs://nameservice/user/history/logs/  # mr歷史作業日志

3.2 如何構造10k規模NM節點?

NM節點主要是主機名和ip,10k節點信息我們通過一段java代碼生成的。代碼如下:
import java.util.Random;

public class RandomIp {

    public static String getRandomIp() {

        // ip范圍
        int[][] range = {
                        {607649792, 608174079}, // 36.56.0.0-36.63.255.255
                        {1038614528, 1039007743}, // 61.232.0.0-61.237.255.255
                        {1783627776, 1784676351}, // 106.80.0.0-106.95.255.255
                        {2035023872, 2035154943}, // 121.76.0.0-121.77.255.255
                        {2078801920, 2079064063}, // 123.232.0.0-123.235.255.255
                        {-1950089216, -1948778497}, // 139.196.0.0-139.215.255.255
                        {-1425539072, -1425014785}, // 171.8.0.0-171.15.255.255
                        {-1236271104, -1235419137}, // 182.80.0.0-182.92.255.255
                        {-770113536, -768606209}, // 210.25.0.0-210.47.255.255
                        {-569376768, -564133889}, // 222.16.0.0-222.95.255.255
        };

        Random random = new Random();
        int index = random.nextInt(10);
        String ip = num2ip(range[index][0] + new Random().nextInt(range[index][1] - range[index][0]));
        return ip;
    }

    /*
     * 將十進制轉換成IP地址
     */
    public static String num2ip(int ip) {
        int[] b = new int[4];
        String ipStr = "";
        b[0] = (int) ((ip >> 24) & 0xff);
        b[1] = (int) ((ip >> 16) & 0xff);
        b[2] = (int) ((ip >> 8) & 0xff);
        b[3] = (int) (ip & 0xff);
        ipStr = Integer.toString(b[0]) + "." + Integer.toString(b[1]) + "." + Integer.toString(b[2]) + "." + Integer.toString(b[3]);
        return ipStr;
    }

    public static void main(String[] args) {
        int count = 100;
        for (int i = 0; i < count; i++) {
            String randomIp = getRandomIp();
            System.out.println(randomIp);
        }
    }
}
View Code

注意:在將10k節點NM信息向RM注冊時,需要在RM端允許未知host和ip信息向RM注冊,避免被RM拒絕。

在yarn-site.xml的ResourceManager高級配置中添加如下配置,並允許所有未知節點向RM注冊。之所以添加這個配置,是由於我們Hadoop集群是用Cloudera Manager維護的,如果不指定配置,Cloudera Manager則只允許維護的NM節點向RM注冊,這個配置主要是設置RM的白名單,允許所有節點注冊。
<property>
    <name>yarn.resourcemanager.nodes.include-path</name>
    <value>/etc/hadoop/myconf/nodes_allow.txt</value>
</property>

在active RM節點設置node白名單限制,允許所有節點向RM注冊。

$ >/etc/hadoop/myconf/nodes_allow.txt      # 清空nodes_allow.txt文件,即允許所有節點向RM注冊
$ su - yarn 'yarn rmadmin -refreshNodes'    # 刷新RM的Nodes列表信息
至此,我們線上的Yarn調度模擬環境已准備完畢,基本具備和線上規模同等的模擬環境。
 
 
【參考資料】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM