HDFS中hsync方法介紹


HDFS中hsync方法介紹

原創文章,轉載請注明:博客園aprogramer

原文鏈接:HDFS中hsync方法介紹

1. 背景介紹 

HDFS在寫數據務必要保證數據的一致性與持久性,從HDFS最初的版本到2.0版本HDFS提供了兩種同步語義。 
1. 將client端寫入的數據刷到每個DataNode的OS緩存中,如果每個副本所在的DataNode同時crash時(例如機房斷電)就會導致數據丟失(sync和hflush方法)。
2. 將client端寫入的數據刷到每個DataNode的磁盤中(hsync方法); 
在Hadoop2.0和cdh4中DFSOutputStream提供了sync,hflush和hsync三個方法,sync和hflush均是語義1,而hsync是語義2,hsync比sync和hflush的同步性更強,下面詳細介紹hsync。 

2. Hadoop2.0中hsync的語義

hsync的語義是:client端所有的數據都發送到副本的每個datanode上,並且datanode上的每個副本都完成了posix中fsync的調用,也就是說操作系統已經把數據刷到磁盤上(當然磁盤也可能緩沖數據);需要注意的是當調用fsync時只有當前的block會刷到磁盤中,要想每個block都刷到磁盤,必須在創建流時傳入Sync標示。 
通過分析上面的語義,可以確定hsyn涉及到兩個角色client和DataNode,下面分別說明這兩個角色。

3. DFSClient端邏輯

DFSClient端邏輯主要包括以下幾步:

1. 判斷是否需要sync,如果當前的數據都已經sync到磁盤了,則不需要再次sync;判斷方法是首先調用flushBuffer(true),如果byteCurBlock(當前block的最后一個字節在file中的偏移量)大於上次sync的偏移量,則說明需要sync,否則不需要;
2. 如果需要sync,則將當前package的sync標示設為true;
3. 調用waitAndQueueCurrentPacket()將當前Package放到發送隊列中
4. waitForAckedSeqno()等待發送package的確認包
5. 如果當前block沒有調用namenode.fsync(),則調用該方法,持久化block元數據
6. 調用streamer.setHflush();
client端的時序圖如下所示
 
查看大圖:大圖

4.DataNode端處理邏輯

DataNode端的改動比較簡單,當接收的package的有sync標示,則執行flushOrSync 方法 (通過調用FileChannel的force方法,force方法會保證將文件內容刷到磁盤中)將block文件及meta文件刷到磁盤。序列圖如下:
 
查看大圖:大圖

5. 性能分析及改進

由於調用hsync會比較耗時,將來可優化的方向:

1. 不是每個副本的DataNode都執行hsync,只有一個DataNode執行hsync;
2. 不同機架上的DataNode執行hsync;
3. hsync可同步進行,而不是等待hsync完成之后再返回給client端response(在這種情況下,client端的hsync方法的返回並不確保sync的完成,只有datanode端能保證)

6. 參考資料

[2]. Hadoop2.0代碼
[3]. https://issues.apache.org/jira/browse/HDFS-744  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM