HDFS只支持文件append操作, 而依賴HDFS的HBase如何完成數據的增刪改查


轉:http://www.th7.cn/db/nosql/201510/135382.shtml

 

1. HDFS的文件append功能

早期版本的HDFS不支持任何的文件更新操作,一旦一個文件創建、寫完數據、並關閉之后,這個文件就再也不能被改變了。為什么這么設計?是為了與MapReduce完美配合,MapReduce的工作模式是接受一系列輸入文件,經過map和reduce處理,直接產生一系列輸出文件,而不是在原來的輸入文件上做原位更新。為什么這么做?因為直接輸出新文件比原位更新一個舊文件高效的多。

       在HDFS上,一個文件一直到它的close方法成功執行之后才會存在,才能被其他的client端所看見。如果某個client端在寫文件時或者在close文件時失敗了,那么這個文件就不會存在,就好像這個文件從來沒寫過,唯一恢復這個文件的方法,就是從頭到尾重新再寫一遍。

       Hadoop1.x版本一直都不支持文件的append功能,一直到Hadoop 2.x版本,append 功能才被添加到Hadoop Core中,允許向HDFS文件中追加寫數據。為此,HDFS Core 也作出了一些重大的改變,以支持這一操作。append功能添加到HDFS經歷了一番曲折和一段很長的時間(具體可以參考http://blog.cloudera.com/blog/2009/07/file-appends-in-hdfs/和 https://issues.apache.org/jira/browse/HADOOP-8230)。

 

2. HBase 如何完成數據更新和刪除操作

       HBase依賴於HDFS來存儲數據。HBase作為數據庫,必須提供對HBase表中數據的增刪改查,而HDFS的文件只支持append操作、不支持刪除和更新操作,那么HBase如何依賴HDFS完成更新以及刪除操作呢??。

2.1 更新操作

       HBase表中的數據當存放到HDFS中時,在HDFS看來,已經可以簡單的理解成key-value對,其中key可以理解成是由:rowkey+column family+column qualifier+timestamp+type 組成。HBase 對新增的數據以及要更新的數據(理解成key-value對),都直接先寫入MemStore結構中,MemStore是完全的內存結構,且是key有序的。當MemStore達到一定大小后,該MemStore一次性從內存flush到HDFS中(磁盤中),生成一個HFile文件,HFile文件同樣是key有序的,並且是持久化的位於HDFS系統中的。通過這種機制,HBase對表的所有的插入和更新都轉換成對HDFS的HFile文件的創建。

       你可能會迅速的想到,那查詢怎么辦?

       是的,這種方式解決了插入和更新的問題,而查詢就變得相對麻煩。而這也正是HBase設計之初的想法:以查詢性能的下降來換取更新性能的提升。

       事實上查詢是如下來完成的。

       每當MemStore結構flush到HDFS上時,就會產生一個新的HFile文件,隨着時間的推移,會產生一連串的HFile文件,這些HFile文件產生的先后順序非常的重要,可以想象成他們按創建時間排成一個隊列,最近產生的在最前面,較早產生的在最后面。當HBase執行查詢操作時(可以理解為給出key,要找到value),首先查詢內存中的MemStroe結構,如果命中,就返回結果,因為MemStore中的數據永遠是最新的,如果不命中,就從前到后遍歷之前產生的HFile文件隊列,在每個HFile文件中查找key,看是否命中,如果命中即可返回(最新的數據排在最前面),如果不命中一直查找下去,直到所有HFile文件被搜索完結束。

由此可見,查詢操作最壞情況下可能要遍歷所有HFile文件,最好情況下在內存中MemStore即可命中,這也是為什么HBase查詢性能波動大的原因。當然HBase也不會真的很傻的去遍歷每個HFile文件中的內容,這個性能是無法忍受的,它采取了一些優化的措施:1、引入bloomfilter,對HFile中的key進行hash,當查詢時,對查詢key先過bloomfilter,看查詢key是否可能在該HFile中,如果可能在,則進入第2步,不在則直接跳過該HFile;2、還記得嗎?HFile是key有序的(具體實現是類SSTable結構),在有序的key上查找就有各種優化技術了,而不是單純的遍歷了。

通過以上機制,HBase很好的解決了插入和更新、以及查找的問題,但是問題還沒有結束。細心的朋友很可能已經看出來,上述過程中,HFile文件一直在產生,HFile文件組成的列表一直在增大,而計算機資源是有限的,並且查詢的性能也依賴HFile隊列的長度,因此我們還需要一種合並HFile文件的機制,以保持適度的HFile文件個數。HBase中實現這種機制采用的是LSM樹(一種NOSQL系統廣泛使用的結構),LSM能夠將多個內部key有序的小HFile文件合並生成一個大的HFile文件,當新的大的HFile文件生成后,HBase就能夠刪除原有的一系列舊的小的HFile文件,從而保持HFile隊列不至於過長,查詢操作也不至於查詢過多的HFile文件。在LSM合並HFile的時候,HBase還會做很重要的兩件事:1、將更新過的數據的舊版本的數據刪除掉,只留下最新的版本;2、將標有刪除標記(下面一節會講到)的數據刪除掉。

 

2.2 刪除操作

       有了以上機制,HBase完成刪除操作非常的簡單,對將要刪除的key-value對進行打標,通常是對key進行打標,將key中的type字段打標成“刪除”標記,並將打標后的數據append到MemStore中,MemStore再flush到HFile中,HFile合並時,檢查這個標記,所有帶有“刪除”標記的記錄將被刪除而不會合並到新的HFile中,這樣HBase就完成了數據的刪除操作。

 

3. HBase 的WAL

HBase的WAL(Write-Ahead-Log)機制是必須的,一個RegionServer通常與一個HLog一一對應,數據寫入Region之前先寫HLog能夠保障數據的安全。 HLog使用Hadoop的SequenceFile存儲日志,而HLog是一直連續不斷追加寫文件的,它強烈依賴SequenceFile的append功能。事實上正是HLog對append功能的強烈需求,或多或少推動了HDFS在最近的版本中添加了文件追加功能。


免責聲明!

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



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