當前位置:首頁 » 操作系統 » yarncontainer源碼

yarncontainer源碼

發布時間: 2022-07-26 17:17:05

1. Spark下Yarn-Cluster和Yarn-Client的區別

(1)SparkContext初始化不同,這也導致了Driver所在位置的不同,YarnCluster的Driver是在集群的某一台NM上,但是Yarn-Client就是在RM在機器上;
(2)而Driver會和Executors進行通信,這也導致了Yarn_cluster在提交App之後可以關閉Client,而Yarn-Client不可以;
(3)最後再來說應用場景,Yarn-Cluster適合生產環境,Yarn-Client適合交互和調試。

2. yarn container 是進程嗎

container就是「一組資源」,現在是「內存+CPU」,未來還有可能把網路帶寬之類的也包含進去。
當有一個Application(在MRV1里叫Job),第一個container就用來跑ApplicationMaster,然後ApplicationMaster再申請一些container來跑Mapper,之後再申請一些container來跑Recer。

container既可以跑Mapper也可以跑Recer,就不像MRV1里的map slot只能跑map、rece slot只能跑rece。

3. YARN到底是怎麼一回事

YARN的編程模型
1:保證編程模型的向下兼容性,MRv2重用了MRv1的編程模型和數據處理引擎,但運行環境被重寫。
2:編程模型與數據處理引擎
maprece應用程序編程介面有兩套:新的API(mapred)和舊的API(maprece)
採用MRv1舊的API編寫的程序可直接運行在MRv2上
採用MRv1新的API編寫的程序需要使用MRv2編程庫重新編譯並修改不兼容的參數 和返回值
3:運行時環境
MRv1:Jobracker和Tasktracker
MRv2:YARN和ApplicationMaster

YARN的組成
yarn主要由ResourceManager,NodeManager,ApplicationMaster和Container等幾個組件組成。
ResourceManager(RM)
RM是全局資源管理器,負責整個系統的資源管理和分配。
主要由兩個組件組成:調度器和應用 程序管理器(ASM)
調度器
調度器根據容量,隊列等限制條件,將系統中的資源分配給各個正在運行的應用程序
不負責具體應用程序的相關工作,比如監控或跟蹤狀態
不負責重新啟動失敗任務
資源分配單位用「資源容器」resource Container表示
Container是一個動態資源分配單位,它將內存,CPU,磁碟,網路等資源封裝在一起,從而限定每個任務的資源量
調度器是一個可插拔的組件,用戶可以自行設計
YARN提供了多種直接可用的調度器,比如fair Scheler和Capacity Scheler等。
應用程序管理器
負責管理整個系統中所有應用程序
ApplicationMaster(AM)
用戶提交的每個應用程序均包含一個AM
AM的主要功能
與RM調度器協商以獲取資源(用Container表示)
將得到的任務進一步分配給內部的任務
與NM通信以自動/停止任務
監控所有任務運行狀態,並在任務運行失敗時重新為任務申請資源以重啟任務
當前YARN自帶了兩個AM實現
一個用於演示AM編寫方法的實常式序distributedshell
一個用於Maprece程序---MRAppMaster
其他的計算框架對應的AM正在開發中,比如spark等。
Nodemanager(NM)和Container
NM是每個節點上的資源和任務管理器
定時向RM匯報本節點上的資源使用情況和各個Container的運行狀態
接收並處理來自AM的Container啟動/停止等各種要求
Container是YARN中的資源抽象,它封裝了某個節點上的多維度資源
YARN會為每個任務分配一個Container,且改任務只能使用該Container中描述的資源
Container不同於MRv1的slot,它是一個動態資源劃分單位,是根據應用程序的需求動態產生的
YARN主要由以下幾個協議組成
ApplicationClientProtocol
Jobclient通過該RPC協議提交應用才程序,查詢應用程序狀態等

Admin通過該協議更新系統配置文件,比如節點黑名單,用戶隊列許可權等。
ApplicationMasterProtocol
AM通過該RPC協議想RM注冊和撤銷自己,並為各個任務申請資源
ContainerManagementProtocol
AM通過要求NM啟動或者停止Container,獲取各個Container的使用狀態等信息
ResourceTracker
NM通過該RPC協議向RM注冊,並定時發送心跳信息匯報當前節點的資源使用情況和Container運行狀況
YARN的工作流程
文字描述一下這個過程:
1:由客戶端提交一個應用,由RM的ASM接受應用請求
提交過來的應用程序包括哪些內容:
a:ApplicationMaster
b:啟動Applicationmaster的命令
c:本身應用程序的內容
2:提交了三部分內容給RM,然後RM找NodeManager,然後
Nodemanager就啟用Applicationmaster,並分配Container

接下來我們就要執行這個任務了,
3:但是執行任務需要資源,所以我們得向RM的ASM申請執行任務的資源(它會在RM這兒注冊一下,說我已經啟動了,注冊了以後就可以通過RM的來管理,我們用戶也可以通過RM的web客戶端來監控任務的狀態)ASM只是負責APplicationMaster的啟用
4::我們注冊好了後,得申請資源,申請資源是通過第四步,向ResourceScheler申請的
5:申請並領取資源後,它會找Nodemanager,告訴他我應經申請到了,然後Nodemanager判斷一下,
6:知道他申請到了以後就會啟動任務,當前啟動之前會准備好環境,
7:任務啟動以後會跟APplicationmaster進行通信,不斷的心跳進行任務的匯報。
8:完成以後會給RM進行匯報,讓RSM撤銷注冊。然後RSM就會回收資源。當然了,我們是分布式的,所以我們不會只跟自己的Nodemanager通信。也會跟其他的節點通信。

4. yarn appmaster得到的container是虛擬的還是實際的

container就是「一組資源」,現在是「內存+CPU」,未來還有可能把網路帶寬之類的也包含進去。 當有一個Application(在MRV1里叫Job),第一個container就用來跑ApplicationMaster,然後ApplicationMaster再申請一些container來跑Mapper

5. 為什麼我要選擇使用Yarn來做Docker的調度引擎

可部署性

先說明下,這里探討的是Yarn或者Mesos集群的部署,不涉其上的應用。Yarn除了依賴JDK,對操作系統沒有任何依賴,基本上放上去就能
跑。Mesos因為是C/C++開發的,安裝部署可能會有庫依賴。
這點我不知道大家是否看的重,反正我是看的相當重的。軟體就應該是下下來就可以Run。所以12年的時候我就自己開發了一套Java服務框架,開發完之後
運行個main方法就行。讓應用包含容器,而不是要把應用丟到Tomcat這些容器,太復雜,不符合直覺。

二次開發

Yarn 對Java/Scala工程師而言,只是個Jar包,類似索引開發包Lucene,你可以把它引入項目,做任何你想要的包裝。 這是其一。

其二,Yarn提供了非常多的擴展介面,很多實現都是可插拔。可替換的,在XML配置下,可以很方便的用你的實現替換掉原來的實現,沒有太大的侵入性,所以就算是未來Yarn升級,也不會有太大問題。

相比較而言,Mesos更像是一個已經做好的產品,部署了可以直接用,但是對二次開發並不友好。

生態優勢

Yarn 誕生於Hadoop這個大數據的「始作俑者」項目,所以在大數據領域具有先天優勢。

底層天然就是分布式存儲系統HDFS,穩定高效。
其上支撐了Spark、MR等大數據領域的扛頂之座,久經考驗。
社區強大,最近發布版本也明顯加快,對於長任務的支持也越來越優秀。

長任務支持

談及長任務(long running
services)的支持,有人認為早先Yarn是為了支持離線短時任務的,所以可能對長任務的支持有限。其實大可不必擔心,譬如現在基於其上的
Spark Streaming就是7x24小時運行的,跑起來也沒啥問題。一般而言,要支持長任務,需要考慮如下幾個點:

Fault tolerance,主要是AM的容錯。
Yarn Security,如果開啟了安全機制,令牌等的失效時間也是需要注意的。
日誌收集到集群。
還有就是資源隔離和優先順序。如果資源隔離做的太差,會對長時任務產生影響。

大家感興趣可以先參考Jira。我看這個Jira 13年就開始了,說明這事很早就被重視起來了。下面我們隊提到的幾個點做下解釋。

Fault tolerance

Yarn 自身高可用。目前Yarn的Master已經實現了HA。
AM容錯,我看從2.4版本(看的源碼,也可能更早的版本就已經支持)就已經支持 keep containers across
attempt
的選項了。什麼意思呢?就是如果AM掛掉了,在Yarn重新啟動AM的過程中,所有由AM管理的容器都會被保持而不會被殺掉。除非Yarn多次嘗試都沒辦
法把AM再啟動起來(默認兩次)。 這說明從底層調度上來看,已經做的很好了。

日誌收集到集群

日誌收集在2.6版本已經是邊運行邊收集了。

資源隔離

