本篇本意是介绍hadoop的部署资源隔离和调度方案yarn。顺便介绍了容器和容器集群管理。
说回yarn隔离分为cpu和内存,cpu基于cgroups,内存自行实现计算ru_maxrss。还对比了k8n的隔离,它内存和cpu都基于cgroups。在调度方面介绍了yarn的两种调度机制Capacity Scheduler和Fair Scheduler。
总体:https://segmentfault.com/a/11...java
yarn
yarn是hadoop的资源隔离和调度
运行在YARN上带来的好处 :linux
一个集群部署多个版本
计算资源按需伸缩
不一样负载应用混搭,集群利用率高
共享底层存储,避免数据跨集群迁移

两层资源调度算法
- RM
负责AM的建立和从AM接收分配请求分配,有调度器(上述的调度算法插件式放这儿),ASM(分配AM)
- AM
负责计算分配量(每一个容器大小,要多少个容器)/监控/容错,一个容器运行一个任务,AM能够要多个分配给本身内部任务。
1.到RM申请,在一个Container(只是一个java对象,虚拟的,指定资源大小,启动时是运行task的bin文件等)中启动AM
包含异步的分配资源,暂存在缓冲区,等待AM来取
2.AM RPC取资源并与NM通讯
AM领取资源后分配任务不是yarn事情,用户自行实现
3.包含各类状态同步,好比7,持续的nm到rm.docker
隔离
目前只能实现cpu和内存的隔离
基于cgroups
linux/kernel/cgroup,包含子系统:cpu,io,mmemory,net等segmentfault

内核中的代码在kennel下。
用户使用:经过文件系统配置(内核给用户提供的方法)
VFS 文件:ext2,ext3磁盘,socket,cgroups 。操做系统实现后能够经过mount挂载到cgroups文件系统
vi /etc/cgconfig.conf。/sys/fs/cgroup/cpuset中配置便可
对于内存并无直接用cgroups
内存隔离:线程监控进程内存量,不是超过马上杀死,有个生命期服务器
- jvm不足以:每一个任务不只有java进程,reduce用C++
- 不能单纯的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网络
两者都从根开始选择队列,应用,容器,分配资源(递归直到叶子容器)。每次选择时依据不一样。框架
概述容器/资源 隔离与调度
技术
- namespace技术用来进行作进程间的隔离,linux namespace包括:mount namespace, uts namespace, ipc namespace, pid namespace, network namespace, user namespace六种,用于将mount点、UTS(hostname, domain name)、IPC资源、进程、网络、用户等六种资源作到进程级别的隔离。容器做为一个普通的进程,使用namespace技术做隔离。
- pivot_root根文件系统切换。mount –bind /etc /tmp/test/etc方式容许从任何其余位置访问任何文件或目录,可是其余用户仍然能看到这些mount点,而mount namespace能够作到mount点在各个进程之间隔离。尽管如此,目前没有对文件/目录作进程间隔离的namespace,因此有必要制做根文件系统再采用pivot_root命令在容器内替换为这个根文件系统(注:chroot只是在指定的根文件系统下运行命令)。
- cgroups技术用来作资源限制,这些资源包括CPU、内存、存储、网络等。
- AUFS文件系统采用CoW写时复制技术将多个文件系统联合到一个挂载点,这样能够为容器实现一个只读的base镜像加一个可写的镜像,从而缩小镜像的体积。
虚拟机/容器
- 在hadoop的yarn部署中,容器只是个资源单位的虚拟(没有移植的概念,是在机器上运行执行文件进程限制资源)
- 最第一版本的chroot(目录隔离)
- 虚拟机(独立系统,经过hypervisor把硬件页指向vm,hypercall调用负责vm和下层硬件调用,因此硬件能够共享,可是隔离性更好,lxc由于一个操做系统很难作到硬件彻底隔离)
- LXC(与虚拟机比不须要单独操做系统,共享的更多就更节省,是docker的基础)
Kernel namespaces (ipc, uts, mount, pid, network and user)
Apparmor and SELinux profiles
Seccomp policies
Chroots (using pivot_root)
Kernel capabilities
CGroups (control groups)
- docker(基于lxc(没有调度分配集群管理);多了https://stackoverflow.com/que...:应用容器,镜像,AUFS能够跨机器/甚至平台移植,增量更改,应用自动部署),rkt(有了k8s以后docker的技术壁垒变低,k8s能够集成任何容器,只要他支持)。能够运行在虚拟机上
资源隔离调度/容器编排管理
- 从初版的JobTracker 单进程的资源分配,源于hadoop。
- 第二版的Borg(google,未公开过)/yarn/mesos(twitter)等双层(单主总体负责分配,多二层负责具体监控等,各个框架调度器并不知道整个集群资源使用状况,只是被动的接收资源;Master仅将可用的资源推送给各个框架)
- 第三版的omega(google) 去中心化,集群信息共享,乐观锁,集群申请变化快性能会很差(http://dockone.io/article/1153)
以上这些自己容器是抽象调的,隔离和调度就能够实现这些容器的隔离和固定大小的分配。能够和docker等容器一块儿用(隔离是重复的),用来调度和部署。docker是运行时隔离和镜像
k8s是须要针对具体容器的,重点在于调度部署等,能够做为docker的编排管理,也针对docker作了不少应用。只要支持dom
- k8s(google基于omega,开发人员基本都是omega和Borg的)也能够隔离,功能更全容器编排与管理,容器互联,pod组合等
因此其实能够用任何k8s,yarn来部署和控制docker资源配置。
- 国内百度云,腾讯云都实现本身的,好比百度的matrix.相似Borg
云
云计算和云存储的思想都是,海量分布式环境,用户请求返回按需计算收费:云计算是一种按使用量付费的模式,这种模式提供可用的、便捷的、按需的网络访问, 进入可配置的计算资源共享池(资源包括网络,服务器,存储,应用软件,服务)
云计算能够认为包括如下几个层次的服务:基础设施即服务(IaaS),平台即服务(PaaS)和软件即服务(SaaS)

须要分布式大量副本和不一样版本控制升级等,docker为其提供了下降运维的方式(相似其中的Iaas+升级等管理工具);虚拟技术和容器管理为其提供了多租户隔离和调度。
云可使用虚拟机节约硬件,私有云能够直接使用docker和k8s即节约硬件也节省操做系统占用,虚拟机和docker也能够适当超卖,docker超卖成本低,由于迁移方便,虚拟机貌似迁移成本很高。在提供虚拟机同时也能够提供k8s+docker的服务,使
k8s
基本上彻底基于cgroups。可是对于内存/磁盘这种没有就不行的不可压缩资源,会再加一个阈值,防止不稳定,能分配的会少于这个。因此k8s对于内存的限制会在fork时误放大没有处理。
https://juejin.im/post/5b3d8c...