亞寵展、全球寵物產業風向標——亞洲寵物展覽會深度解析
942
2025-04-03
3.6.3? 一致模型
文件系統的一致模型(coherency model)描述了文件讀/寫的數據可見性。HDFS為性能犧牲了一些POSIX 要求,因此一些操作與你期望的可能不同。
新建一個文件之后,它能在文件系統的命名空間中立即可見,如下所示:
Path p = new Path("p");
Fs.create(p);
assertThat(fs.exists(p),is(true));
但是,寫入文件的內容并不保證能立即可見,即使數據流已經刷新并存儲。所以文件長度顯示為0:
Path p = new Path("p");
OutputStream out = fs.create(p);
out.write("content".getBytes("UTF-8"));
out.flush();
assertThat(fs.getFileStatus(p).getLen(),is(0L));
當寫入的數據超過一個塊后,第一個數據塊對新的reader就是可見的。之后的塊也不例外。總之,當前正在寫入的塊對其他reader不可見。
HDFS提供了一種強行將所有緩存刷新到datanode中的手段,即對FSDataOutputStream調用hflush()方法。當hflush ()方法返回成功后,對所有新的reader而言,HDFS能保證文件中到目前為止寫入的數據均到達所有datanode的寫入管道并且對所有新的reader均可見:
Path p = new Path("p");
FSDataOutputStream out = fs.create(p);
out.write("content".getBytes("UTF-8"));
out.hflush();
assertThat(fs.getFileStatus(p).getLen(), is(((long) "content".length())));
注意,hflush()不保證datanode已經將數據寫到磁盤上,僅確保數據在datanode的內存中(因此,如果數據中心斷電,數據會丟失)。為確保數據寫入到磁盤上,可以用hsync()替代[1]。
hsync()操作類似于POSIX中的fsync()系統調用,該調用提交的是一個文件描述符的緩沖數據。例如,利用標準Java API數據寫入本地文件,我們能夠在刷新數據流且同步之后看到文件內容:
FileOutputStream out = new FileOutputStream(localFile);
out.write("content".getBytes("UTF-8"));
out.flush(); // flush to operating system
out.getFD().sync(); // sync to disk
assertThat(localFile.length(), is(((long) "content".length())));
在HDFS中關閉文件其實隱含了執行hflush()方法:
Path p = new Path("p");
OutputStream out = fs.create(p);
out.write("content".getBytes("UTF-8"));
out.close();
assertThat(fs.getFileStatus(p).getLen(), is(((long) "content".length())));
這個一致模型和設計應用程序的具體方法息息相關。如果不調用hflush()或hsync()方法,就要準備好在客戶端或系統發生故障時可能會丟失數據塊。對很多應用來說,這是不可接受的,所以需要在適當的地方調用hflush()方法,例如在寫入一定的記錄或字節之后。盡管hflush()操作被設計成盡量減少HDFS負載,但它有許多額外的開銷(hsync()的開銷更大),所以在數據魯棒性和吞吐量之間就會有所取舍。怎樣權衡與具體的應用相關,通過度量應用程序以不同頻率調用hflush()或hsync()時呈現出的性能,最終選擇一個合適的調用頻率。
Hadoop 存儲 大數據
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。