資源隔離的話,Yarn做的不好,目前有效的是內存,對其他方面一直想做支持,但一直有限。這估計也是很多人最後選擇Mesos的緣由。但是現在這
點優勢Mesos其實已經盪然無存,因為Docker容器在資源隔離上已經做的足夠好。Yarn和Docker一整合,就互補了。

小結

Mesos 和 Yarn 都是非常優秀的調度框架,各有其優缺點,彈性調度,統一的資源管理是未來平台的一個趨勢,類似的這種資源管理調度框架必定會大行其道。

一些常見的誤解

脫胎於Hadoop,繼承了他的光環和生態,然而這也會給其帶來一定的困惑,首先就是光環一直被Hadoop給蓋住了,而且由於固有的慣性,大家會理所當然的認為Yarn只是Hadoop里的一個組件,有人會想過把Yarn拿出來單獨用么?

然而,就像我在之前的一篇課程里,反復強調,Hadoop是一個軟體集合,包含分布式存儲,資源管理調度,計算框架三個部分。他們之間沒有必然的關
系,是可以獨立開來的。而Yarn
就是一個資源管理調度引擎,其一開始的設計目標就是為了通用,不僅僅是跑MR。現在基於Yarn之上的服務已經非常多,典型的比如Spark。

這里還有另外一個誤區,MR目前基本算是離線批量的代名詞,這回讓人誤以為Yarn也只是適合批量離線任務的調度。其實不然,我在上面已經給出了分析,Yarn 是完全可以保證長任務的穩定可靠的運行的。

如何基於Yarn開發分布式程序

本文不會具體教你如何使用Yarn的API,不過如果你想知道Yarn的API,但是又覺得官方文檔太過簡略,我這里倒是可以給出兩個建議:

代碼使用範例可以參看Spark Yarn相關的代碼。算的上是一個非常精簡的Yarn的adaptor。
買本Yarn相關的書,了解其體系結構也有助於你了解其API的設計。

接下來的內容會探討以下兩個主題:

基於Yarn開發分布式程序需要做的一些准備工作
基於Yarn開發容器調度系統的一些基本思路

基於Yarn開發分布式程序需要做的一些准備工作

肯定不能擼起袖子就開始干。開始動手前,我們需要知道哪些事情呢?

Yarn原生的API太底層,太復雜了

如果你想愉快的開發Yarn的應用,那麼對Yarn的API進行一次封裝,是很有必要的。
Yarn為了靈活,或者為了能夠滿足開發者大部分的需求,底層交互的API就顯得比較原始了。自然造成開發難度很大。這個也不是我一個人覺得,現在
Apache的Twill,以及Hulu他們開發的時候Adaptor那一層,其實都是為了解決這個問題。那為什麼我沒有用Twill呢,第一是文檔實在
太少,第二是有點復雜,我不需要這么復雜的東西。我覺得,Twill與其開發這么多功能,真的不如好好寫寫文檔。

最好是能開發一個解決一類問題的Framework

Yarn只是一個底層的資源管理和調度引擎。一般你需要基於之上開發一套解決特定問題的Framework。以Spark為例,他是解決分布式計算
相關的一些問題。而以我開發的容器調度程序,其實是為了解決動態部署Web應用的。在他們之上,才是你的應用。比如你要統計日誌,你只要在Spark上開
發一個Application 。 比如你想要提供一個推薦系統,那麼你只要用容器包裝下,就能被容器調度程序調度部署。

所以通常而言,基於Yarn的分布式應用應該符合這么一個層次:

Yarn -> Adapter -> Framework -> Application

Adapter 就是我第一條說的,你自個封裝了Yarn的API。 Framework就是解決一類問題的編程框架,Application才是你真正要解決業務的系統。通過這種解耦,各個層次只要關注自己的核心功能點即可。

保證你上層的Framework/Application可以移植

Spark是個典型,他可以跑在Mesos上,也可以跑在Yarn上,還可以跑在自己上面(Standalone),實時上,泡在Yarn上的,以及跑Standalone模式的,都挺多的。這得益於Spark本身不依賴於底層的資源管理調度引擎。

這其實也是我上面說的兩條帶來的好處,因為有了Adaptor,上層的Framework可以不用綁死在某個資源調度引擎上。而Framework則可以讓Applicaiton 無需關注底層調度的事情,只要關注業務即可。

另外,你費盡心機開發的Framework上,你自然是希望它能跑在更多的平台上,已滿足更多的人的需求,對吧。

基於Yarn開發容器調度系統的一些基本思路

首先我們需要了解兩個概念:

