13.1 HDFS原理及應用 13.2 MapReduce與Yarn原理及應用
13.1 HDFS原理及應用
分而治之簡單介紹
Hadoop(5.x版本比較好)。批轉流計算(批量積攢一段時間數據,然後流式處理)
內存尋址(納秒級)比IO尋址(磁盤毫秒級)快10萬倍,差6個0
固態硬盤IO一般 500mb/s, 機械硬盤 幾百mb/s. IO是瓶頸
問題:1T文件如何在內存50mb的單機上排序存儲文件?
1 Hash Mod三列到200個小文件中(每個文件50mb)。然後每個小文件放到內存排序
2 每個文件之間內部有序,外部無序。每個文件設置一個變量,200個變量中依次取數比較放入新文件(歸併排序思想)
HDFS
用來分治的分佈式文件系統。
更好的支持分佈式計算,目錄樹結構
HDFS整體介紹,我的筆記都來源於此:儲存模型,架構設計,持久化,讀寫流程等很全面
應用
1 基礎設施
安裝hadoop,java jdk
下載ssh(可遠程登錄管理)
可在A服務器下輸入B服務器賬號密碼,然後在A服務器下操作B服務器
ssh設免祕鑰
設host IP地址映射,關閉防火牆,不同系統之間時間同步
設置主機名稱 HOSTNAME=node1
設置IP
2 部署配置
1 hadoop配置,創建文件夾並解壓
2 vi/etc/profile配置環境變量
export JAVA_HOME=...
export HADOOP_HOME=...
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin(hadoop有兩個bin)
3 source/etc/profile(加載配置文件)
4 配置hadoop角色
a cd $HADOOP_HOME/etc/hadoop
b vi hadoop_env.sh -> export JAVA_HOME=/user/java/default
(跨系統取不到對方JAVA_HOME,也就無法運行代碼,直接再這裏本地暴露自己JAVA_HOME)
c vi core-site.xml 定義NameNode在哪裏 如hdfs:node1:9000 (ip:port)
d vi halfs-site.xml 配置副本數量,NameNode數據和DataNode數據放哪個目錄。HA模式下,配置JournalNode。非HA模式下,配置SSN在這裏
e vi slaves 配置DataNode在哪裏啓動
5 初始化啓動
格式化數據,基本僅一次。
-start-dfs.sh 讀取我們配置文件並啓動
HA模式
高可用,多個NameNode,主備切換
多個NN如何數據同步?-- 哎又是Zookeeper啊
1 樹節點強鎖(臨時節點)
2 事件機制-> watch監控 callback回調
3 臨時節點
多臺NN分Active狀態和StandBy狀態。Active對外服務。增加JournalNode角色(大於3臺)負責同步NN editlog(最終一致)。增加Zookeeper(與NN同臺)負責NN主從選舉和切換,DN同時向NN們回報block清單。
HA中無SNN角色(一段時間),由StandBy代替(實時的)
集羣
應用搭建:HA依賴ZK,搭建ZK集羣。修改hadoop配置文件並集羣同步
初始化啓動
1 啓動JournalNode
2 選一個NN格式化,僅一次
3 啓動這個NN以備另一臺同步
4 另一臺機器中:hdfs namenode_bootstrapStandby 同步
5 格式化ZK,僅一次
6 start_dfs.sh啓動
使用
權限
hdfs是一個文件系統,類似unix,linux
有用戶權限概念,有超級用戶概念
權限hdfs來自namenode自己控制
默認hdfs依賴操作系統上用戶和組
HDFS API
windows下
環境變量配置HADOOP_USER_NAME
maven加入依賴
eclipse下
配置類Resource下有core-site.xml/hdfs-site.xml
public Configuartion conf = new Configuration(true)//調用配置類信息
public FileSystem fs = FileSystem.get(conf);
Path dir = new Path("xxx");
if(fs.exists(dir)){
fs.delete(dir,true);
}
fk.mkdirs(dir);
fs = FileSystem.get(URL.create("xxx"),conf,"user") // 拿文件,user爲用戶
上傳文件
BufferInputStream input = new ~(xxx.txt);
Path outfile = new Path(xxx);
FSDataOutputStream output = fc.create(outfile);
IOUtils.copyBytes(input,output,conf,true);
下載文件
Path file = new ~;
FileStatus fss = fs.getFileStatus(file);
BlockLocation [] blks = fc.getFileBlockLocations(fss,0,fss.getLen()); //0偏移量,fss.getLen()返回fss所有block數據
for(BlockLocation b:bks){
System.out.println(b);
}
FSDataInputStream in = fs.open(file);
in.seek(123456);//根據偏移量只讀自己需要的數據,同時數據從距離近的DataNode上讀
13.2 MapReduce與Yarn原理及應用
Map:映射 ,變換,過濾。 1進n出
Reduce:分解,縮小,歸納
key value:key劃分數據分組(group),group不可拆分
data經過map到中間數據集,經過reduce最終result集
簡單流程圖
一個切片約爲一個block塊。block爲物理切分,split切片爲邏輯切分。加入邏輯切分用來解耦
map並行數量由切片決定,只有map部分1對1,一個切片對應一個map。
reduce並行度由人決定
詳細流程圖
序號1 切片會格式化出記錄,以記錄爲單位調用map方法
序號2 map輸出kv映射(kv參與分區計算,拿k計算出 kvp (partition分區號))放入內存中
map任務輸出是一個文件,保存在本地系統中
序號3 在內存中分區有序的排序,減少後面排序壓力。
序號4 當內存寫滿則批量數據寫入磁盤,並進行二次排序,分區內有序。批量是爲了減少操作系統上下文開銷
序號5 reduce歸併排序和reduce方法計算同時發生,儘量減少IO開銷
有批量計算中非常好的迭代器模式支持
具體Map_Reduce例子
總結
HDFS
儲存模型:切塊;散列->分治
目的:分佈式計算
實現:角色NN,DN
重點:讀寫流程
MapReduce
計算模型(批量計算)
2階段
map:單條記錄加工處理
reduce:多條記錄加工處理
實現
JobTracker (做決策)
TaskTracker
Client
角色實現具體流程
Client:會根據每次計算數據查詢NameNode元數據block計算出切片,做出規劃得到切片清單。最後真正數據放哪還是JobTracker決策
JobTracker:
1 啓動後從HDFS中讀取split切片清單
2 根據自己收到的TaskTracker(有心跳)回報資源,最終確定每一個切片對應的map去哪個節點(確定最終清單)
3 TaskTracker心跳時取回分配給自己任務信心執行
TaskTracker (在DataNode下)
1 心跳取到任務
2 從HDFS下載jar.xml等到本機
3 最終啓動任務描述中的map和reduce任務
代碼從某一個節點啓動,通過客戶端上傳初步決策,JobTracker最終決策,TaskTracker下載執行計算
問題
JobTracker
1 單點故障
2 壓力過大
3 集成資源管理任務調度,未來新計算框架不能複用資源管理(互相不能感知,資源爭搶,如2個隔離JobTracker就無法調度)
Yarn誕生了,解決了所有這些問題
Yarn
跳過一大段複雜具體細節,直接簡單總結
每個節點都有一個Application Master(有資源調度能力,但是沒有資源管理能力)。
Resource Manager選出一個Application Master幫他分析用哪個container執行
然後RM來具體要求container從HDFS下載jar.xml並啓動map reduce任務
Resource Manager是主節點,NodeManager從節點,NodeManager包含Container和Application master
TaskTracker類似container,JobTracker類似Application master,然後Resource Manager統顧所有
Resource Manager主從則需要用Zookeeper。Yarn會RM進程中加入HA,Zookeeper自動連接不用再配置
Yarn和HDFS互相獨立不衝突。
Yarn搭建
mapred-site.xml配置yarn,表示要用yarn而不是單機
yarn-site.xml配置
<name>nodemanager</name>
<value>mapreduce_shuffle</value>
配置ResourceManager設成true,Zookeeper,集羣id和集羣物理映射
start-yarn.sh啓動yarn
測試wordcount(cd到mapreduce目錄下)
jar hadoop xx.jar wordcount 輸入path 輸出path
Eclipse下
寫代碼表面類似單機運行,底層分佈式運行
resource下配置mapred-site.xml/yarn-site.xml
~WordCount~{
Configuration conf = new Configuration(true);
Job job = Job.getInstance(conf);
job.setJarByClass(WordCount.class);
//輸入文件路徑 job.setInputPath();
//輸出文件路徑 job.setOutputPath();
Path infile = new Path(~由參數動態寫入) //現在使用方法
TestInputFormat.addInputPath(job.infile);
Path outfile = new Path(~由參數動態寫入)
TestInputFormat.addOutputPath(job.outfile);
job.setMapperClass(mapper.class);//map邏輯
job.setMapOutputKeyClass(Text.class); //告訴map key是什麼類型
job.setReduceClass(reduce.class);//reduce邏輯
job.waitForCompletion(true);
}
實現map.class和reduce.class邏輯
public class mapper extends Mapper<Object,Text,Text,IntWritable>{
//hadoop有一套自己的序列化,反序列化
//也可以自己開發序列化,反序列化
private Text word = new Text();
public void map(Object key, Text value,Context context){
//Object key每一行字符串第一個字節面向源文件的偏移量
//Text value真正字符串
//寫入map業務邏輯,通過前面具體Map_Reduce例子筆記圖
}
}
public class reduce extends Reducer~{
~
~reduce~{
//寫入reduce業務邏輯,通過前面具體Map_Reduce例子筆記圖
}
}