本篇本意是介紹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...