注:本文涉及書中3.6小結
數據流
1. 文件讀取
結合上圖,客戶端通過調用FileSystem對象的open()方法來打開希望讀取的文件
step1. DistributedFileSystem通過使用RPC來調用namenode,以確定文件的起始塊的位置。
注:RPC是遠程過程調用(Remote Procedure Call)是一個計算機通信協議。 該協議允許運行于一臺計算機的程序調用另一臺計算機的子程序,而程序員無需額外地為這個交互作用編程。
step2. 對于每一個塊,那么namenode返回存有該塊副本的datanode地址,這些datanode根據它們與客戶端的距離來排序。
(注:Hadoop中的網絡距離,詳見本書3.6.1小節的圖3-3)
step3.?DistributedFileSystem類返回一個FSDataInputStream對象給客戶端并讀取數據,客戶端對這個輸入流調用read()方法。
step4. 通過對數據流反復調用read()方法,可以將數據從datanode傳輸到客戶端。
step5. 到達塊的末端時,DFSInputStream關閉與該datanode的連接,然后尋找下一個塊的最佳datanode。也就是說不斷的讀入連續的塊。
step6. 客戶端讀取完畢,對FSDataInputStream調用close()方法。
2. 文件寫入
step1.?客戶端通過對DistributedFileSystem對象調用create()方法來新建文件。
step2.?DistributedFileSystem對namenode創建一個RPC調用,在文件系統的命名空間中新建一個文件,此時該文件中還沒有相應的數據塊。
step3.?DistributedFileSystem向客戶端返回一個FSDataOutputStream對象,由此客戶端可以開始寫入數據。
step4. DFSOutputStream將數據分成一個個數據包,并寫入內部隊列,稱為“數據隊列”(data queue)。DataStreamer處理數據隊列,根據datanode列表要求namenode分配合適的新塊來存儲數據復本,這些datanode構成了一個管線。
step5.?DFSOutputStream維護一個內部數據包隊列來等待datanode的收到確認回執,稱為“確認隊列”(ack queue)。收到管道中所有datanode確認信息后,該數據包才會從確認隊列刪除。
step6. 客戶端完成數據寫入,對數據流調用close()方法。
step7. 等待namenode收到文件寫入完成的信號。
3. 一致模型
文件系統的一致模型(coherency model)描述了文件讀/寫的數據可見性。
Hadoop1.x中,HDFS通過對FSDataOutputStream調用sync()方法,來使所有緩存與數據節點強行同步。
Hadoop2.x中,用hflush()替代了sync(),且增加了hsync()
sync()可以防止故障時丟失數據,但會增加很多額外的開銷,需要在數據魯棒性和吞吐量之間進行權衡,所以設置sync()的調用頻率。