yarn cgroup 資源隔離(cpu篇)

環境配置

cdh 5.9.0
cm  5.15.0
os  centos 7.2

背景

yarn container 默認不支持對cpu進行資源隔離,一些計算密集型任務甚至可能佔滿NM節點的cpu資源,從而影響到其他任務的執行效率。

  • spark streaming 出現消費延時
  • 一些調度任務運行時間波動較大

例如申請的1個vcore,實際上又啓動了多線程,還有GC線程等都會造成資源使用不可控。
部分Container佔用大量計算資源

目標

  • 限制一些計算密集型任務的CPU使用,避免多 Container 運行在同一臺機器上,cpu 爭用導致的任務運行時間不穩定,流任務消費抖動等情況
  • 避免個別 Container CPU 使用過高,造成系統負載過高或者不穩定 / 影響到其他服務的穩定性(例如 DATANODE)

資源隔離

Cgroup & LinuxContainerExecutor

默認情況下,NodeManager 使用 DefaultContainerExecutor 以 NodeManager 啓動者的身份來執行啓動Container等操作,安全性低且沒有任何CPU資源隔離機制。

要達到這種目的,必須要使用 LinuxContainerExecutor,從而以應用提交者的身份創建文件,運行/銷燬 Container。允許用戶在啓動Container後直接將CPU份額和進程ID寫入cgroup路徑的方式實現CPU資源隔離。

Cgroup 是linux kernel的一個功能,可以資源進行隔離,Yarn中現在支持對cpu/mem/io三種資源進行隔離。

cpu 資源隔離

NodeManager 通過修改 cgroup 的 cpu.cfs_period_us,cpu.cfs_quota_us,cpu.shares 三個文件實現對 cpu 的資源限制,還可以進一步細分爲 soft limit 和 hard limit 兩種方式。

  • cpu.cfs_period_us - 時間週期,默認爲1000*1000微秒(1s),在yarn中按該時間來劃分一次cpu的時間片調度週期
  • cpu.cfs_quota_us - 單位時間內可用的 cpu 時間,默認無限制(-1)
  • cpu.shares - 用於分配cpu執行的權重,默認爲 1024

NodeManager 資源相關配置
* yarn.nodemanager.resource.cpu-vcores nodemanager 可以分配的 vcore 數量。
* yarn.nodemanager.resource.percentage-physical-cpu-limit nm 所有Container cpu 使用佔物理機cpu資源的比例,通過降低nm的cpu.cfs_period_us實現。

nm 所在的物理機 core 數量爲 40,cpu limit 設置爲 90%,則 nm 上所有 container 的綜合 cpu 使用不會超過 3600%

hard limit

yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage 設置爲 true 時生效。通過改變cpu.cfs_quota_uscpu.cfs_period_us文件控制cpu資源使用的上限。

嚴格按照任務初始分配的cpu進行限制,即使還有空閒的CPU資源也不會佔用。

core = cpu.cfs_quota_us/cpu.cfs_period_us
計算公式
  • containerVCores 單個 container 申請的core
  • yarnProcessors nodemanager 所在節點的物理 core * yarn.nodemanager.resource.percentage-physical-cpu-limit
  • nodeVcores nodemanager 設置的 VCore 數量

    containerCPU = (containerVCores * yarnProcessors) / (float) nodeVCores

例如一臺4核的虛擬機,VCore 設置爲8,啓動一個vcore 爲 1 的 Container,在 yarn.nodemanager.resource.percentage-physical-cpu-limit 爲 100的情況下,使用率不會超過50%

如果將yarn.nodemanager.resource.percentage-physical-cpu-limit設置爲90,則每個Container的cpu使用率不會超過45%

soft limit

yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage 設置爲 false 時生效,通過 cpu.shares 文件控制資源使用,該參數只能控制資源使用的下限。

按比例對資源進行限制,在這種模式下,允許 Container 使用額外的空閒CPU資源。

計算公式

有 VCore 分別爲 1,1,2 的三個 Container,則 cpu.shares 會被設置爲 1024 1024 2048,那麼他們可以使用的cpu時間比率爲1 : 1 : 2

啓動兩個應用,每個應用的 Container 的 VCore 都爲1,則每個executor都使用100%

F8E11DEA-495B-4E71-8E36-7A32E7027E21.png

啓動兩個應用,一個應用Container VCore爲1,一個應用 Container VCore爲2,前者分到的cpu 資源爲66%,後者爲132%

58683F4B-8369-431B-93EF-5749F47FC8F6.png

