資料來源:
網絡資源/《Hadoop權威指南》
hadoop i/o 操作:
1.資料完整性:
datanode在接收到資料的時候會校驗資料完整性,比如CRC-32,datanode在接受client資料或者複制其他datanode的資料時會驗證資料完整性。
正在寫資料的client會将資料和校驗和發送到datanode管線,最後一個datanode來負責校驗資料完整性
client接收到datanode的資料塊之後,會校驗資料和,并将驗證結果傳回datanode,datanode會持久化校驗日志,每次client驗證之後,會更新校驗日志,儲存這些資訊,有利于檢測磁盤損壞。
datanode會背景運作一個檢測線程,用于檢測datanode上的block是否損壞。
用戶端校驗使用LocalFileSystem,LocalFileSystem使用CheckSumFileSystem
2.壓縮
資料壓縮算法是否支援切分,如果不支援切分,在map任務階段,會存在更多的節點間的資料傳輸
mapreduce結果和map結果支援壓縮
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9UlaNVTQq5UMNRVT3V1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jM0EzNzYjM2ETOwcDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
3.序列化
mapreduce中使用序列化可以使用實作writable接口的類,基本類型和資料類型都已經支援了
或者使用序列化架構,比如avro
others:
string和text的差別:text是Hadoop 中繼承writable借口的,跟string對應的類型,不同的是string存儲的是char而text是utf-8編碼的位元組數組,string 不可變
如果遇到複雜的資料類型,最好不要類型套用,因為序列化速度會變慢,最好自己實作writable接口
4.sequenceFile
sequenceFile存儲鍵值對,可以從任意位置讀取,因為存儲檔案中包含了同步辨別
壓縮方式存儲,隻壓縮value 不壓縮key
mapfile: 可以按照鍵來擷取值,将key進行劃分存放到多個sequenceFile中,value是一個sequenceFile,但是資料的添加必須按照key順序進行添加,bloomMapfile 是一個包含布隆過濾器的mapfile,适合稀疏資料。
5.mapreduce
hdfs可是設定多個配置檔案,用于在不同的環境下運作,用于區分測試和開發環境
寫程式,首先可以使用mrunit來編寫map和reduce的單元測試,然後實作tool接口,編寫一個測試驅動程式完成的進行流程測試
mapreduce 送出運作過程
mr的流程排程架構,jobcontrol和ooize,jobcontrol相當于用戶端,而ooize是一個伺服器的角色, 而且支援控制流。
job送出涉及元件:用戶端client、yarn資料總管、yarn節點管理器、application master和分布式檔案系統
MapReduce任務submit過程:
1).用戶端runjob
2).用戶端想資料總管申請應用ID,并檢查輸出檔案路徑正确性,計算資料分片,失敗,不送出job
3).用戶端将運作需要的jar包和輸入切片等資訊儲存到共享檔案系統中
4).然後調用submitApplication
5).資料總管向yarn排程器請求一個運作容器,在該容器所在節點的節點管理器的幫助下,啟動應用的master程序
6).Master程序會決定該任務是Uber任務還是分布式任務,如果是Uber任務,就在同一節點上運作應用程式
7).如果是分布式的程式,Master會幫助map和reduce任務向資料總管請求運作容器,一般5%左右的map任務完成之後
才會有reduce的請求,map任務運作盡量本地化,reduce可以在任意節點上
8).運作容器配置設定之後Master會與容器的nodeManager,通訊,啟動運作容器,然後進行本次任務運作資源的本地化,jar包等資源
9).容器運作應用任務
任務失敗的情況:
1)任務失敗,在jvm退出之前,想application master彙報,然後退出
2)任務失敗,jvm崩潰,節點管理器會發現該任務的jvm異常退出,節點管理器向application master彙報
3)任務逾時沒有向application master彙報,application master标記該任務失敗,通知節點管理器将該任務的JVM kill
application master失敗:
資料總管會尋找尋找新的容器,重新運作application master,新的application可是使用已經計算好的結果,不必重新計算
節點管理器失敗:
1)心跳資訊發送逾時,資料總管會将application和task轉移到其他節點
2)節點上運作的任務失敗次數過多,進入黑名單,但是黑名單在多個application之間是不共享的
資料總管失敗:
單點故障問題,一般使用zookeeper來搭建HA系統
Shuffle:
https://www.cnblogs.com/felixzh/p/4680808.html
map端的過程:計算輸出->buffer in mem->溢出寫到磁盤->合并所有的溢出檔案
a. 計算輸出,将輸出寫入緩沖區中,序列化成位元組數組,在寫入緩沖區的過程中會按照key擷取partition資訊,由哪個reducer來處理
b.緩沖區達到門檻值(一般為80%),會啟動另外一個線程,向磁盤中輸出臨時檔案,剩餘20%的緩沖空間,由另外的一個線程
繼續輸出,互不影響。在溢出的過程中,會對資料進行sort和merge,字典排序,相同key的值,會被合并,如果設定了
combiner,則會對值進行處理。
c.不管中間過程中是否會溢出臨時檔案,最後一步都是合并檔案,確定有序和單一key值
可以使用計數器來判斷溢出到磁盤的數量次數
map相關優化:
HDFS block和spile切片的差別,通過控制minSize(切片的最小大小)和HDFS blocksize,可以控制map數量,分兩種情況:
檔案大,不是小檔案,增大splite的minSize,減少maper的數量
檔案大,小檔案,使用CombineFileInputFormat将input path合并減少mapper的數量
reduce:
多線程拷貝map的結果,并進行合并排序,分趟多次進行合并,合并之後,傳給reduce函數
3種合并方式:記憶體->記憶體 記憶體->磁盤 磁盤->磁盤
第二種方式,類似溢出,隻要mapper階段沒有結束,第二種方式就一直存在
第三種方式,是最後所有的資料接收完畢之後,merge所有的資料
最後給reducer的輸入結果,可能在記憶體中,可能在磁盤中
reducer階段優化:
中間結果壓縮
mapreduce 并行度決定因素:
maptask的并行數目是由輸入資料的邏輯切片split來決定的,邏輯切片的大小由多個因素共同決定
splitSize=max{minSize,min{maxSize,blockSize}}
minSize.maxSize 是對邏輯切邊設定的大小,block是對HDFS塊的大小
當minsize大于blocksize的時候,起作用
maxsize當小于blocksize的時候,起作用
Combiner作用:
合并<key,value>,減少資料傳輸量
針對spill的臨時檔案進行combine,當臨時檔案數量達到min.num.spill.for.combine,combiner就會在merge之前執行,否則會在merger之後執行,有時候還會因為負載問題,不執行
MapReduce排序:
自動排序規則和自定義排序:https://blog.csdn.net/yongh701/article/details/50601319
次排序、分區、排序、分組:https://www.cnblogs.com/datacloud/p/3584640.html
全排序:https://www.iteblog.com/archives/2147.html、https://www.iteblog.com/archives/2146.html
輸入壓縮:
http://www.cnblogs.com/yurunmiao/p/4528499.html
對于容器型的資料檔案格式,avro,sequence file,parquet 等,選擇一個快速的壓縮算法即可,LZO、LZ4、Snappy
其他的可以選擇支援切分的壓縮算法,bzip2
大檔案不能選擇不支援切分的壓縮算法
預設的MapReduce類型
預設的mapper将輸入原封不動的寫到輸出,泛型類型,是以沒有輸入類型限制
預設的partitioner是hash partitionrer,分區數目根據reducer來設定
預設的reducer是一個,把輸入寫到輸出
分片計算:
在步驟3的時候,用戶端盡進行計算分片,然後application master使用了分片的引用,引用包含了分片的位址和位元組長度,位址是為了排程map任務到資料節點上,包含有位元組長度是因為application master會優先盡心大的分片計算,貪婪算法
任務分到到map的時候,在傳遞給mapper函數的之前,會将分片的引用資訊傳遞給InputFormat的實作類,擷取一個reader(疊代器),然後mapper函數會使用這個疊代器擷取每一條記錄
MapReduce資料輸入
InputFormat實作類如下:
FileInputFormat、TextInputFormat、SequenceInputFormat、DBInputFormat
DBInputFormat使用小心,過多的mapper可能導緻資料庫崩潰,最好使用sqoop現将資料導出轉入HDFS或者分布式資料庫
Hbase對應的是TableInputFormat
多個輸入:MultipleInputs可以為不同的輸入路徑指定不同的mapper,但是需要確定mapper輸出一緻
格式相同,下面的函數,格式不同需要指定不同的mapper,上面的函數
MapReduce資料輸出
文本輸出:TextOutputFormat
二進制數出:SequenceFileOutputormat 如果該輸出接下來會被其他的MapReduce程式使用,可選,結構緊湊
多個輸出:(鍵、值、檔案名稱和辨別)
延遲輸出:LazyOutputFormat 防止輸出空檔案,等輸出第一條資料的時候才建立檔案
MapReduce 計數器
mapreduce 使用枚舉來做計數器的聲明
Join
reduce端的join,shuffle傳輸資料量大,reduce端,占用記憶體大,容易oom
map端的join(https://blog.csdn.net/huashetianzu/article/details/7821674),使用DistributeCache,調用addlocalfile方法,
JobTracker在作業啟動之前會擷取這個URI清單,并将相應的檔案拷貝到各個TaskTracker的本地磁盤上,使用者使用
DistributedCache.getLocalCacheFiles()方法擷取檔案目錄,并使用标準的檔案讀寫API讀取相應的檔案。
https://blog.csdn.net/huashetianzu/article/details/7821674
semi join ,縮減mapper到reducer的資料傳輸量
reducer side map + bloom filter