啞應用。所謂啞應用指的是無法和分布式系統直接進行交互,分布式系統也僅僅透過容器能進行生命周期的控制,比如關閉或者開啟的應用。典型的比如MySQL、Nginx等這些基礎應用。他們一般有自己特有的交互方式,譬如命令行或者socket協議或者HTTP協議。
伴生組件。因為有了啞應用的存在,分布式系統為了能夠和這些應用交互,需要有一個代理。而這個代理和被代理的啞應用,具有相同的生命周期。典型
的比如,某個服務被關停後,該事件會被分布式系統獲知,分布式系統會將該事件發送給Nginx的伴生組件,伴生組件轉化為Nginx能夠識別的指令,將停
止的服務從Nginx的ProxyBackend列表中剔除。

在容器調度系統中,如果Yarn的NodeManager直接去管理Docker則需要Yarn本身去做支持,我覺得這是不妥的。Yarn的職責就是做好資源管理,分配,調度即可,並不需要和特定的某個技術耦合,畢竟Yarn是一個通用型的資源調度管理框架。

那基於上面的理論,我們基於Yarn,開發一套框架,這個框架會是典型的 master-slave結構(這是Yarn決定的)。這個框架的 slaves 其實都是Docker 的伴生對象。master 可以通過這些Slave 對容器實現間接的管理。

我們簡單描述下他們的流程:

用戶提交Application,申請資源;
Yarn啟動Framework的master;
Yarn啟動Framework的slave;
slave 連接上master,並且發送心跳,從而master知道slave的狀況slave啟動Docker,slave與被啟動的這個docker container 一一對應;
slave定時監控Container;
slave發現container crash,slave自動退出,Yarn獲得通知,收回資源;
master發現有節點失敗,發出新的節點要求,重新在另外一台伺服器上啟動slave,重復從2開始的步驟。

這里還有一個問題,如果slave 被正常殺掉,可以通過JVM ShudownHook 順帶把Container也關掉。
但是如果slave被kill -9
或者異常crash掉了,那麼就可能導致資源泄露了。目前是這個信息是由master上報給集群管理平台,該平台會定時清理。你也可以存儲該信息,譬如放
到Redis或者MySQL中,然後啟動後台清理任務即可。

了解了這個思路後,具體實施就變得簡單了,就是開發一個基於Yarn的master-slave程序即可,然後slave去管理對應的Docker容器,包括接受新的指令。master提供管理界面展示容器信息,運行狀態即可。

當然,你還可以再開發一套Framework B專門和Nginx交互,這樣比如上面的系統做了節點變更,通知B的master,然後B的master 通過自己的伴生組件Slave 完成Nginx的更新,從而實現後端服務的自動變更和通知。

6. 怎樣獲得在yarn框架上運行jar包的執行結果

配置方法
(1) 首先需要確保spark在1.1.0以上的版本。
(2) 在HDFS上建立一個公共lib庫,比如/system/spark-lib/,設置許可權為755。把spark-assembly-*.jar上傳到公共lib庫中。
(3) 在spark-env.sh中配置:

view plain to clipboardprint?
<span style="font-size:14px;">spark.yarn.jar hdfs://yarncluster/system/spark_lib/spark-assembly-1.1.0-hadoop2.3.0-cdh5.1.0.jarspark.yarn.preserve.staging.files false</span>

**spark.yarn.jar配置成HDFS上的公共lib庫中的jar包。這個配置項會使提交job時,不是從本地上傳spark-assembly*.jar包,而是從HDFS的一個目錄復制到另一個目錄(不確定HDFS上的復制是怎麼操作的),總的來說節省了一點時間。(網上有的文章里說,這里的配置,會節省掉上傳jar包的步驟,其實是不對的,只是把從本地上傳的步驟改成了在HDFS上的復制操作。)
**spark.yarn.preserve.staging.files: 這個配置項配置成false,表示在執行結束後,不保留staging files,也就是兩個jar包。然後HDFS上的.sparkStaging下的兩個jar包在作業執行完成後就會被刪除。如果配置成true,執行完後HDFS上的.sparkStaging下兩個jar包都會保存下來。
然後再運行,發現HDFS上.sparkStaging目錄下不會再保留jar包。
問題定位
按道理來說,因為spark.yarn.preserve.staging.files默認是false,所以HDFS上的jar包是不會被保留的。但是在spark1.0.2中,卻沒有刪除。我看了下1.0.2的代碼,刪除的機制是存在的:
//yarn/alpha/src/main/scala/org/apache/spark/deploy/yarn/ApplicationMaster.scala

