在hdfs上面最不明確的事情之一就是資料的冗餘。它完全是自動進行的,因為無法得知其中詳細的資訊,我們需要做的就是相信它。hbase完全相信hdfs儲存資料的安全性和完整性,並將資料檔案交給hdfs儲存。正是因為hdfs的資料冗餘方式對於hbase來說是完全透明的,產生了乙個問題:hbase的效率會受到多大的影響?說的簡單一點,當hbase需要訪問資料時,如何保證有乙份冗餘的資料塊離自己最近?當我們對hbase做一次mapreduce的掃瞄操作時,這個問題尤其顯現出來。所有的regionserver都在從hdfs上面讀取資料,理想的狀況當然是每個regionserver要讀取的資料都離自己很近。這個問題就牽扯到hbase的資料檔案是如何在hdfs上面儲存的。
讓我們回到hbase,現在你已經理解了hadoop是如何保證在mapreduce的過程中每個task都盡量處理本地資料。如果你看過hbase的儲存架構你就會知道hbase只是簡單的將hfile和wal log儲存在hdfs上面。通過簡單的呼叫hdfs的api來建立檔案:filesystem.create(path path)。接下來你會關心兩件事情的效率:1)隨機的訪問 2)通過mapreduce掃瞄全表。我們當然希望當每個regionserver讀取資料時儲存資料的資料塊就在本地。它能做到嗎?
第一種情況,你有兩個集群,乙個集群裝hadoop,另乙個集群裝hbase,兩個集群是分隔開的,只有網線來傳輸資料。好了,討論到此為止,神也幫不了你。
第二種情況,你有乙個大的集群,每台機器都混裝了hadoop和hbase,每個regionserver上面都有乙個datanode(這是我們最希望看到的)。好,這樣的話regionserver就具備了從本地讀取資料的前提。我們還剩下乙個問題,如何保證每個regionserver管理的region所對應的hfile和wal log就存在本地的datanode上面?設想一種情況,你對hbase建立了大量的資料,每個regionserver都管理了各自的region,這時你重啟了hbase,重啟了所有的regionserver,所有的region都會被隨機的分配給各個regionserver,這種情況下你顯然無法保證我們希望的本地資料儲存。
在討論如何解決這個問題之前我們先強調一點:hbase不應該頻繁的被重啟,並且部署的架構不應該被頻繁的改變,這是能解決這個問題的乙個基礎。寫入hdfs的檔案都有乙個特點,一旦寫入乙個檔案就無法更改(由於種種原因)。因此hbase會定期的將資料寫入hdfs中並生成乙個新檔案。這裡有乙個讓人驚奇的地方:hdfs足夠聰明,它知道如何將檔案寫到最合適的地方。換句話說,它知道把檔案放到什麼地方使得regionserver用起來最方便。如果想知道hdfs如何做到這一點,我們需要深入學習hadoop的源**,看看前面提到的filesystem.create(path path) 具體是怎麼工作的。
在hdfs中實際呼叫的函式是:distributedfilesystem.create(path path), 他看起來是這個樣子的:
public fsdataoutputstream create(path f) throws ioexception else if (newblock) else catch (notenoughreplica***ception e) {
fsnamesystem.log.warn("not able to place enough replicas, still in need of " + numofreplicas);
return writer;
這段**很清楚的說明了整個的選擇過程,namenode總是為第乙份冗餘優先選擇本地節點作為儲存空間,對於第二份冗餘,則是優先選擇另乙個機架的節點。如果前兩份冗餘位於不同機架,第三份冗餘偏向於選擇與第乙份冗餘相同的機架,否則選擇不同的機架。大於三份的冗餘就聽天由命,隨機挑選節點了。
總結一下,基於當前的情況,每個region server執行的時間越長,那麼資料的儲存地點就越穩定,每個region server就能保證它要管理的資料在本地就有乙份拷貝。這樣無論是scan還是mapreduce都能達到效率的最優化。
最後要說的是hbase team正在致力於重新設計masterserver分配region的機制。新的設計能夠盡量保證每個region被分配給擁有最多region block的region server。這將能夠部分解決重啟regionserver所帶來的問題。
查詢指定的物件在那些資料庫中存在
create proc find object object name varchar 100 xtype varchar 2 as object name 物件名 xtype 物件的型別 物件型別。可以是下列物件型別中的一種 c check 約束 d 預設值或 default 約束 f forei...
查詢指定的表在那些資料庫中存在
查詢指定的表在那些資料庫中存在 declare tbname sysname set tbname 客戶資料 declare dbname sysname,sql nvarchar 4000 re bit,sql1 varchar 8000 set sql1 declare tb cursor fo...
查詢指定的表在那些資料庫中存在
查詢指定的表在那些資料庫中存在 declare tbname sysname set tbname 客戶資料 declare dbname sysname,sql nvarchar 4000 re bit,sql1 varchar 8000 set sql1 declare tb cursor fo...