1、cpu子系统的介绍
cpu子系统用于控制cgroup中所有进程可以使用的cpu时间片。Cpu子系统管理cpu资源的使用是通过调度器实现的。主要有两种调度器:
CFS(completely fair scheduler)调度器:基于进程组的优先级或控制组的shares参数在控制组间按比例划分cpu时间。
RT(real-time)调度器:用与实时进程,控制实时进程的cpu时间。
1.1、控制cpu时间的参数设置:
cpu资源按照百分比进行使用和隔离。通过cpu.shares参数实现。通过设置cpu子系统中cpu.shares参数的值,设置控制组占用cpu的相对比例(相对于其他控制组)。默认情况下cpu.shares为1024,即所有控制组平分cpu时间。如:两个控制组该参数都是100,那么将获得相同的cpu时间,如果其中一个组是200,那么这个组的cpu时间是另一个组的2倍。每个控制组真正获得cpu时间与控制组的数量有关。CPU资源有空闲时,进程获得的cpu可以大于申请的量。这种方式能够保证每个节点上的cpu资源得到充分共享和使用,但只能保证每个container的CPU使用下限。
1.2、完全公平调度器
CFS在真实硬件上模拟完全理想的多任务处理器。在“完全理想的多任务处理器”下,每个进程能同时获得cpu的运行时间,如,当系统中有两个进程时,cpu时间被分成两份,每个进程获得50%。但在真实硬件上,当一个进程占用cpu时,其他进程必须等待。CFS采用某种策略每次调用不同进程,最终实现所有进程的公平调度。
CFS思路:根据各个进程的权重分配运行时间,可以保证高优先级进程获得较多的运行时间;CFS是通过红黑树选择每次要运行的进程从而保证公平选择运行的进程。运行时间=调度周期*进程权重/所有进程权重之和。
CFS将可运行进程插入到红黑树中,每个调度点,CFS会选择红黑树中最左边的叶子节点作为下一个获得cpu的进程,红黑树的键值是虚拟运行时间vruntime。每次时钟中断时,CFS要更新进程的虚拟运行时间,然后调整当前进程在红黑树中的位置,调整完成后,如果发现当前进程不再是最左边节点,就标记need_resched,中断返回时,检查need_resched标记完成进程切换。
vruntime=已运行时间*nice_0_load/进程权重(nice_0_load :nice值为0的进程的权重),vruntime记录了进程已运行的时间(只是将已运行时间根据进程权重进行了缩放)。
权重与nice值有一一对应关系(nice越大,权重越小);Nice值与优先级有关(优先级越大,nice越小)。所以,优先级越大,权重越大。cpu.shares=进程权重。
2、基于CFS的CGroup调度
CFS维护了一个task_group数据结构,所有的task_group组成树。
时钟中断时,从当前调度实体开始,沿着该树从下到上更新调度实体的虚拟运行时间;更新完成后,如果需要进行调度,选择下一个运行进程:首先从当前队列选择一个调度实体(红黑树最左边叶子节点),并将其设为下一个要运行的实体,如果当前实体是进程,结束,否则,从该task_group的调度队列中继续选择,直到选择的为进程。
3、YARN的cpu资源隔离
3.1、Cpu隔离介绍
为了按要求向不同任务提供相应的cpu资源,同时保证这些资源具有独占性以避免它们之间相互干扰,需要对cpu资源进行隔离。yarn使用CGroups中的cpu子系统进行cpu资源的隔离。
原因:cpu资源性质:弹性资源---它的量的大小不会直接影响应用程序的死活,只会影响运行快慢;CGroups是轻量级(相对于JVM)资源隔离技术。
YARN引入了“虚拟cpu”。因为不同节点的cpu性能和计算能力不同,可以为高性能、高计算能力cpu配置多个虚拟cpu来弥补这种差异;虚拟cpu的引入可以更细粒度的分配cpu资源。管理员可以设置每个节点上的vcore数量。应用程序申请cpu资源也是申请vcore数。
3.2、在YARN中运用CGroups(安装配置)
安装cgroup:
检测是否安装---/proc/cgroups是否存在;查看挂载点(/cgroup或/sys/fs/cgroup);
安装libcgroup;
创建cpu层级,并挂载cpu子系统;
配置yarn使用LinuxContainerExecutor
在yarn-site.xml中添加LinuxContainerExecutor相关的配置选项
配置虚拟cpu数目
修改container-executor.cfg文件
3.3、yarn中的实现
Yarn中采用linuxContainerExecutor和CgroupLCEResourceHandler来实现。
linuxContainerExecutor以安全方式启动和清除container对应的进程,linuxContainerExecutor中,实现ContainerExecutor接口中的方法(init-初始化、startLocalizer—为container启动准备运行环境、launchContainer—启动container、signalContainer—向ContainerExecutor发送信息、deleteAsUser---以usr身份清理container)。
CgroupLCEResourceHandler:执行与cgroup组相关的操作(createcgroup、updatecgroup、deletecgroup、preExecute、postExecute、getResourceOption)。
当不使用cgroup进行cpu资源隔离时,可以使用DefaultContainerExecutor(不提供cgroup和任何安全措施)。
4、未来
4.1、添加进程
目前是将进程添加到tasks文件中,不能保证线程组在同一cgroup,可以将进程组id放入cpu.pros文件中,将线程放入tasks文件中。
4.2、限制每个container的cpu资源使用上限
限制每个container的CPU资源使用上限,通过cpu.cfs_period_us(访问cpu的周期)、cpu.cfs_quota_us(一控制组中的所有进程在cpu周期内占用cpu的时间)参数实现。只能获得所申请的量,不能多用,即使有空闲cpu也不允许使用。
4.3、限制yarn的cpu资源使用上限