view plain to clipboardprint?
<span style="font-size:14px;"><span style="font-family:Microsoft YaHei;font-size:12px;"> /** * Clean up the staging directory. */ private def cleanupStagingDir() { var stagingDirPath: Path = null try { val preserveFiles = sparkConf.get("spark.yarn.preserve.staging.files", "false").toBoolean if (!preserveFiles) { stagingDirPath = new Path(System.getenv("SPARK_YARN_STAGING_DIR")) if (stagingDirPath == null) { logError("Staging directory is null") return } logInfo("Deleting staging directory " + stagingDirPath) fs.delete(stagingDirPath, true) } } catch { case ioe: IOException => logError("Failed to cleanup staging dir " + stagingDirPath, ioe) } }</span></span>
按照這個邏輯,默認在AM關閉的時候,是會刪除HDFS上的jar包的。不過沒有正常刪除。推測這應該是一個1.0.2裡面的bug,而在1.1.0裡面已經修復。

nodemanager節點上的jar包緩存
升級到1.1.0版本後,HDFS上的jar包問題就解決了。但是nodemanager節點上的jar包還是會保留。這個問題的定位很糾結,不過結果卻出乎意料的簡單。不說了,上結果吧。
配置方法
(1) 配置yarn-site.xml:
<span style="font-family:Microsoft YaHei;font-size:12px;"> <property>
<name>yarn.nodemanager.local-dirs</name>
<value>local-dir1, local-dir2,local-dir3</value>
</property>
<property>
<name>yarn.nodemanager.localizer.cache.target-size-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.nodemanager.localizer.cache.cleanup.interval-ms</name>
<value>1800000</value>
</property></span>
**yarn.nodemanager.local-dirs: 這個目錄是nodemanager上的作業中間數據存放路徑。推薦配置多個盤上的多個路徑,從而分散作業執行中的磁碟IO壓力。
**yarn.nodemanager.localizer.cache.target-size-mb:配置nodemanager上的緩存目錄的最大限度。nodemanager上有一個deletion server服務,會定期檢測,如果yarn.nodemanager.local-dirs中配置的目錄大小(如果配置了多個,則計算多個目錄的總大小)是否超過了這里設置的最大限度值。如果超過了,就刪除一些已經執行完的container的緩存數據。
因為spark提交作業後遺留在nodemanager上的jar包就在yarn.nodemanager.local-dirs下面,所以只要這里配置合適的大小值。那麼nodemanager上的deletion server是會自動檢測並保證目錄總大小的。所以只要配置了這個量,我們就不需要再擔心nodemanager上的jar包緩存問題了,交給yarn就好了!很簡單啊有木有,可就這么個問題,居然花了我一個星期的時間去定位。
**yarn.nodemanager.localizer.cache.cleanup.interval-ms: deletion server多長時間做一次檢測,並且清除緩存目錄直到目錄大小低於target-size-mb的配置。
通過上面這三個量的配置,nodemanager會確保本地的緩存數據總量在target-size-mb之下,也就是超過了的話,之前的spark的jar包就會被刪除。所以我們就不需要再擔心nodemanager節點上的spark jar包緩存問題了。不過target-size-mb的默認值是10G,這個值當然可以根據你的實際情況進行調整。

7. 如何理解 yarn 的 container

container就是「一組資源」,現在是「內存+CPU」,未來還有可能把網路帶寬之類的也包含進去。
當有一個Application(在MRV1里叫Job),第一個container就用來跑ApplicationMaster,然後ApplicationMaster再申請一些container來跑Mapper,之後再申請一些container來跑Recer。
container既可以跑Mapper也可以跑Recer,就不像MRV1里的map slot只能跑map、rece slot只能跑rece。

熱點內容
微信上的電影怎麼下載或緩存 發布:2025-01-19 14:30:57 瀏覽:826
如何在外網訪問伺服器 發布:2025-01-19 14:29:45 瀏覽:380
百度重定向腳本 發布:2025-01-19 14:29:36 瀏覽:428
php怎麼反編譯 發布:2025-01-19 14:10:54 瀏覽:590
加密貨幣交易平台排名 發布:2025-01-19 13:58:21 瀏覽:741
紅綠燈的編程 發布:2025-01-19 13:57:37 瀏覽:113
老男孩linux教程 發布:2025-01-19 13:44:48 瀏覽:941
買車怎麼區分車配置 發布:2025-01-19 13:44:45 瀏覽:242
丟失緩存視頻 發布:2025-01-19 13:44:09 瀏覽:183
C語言tp 發布:2025-01-19 13:26:20 瀏覽:107