啓動兩個應用,一個應用Container vcore爲1,一個應用 Container vcore爲3,前者分到的cpu 資源爲50%,後者爲150%

image.png

TIPS: 由此可見,任務的可用資源會隨着不同的機器負載發生變化

兩種方式的一些對比

PCore 爲8的機器,NM VCore 設置爲6,p-limit 設置爲50。

scenario soft limit hard limit
啓動 4個 Container,每個 Container 的 VCore 爲1 100%, 100% 66.7%, 66,7%
啓動 2個 Container,其中一個VCore爲2,一個VCore爲1 200%, 100% 133%, 66.7%
啓動 4個 Container,其中兩個VCore爲2,兩個VCore爲1 133%, 66.7% 133%, 66.7%

總結

根據不同場景選擇限制模式

一些對比 soft limit hard limit
優點 nm資源使用率高 資源限制更嚴格,運行時間更可控
缺點 根據機器上運行的Container資源申請情況,資源分配動態變化,可能造成運行時間不穩定 低負載場景下不能充分利用空閒的nm資源
控制方式 控制Container使用的cpu下限 控制Container使用的cpu上限
使用場景 對任務運行時間不敏感 集羣上運行多種類型的任務,對SLA有一定要求

開啓Cgroup後帶來的變化

  • 計算密集型任務運行時間相比之前可能會變長,需要修改相關配置
  • driver 默認使用1c,如果是 cluster 模式,driver 會運行在container中,所以也會受到限制。driver 負載比較高的任務(例如讀取了大量的分區或者task數量比較多),速度會有所下降。
  • 大多數任務運行時間較之前穩定。

相關配置

參數 屬性 描述
yarn.nodemanager.container-executor.class org.apache.hadoop.yarn.server
.nodemanager.LinuxContainerExecutor
Yarn 是否使用 Linux Container Executor。
yarn.nodemanager.linux-container-executor.resources-handler.class org.apache.hadoop.yarn.server
.nodemanager.util.CgroupsLCEResourcesHandler
YARN 是否根據容器創建 cgroup,從而隔離容器的 CPU 使用情況
yarn.nodemanager.linux-container-executor.cgroups.hierarchy /hadoop-yarn yarn 使用的 cgroup 組,默認爲/hadoop-yarn,一般不作修改
yarn.nodemanager.linux-container-executor.cgroups.mount true 是否自動掛載cgroup
yarn.nodemanager.linux-container-executor.cgroups.mount-path /sys/fs/cgroup cgroup 掛載目錄,centos7 爲/sys/fs/cgroup,centos6 爲 /cgroup
yarn.nodemanager.linux-container-executor.group yarn 容器執行組,一般無需設置
yarn.nodemanager.resource.percentage-physical-cpu-limit 90 配置nodemanager使用多少物理cpu資源,比如24核服務器配置90的話,只能使用21.6核
yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage true 是否啓用嚴格資源限制,按任務申請的CPU數量控制 / 按core的比率限制
yarn.nodemanager.linux-container-executor.nonsecure-mode.local-user nobody 使用 Linux-container-executor 時,運行容器的 UNIX 用戶,一般不用更改

相關代碼

CgroupsLCEResourcesHandler.setupLimits

  public void setupLimits(ContainerId containerId,
                           Resource containerResource) throws IOException {
    String containerName = containerId.toString();

    if (isCpuWeightEnabled()) {
      int containerVCores = containerResource.getVirtualCores();
      createCgroup(CONTROLLER_CPU, containerName);

      int cpuShares = CPU_DEFAULT_WEIGHT * containerVCores;
      // absolute minimum of 10 shares for zero CPU containers
      cpuShares = Math.max(cpuShares, 10);

      updateCgroup(CONTROLLER_CPU, containerName, "shares",
          String.valueOf(cpuShares));
      if (strictResourceUsageMode) {
        int nodeVCores =
            conf.getInt(YarnConfiguration.NM_VCORES,
              YarnConfiguration.DEFAULT_NM_VCORES);
        if (nodeVCores != containerVCores) {
        // yarnProcessors 爲物理機總線程數 * cpu_limit 
          float containerCPU =
              (containerVCores * yarnProcessors) / (float) nodeVCores;
          int[] limits = getOverallLimits(containerCPU);
          updateCgroup(CONTROLLER_CPU, containerName, CPU_PERIOD_US,
              String.valueOf(limits[0]));
          updateCgroup(CONTROLLER_CPU, containerName, CPU_QUOTA_US,
              String.valueOf(limits[1]));
        }
      }
    }
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章