天天看點

Hadoop-2.6.0 CPU CGroup實作分析一、概述二、實作細節

       Hadoop-2.6.0中對CPU CGroups的實作,主要是通過CgroupsLCEResourcesHandler來實作的,通過它的int*()系列方法初始化一些參數和環境,比如CGroups的路徑等,然後在啟動容器内的可執行文

件前由LinuxContainerExecutor調用preExecute()方法,進行setupLimits()即設定限額操作,而在容器内的可執行退出後(無論成功還是失敗)由LinuxContainerExecutor調用postExecute()方法,進行

clearLimits()即清除限額操作。

                   通過參數yarn.nodemanager.linux-container-executor.resources-handler.class配置

                   配置為org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler即可

                   參數預設值是org.apache.hadoop.yarn.server.nodemanager.util.DefaultLCEResourcesHandler。

                  參見如下代碼注釋:

<code>/*</code>

<code> </code><code>* Next three functions operate on all the resources we are enforcing.</code>

<code> </code><code>*/</code>

<code>private</code> <code>void</code> <code>setupLimits(ContainerId containerId,</code>

<code>                         </code><code>Resource containerResource) </code><code>throws</code> <code>IOException {</code>

<code>  </code><code>String containerName = containerId.toString();</code>

<code>  </code><code>if</code> <code>(isCpuWeightEnabled()) {</code>

<code>    </code> 

<code>    </code><code>// 取container申請到資源中的VCores,注意用的是虛拟core</code>

<code>    </code><code>int</code> <code>containerVCores = containerResource.getVirtualCores();</code>

<code>    </code><code>// 建立CGroup,其實就是在CGroup路徑中建立與CPU和容器名稱相關的路徑</code>

<code>    </code><code>createCgroup(CONTROLLER_CPU, containerName);</code>

<code>    </code><code>// 對應隔離方式(一),即shares</code>

<code>    </code><code>int</code> <code>cpuShares = CPU_DEFAULT_WEIGHT * containerVCores;</code>

<code>    </code><code>// 更新CGroup,其實就是在上述路徑中将數值cpuShares寫入shares檔案</code>

<code>    </code><code>// 這個cpuShares的值就是container申請到資源中的VCores * 1024</code>

<code>    </code><code>updateCgroup(CONTROLLER_CPU, containerName, </code><code>"shares"</code><code>,</code>

<code>        </code><code>String.valueOf(cpuShares));</code>

<code>    </code><code>// 對應隔離方式(二),即cfs_period_us、cfs_quota_us</code>

<code>    </code><code>// 這個是需要參數yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage設定為true的</code>

<code>    </code><code>if</code> <code>(strictResourceUsageMode) {</code>

<code>      </code><code>int</code> <code>nodeVCores =</code>

<code>          </code><code>conf.getInt(YarnConfiguration.NM_VCORES,</code>

<code>            </code><code>YarnConfiguration.DEFAULT_NM_VCORES);</code>

<code>      </code><code>if</code> <code>(nodeVCores != containerVCores) {</code>

<code>        </code><code>float</code> <code>containerCPU =</code>

<code>            </code><code>(containerVCores * yarnProcessors) / (</code><code>float</code><code>) nodeVCores;</code>

<code>        </code><code>int</code><code>[] limits = getOverallLimits(containerCPU);</code>

<code>        </code> 

<code>        </code><code>// 更新CGroup,其實就是在上述路徑中将數值limits[0]和limits[1]分别寫入cfs_period_us檔案和cfs_quota_us檔案</code>

<code>        </code><code>updateCgroup(CONTROLLER_CPU, containerName, CPU_PERIOD_US,</code>

<code>          </code><code>String.valueOf(limits[</code><code>0</code><code>]));</code>

<code>        </code><code>updateCgroup(CONTROLLER_CPU, containerName, CPU_QUOTA_US,</code>

<code>          </code><code>String.valueOf(limits[</code><code>1</code><code>]));</code>

<code>      </code><code>}</code>

<code>    </code><code>}</code>

<code>  </code><code>}</code>

<code>}</code>

<code>private</code> <code>void</code> <code>clearLimits(ContainerId containerId) {</code>

<code>    </code><code>// 删除Container對應路徑和檔案</code>

<code>    </code><code>deleteCgroup(pathForCgroup(CONTROLLER_CPU, containerId.toString()));</code>

<a target="_blank" href="http://wiki.baifendian.com/pages/viewpage.action?pageId=12824126"></a>

繼續閱讀