hadoop-yarn、内核资源隔离

本篇介绍hadoop的部署资源隔离和调度方案yarn。隔离分为cpu和内存,cpu基于cgroups,内存自行实现计算ru_maxrss。还对比了k8n的隔离,它内存和cpu都基于cgroups。在调度方面介绍了yarn的两种调度机制Capacity Scheduler和Fair Scheduler。
整体:https://segmentfault.com/a/11...

yarn

yarn是hadoop的资源隔离和调度
运行在YARN上带来的好处 :

一个集群部署多个版本
计算资源按需伸缩
不同负载应用混搭,集群利用率高
共享底层存储,避免数据跨集群迁移

hadoop-yarn、内核资源隔离

1.到RM申请,在一个Container中启动AM
包含异步的分配资源,暂存在缓冲区,等待AM来取
2.AM RPC取资源并与NM通信
AM领取资源后分配任务不是yarn事情,用户自行实现
3.包含各种状态同步,比如7,持续的nm到rm.

隔离

目前只能实现cpu和内存的隔离
基于cgroups
linux/kernel/cgroup,包含子系统:cpu,io,mmemory,net等

hadoop-yarn、内核资源隔离

内核中的代码在kennel下。
用户使用:通过文件系统配置(内核给用户提供的方法)
VFS 文件:ext2,ext3磁盘,socket,cgroups 。操作系统实现后可以通过mount挂载到cgroups文件系统
vi /etc/cgconfig.conf。/sys/fs/cgroup/cpuset中配置即可
对于内存并没有直接用cgroups
内存隔离:线程监控进程内存量,不是超过立刻杀死,有个生命期

  1. jvm不足以:每个任务不仅有java进程,reduce用C++
  2. 不能单纯的cgroups内存树直接配置
    Linux中所有的进程都是通过fork()复制来实现的,而为了减少创建进程带来的堆栈消耗和性能影响,Linux使用了写时复制机制来快速创建进程。也就是说,一个子进程刚刚产生时,它的堆栈空间和父进程是完全一致的,那么从一开始它就拥有和父进程同样的ru_maxrss,如果父进程的ru_maxrss比较大,那么由于rusage计算值取最大值,就算在触发写时复制后,子进程使用的实际最大驻留集大小被更新,我们获得的也还是父进程的那个值,也就是说我们永远拿不到子进程真实使用的内存。
    Java创建子进程时采用了“fork() + exec()”的方案,子进程启动瞬间,它的内存使用量与父进程是一致的,exec系函数,这个系别的函数通过将当前进程的使用权转交给另一个程序,这时候进程原有的所有运行堆栈等数据将全部被销毁,因此ru_maxrss也会被清零计算,然后子进程的内存会恢复正常;也就是说,Container(子进程)的创建过程中可能会出现内存使用量超过预先定义的上限值的情况(取决于父进程,也就是NodeManager的内存使用量);此时,如果使用Cgroup进行内存资源隔离,这个Container就可能会被“kill”。
    虽然我们已经可以获得各个Container进程树的内存(物理内存、虚拟内存)使用量,但是我们不能仅凭进程树的内存使用量(物理内存、虚拟内存)是否超过上限值就决定是否“杀死”一个Container,因为“子进程”的内存使用量是有“波动”的,为了避免“误杀”的情况出现,Hadoop赋予每个进程“年龄”属性,并规定刚启动进程的年龄是1,MonitoringThread线程每更新一次,各个进程的年龄加一,在此基础上,选择被“杀死”的Container的标准如下:如果一个Contaier对应的进程树中所有进程(年龄大于0)总内存(物理内存或虚拟内存)使用量超过上限值的两倍;或者所有年龄大于1的进程总内存(物理内存或虚拟内存)使用量超过上限值,则认为该Container使用内存超量,可以被“杀死”。(注意:这里的Container泛指Container进程树)
    fork/exec/线程/进程在另一篇:xx

调度

1.可以占用空闲资源 Capacity Scheduler DefaultResourceCalculator(哪个用得少分哪个),drf
2.平均分配 Fair Scheduler 支持fair,fifo,drf

二者都从根开始选择队列,应用,容器,分配资源(递归直到叶子容器)。每次选择时依据不同。

  • Capacity Scheduler
    在 Capacity Scheduler 中,在比较资源占用率时,不同的资源比较器对资源定义是不一样的。默认的是 DefaultResourceCalculator,它只考虑内存资源。另外一种是 DominantResourceCalculator,采用了 DRF 比较算法,同时考虑内存和 cpu 两种资源
    DRF:每次计算资源分配占用,最大的。选择最大中最小的分配资源

    hadoop-yarn、内核资源隔离

    考虑一个有9个cpu和18GB的系统,有两个用户:用户A的每个任务都请求(1CPU,4GB)资源;用户B的每个任务都请求(3CPU,1GB)资源。最终A分配3份,B分配两份

    hadoop-yarn、内核资源隔离

  • Fair Scheduler
    fair比较:
    若 s2紧需资源,s1 不紧需资源,把资源给 s2
    若 s1、s2 都紧需资源,把资源给 minShareRatio 更小的,minShareRatio1 = 已使用内存/ 最小资源保证
    若 s1、s2 都不紧需资源, 把资源给 useToWeightRatio 更小的, useToWeightRatio = 已使用内存 / 权重

k8s

基本上完全基于cgroups。但是对于内存/磁盘这种没有就不行的不可压缩资源,会再加一个阈值,防止不稳定,能分配的会少于这个。所以k8s对于内存的限制会在fork时误放大没有处理。
https://juejin.im/post/5b3d8c...

相关推荐