Hadoop YARN框架調研以及問題總結
1.YARN總體介紹
YARN的根本思想是將 JobTracker 兩個主要的功能分離成單獨的組件,分別是全局資源管理器(Resouce Manager ,RM)和每個應用獨有的Application Master(AM)。RM管理所有應用程序計算資源的分配,每一個應用的 ApplicationMaster 負責相應的調度和協調。
1.1 RM
RM是全局的資源管理器,負責整個系統資源管理和分配。主要有兩個組件組成,調度器(Scheduler),和應用管理器(Applications Manager,ASM)。
1.1.1 調度器(Scheduler)
調度器根據根據容量、隊列等限制條件,將系統中資源給各個正在運行的應用程序。資源分配的單位用資源容器(Container)表示。Container是動態資源分配的單位,將內存、CPU、磁盤、網絡等資源封裝在一起,從而限制每個任務使用的資源量。現在YARN支持Fair Schedule和Capacity Schedule。
1.1.2 Applications Manager
ASM負責管理整個系統中所有的應用程序,包括應用程序提交、與調度器協商資源以啓動ApplicationMaster(AM)、監控AM的運行狀態並在失敗時重新啓動AM。
1.2 Application Master
AM主要有三個功能:
A.與RM協商獲取資源
B.與NM通信以啓動/停止任務
C.監控所有任務的運行狀態,並在任務運行失敗時重新爲任務申請資源以重啓任務。
1.3 NodeManager
NodeManager(NM)是每個節點上資源和任務管理器。有兩個主要作用:
A.定時的向RM彙報本節點的資源使用情況和各個Container的運行狀態。
B.接收並處理AM的任務啓動/停止等請求
1.4 Container
Container是YARN爲了將來作資源隔離而提出的一個框架。每個任務對應一個Container,且該任務只能在該Container中運行。
2. YARN的部署
<!--[if !supportLists]-->1. <!--[endif]-->編譯
mvn package -Pdist,native -DskipTests
<!--[if !supportLists]-->2. <!--[endif]-->安裝環境
茂源已經將安裝好的rpm包放到yum的服務器,因此修改repos即可。
路徑/etc/yum.repos.d/
<!--[if !supportLists]-->A.<!--[endif]-->添加sogou-ws-gym.repo,其內容如下:
[sogou-ws-gym]
name=Sogou WebSearch internal packages
baseurl=http://gym.wd.djt.ss.vm.sogou-op.org/yum-release/cdh4
gpgcheck=0
enabled=1
<!--[if !supportLists]-->B. <!--[endif]-->執行命令yum clean all
<!--[if !supportLists]-->C. <!--[endif]-->yum list| grep hadoop可以看到所有的hadoop的包
<!--[if !supportLists]-->D.<!--[endif]-->yum install 所有cdh4.3.0 hadoop版本是2.0.0的包,可以使用一個腳本來執行,後續完成。
<!--[if !supportLists]-->3. <!--[endif]-->更新配置
路徑/etc/hadoop/conf
主要修改的配置文件:core-site.xml,hdfs-site.xml,mapred-site.xml(支持MR任務),yarn-site.xml,slaves(添加集羣中所有host)
可以scp已經配置OK的xml,並修改hostname來完成更新配置
scp [email protected]:/etc/hadoop/conf/* ./
注意配置classpath
<!--[if !supportLists]-->4. <!--[endif]-->啓動YARN
路徑/etc/init.d/
啓動服務service hadoop-hdfs-namenode init
service hadoop-hdfs-namenode start
service hadoop-hdfs-datanode start
service hadoop-yarn-resourcemanager start
service hadoop-yarn-nodemanager start
根據service啓動時打印的log的路徑來看各個service啓動時出錯信息,使用jps命令來看各個service有沒有正常啓動。
典型錯誤:
A.啓動hdfs的service時,需要mkdir namenode和datandoe的路徑,並保證其用戶的group都是hdfs,否則會出現permission denied
3. YARN distributeshell的啓動
在yarn的目錄下,啓動如下命令:
sudo -u hdfs hadoop jar share/hadoop/yarn/hadoop-yarn-applications-distributedshell-2.0.0-cdh4.3.0.jar org.apache.hadoop.yarn.applications.distributedshell.Client -jar share/hadoop/yarn/hadoop-yarn-applications-distributedshell-2.0.0-cdh4.3.0.jar -shell_command ls -num_containers 10 -container_memory 350 -master_memory 350
4. SVC系統面臨問題
使用YARN框架整合資源提高集羣利用率面臨的問題:
A.按時間調度的策略
B.嚴格控制container資源問題
C.基於RPC框架的CS通信模型
對於問題A,使用cgroup動態修改的功能
可以通過 LXC 讀和操縱 cgroup 文件系統的一些部分。要管理每個容器對 cpu 的使用,可以通過讀取和調整容器的 cpu.shares 來進行:
1.lxc-cgroup -n name cpu.shares
2.lxc-cgroup -n name cpu.shares howmany
使用cgroup來嚴格限制container資源,並支持動態修改
對於問題B
對於YARN本身架構採用了cgroup來限制container的CPU資源,利用線程來控制內存的總體資源。
現在需要在NodeManager中增加一個Monitor接口,此接口的主要作用是:保障volunteer機器的使用權
對於問題C
有兩種方案實現:
A.實現基於RPC的框架的通信模型,在client端提供接口SendRecvData(request, &reponse);同時在server端提供接口ProcessData(request, &reponse)。用戶需要聯編通信模型的庫。具體的實現可以在詳設中說明。
B.類似hadoop streaming模型,對於client端,調用如下的編程模式:cat 提供需要計算的數據 | ./SendRecv > temp。對於client端,我們需要實現SendRecv接口。
對於Server端,調用如下的模式:./RecvData ,對於Server端需要實現RecvData,同時將用戶實際的計算程序作爲RecvData的子進程,需要實現進程間的通信,並同時需要注意對於多線程的程序,需要保證輸入和輸出數據的一致性。
對於需要計算的數據的格式,可以按照sequence file的格式,value-len value的形式。
用戶不需要關心數據傳輸的過程。
<!--[if !supportLists]-->5. <!--[endif]-->內存收集方式實驗
對於內存收集使用/proc/meminfo的形式,針對問題:對於將文件mmap到內存後,對於cached內存影響的問題
使用如下的代碼進行測試:
#include <sys/mman.h> /* for mmap and munmap */
#include <sys/types.h> /* for open */
#include <sys/stat.h> /* for open */
#include <fcntl.h> /* for open */
#include <unistd.h> /* for lseek and write */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int fd;
void *mapped_mem, * p;
int flength = 1024;
void *start_addr = 0;
fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
flength = lseek(fd, 1, SEEK_END);
printf("get file:%s, len:%d!\n", argv[1], flength);
write(fd, "\0", 1); /* 在文件最後添加一個空字符,以便下面printf正常工作 */
lseek(fd, 0, SEEK_SET);
while ( 1 ) {
mapped_mem = mmap(start_addr, flength, PROT_READ, MAP_PRIVATE, fd, 0);
/* 使用映射區域. */
printf("%s\n", (char *)mapped_mem);
close(fd);
const int alloc_size = 32 * 1024;
char* memory = (char *)malloc (alloc_size);
mlock (memory, alloc_size);
sleep(100000);
}
munmap(mapped_mem, flength);
return 0;
}
執行上述程序,傳入一個長度爲4247B(約4.2K)的文件。其cached內存的大小,執行前後基本沒有增加。如下圖:
程序執行前 程序執行後
多次測試,發現cached的數據在前後增加並不顯著。
對於mapped的內存:
程序執行前 程序執行後
Mapped的數據增加了48KB(尚不能解釋爲什麼增長這麼多)。但可以看出對於mmap文件映射後,cached的數adf據無明顯變化,而應該佔用的是mmaped的內存。
同樣測試mlock後,cached的數據也無明顯變化,僅佔用了Mlocked的內存,如下圖:
程序執行前 程序執行後
因此,可以知道,mlock只佔用了Mlocked的內存。
根據上述的實驗,可以知道:對於總機的內存佔用情況,可以使用下述的公式計算:
MemFree + Cached – Mlocked – Mapped