溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Hbase寫數(shù)據(jù)和存數(shù)據(jù)的過程

發(fā)布時間:2021-08-18 21:15:16 來源:億速云 閱讀:122 作者:chen 欄目:云計算

這篇文章主要講解了“Hbase寫數(shù)據(jù)和存數(shù)據(jù)的過程”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Hbase寫數(shù)據(jù)和存數(shù)據(jù)的過程”吧!

Hbase寫數(shù)據(jù)和存數(shù)據(jù)的過程

Client寫入 -> 存入MemStore,一直到MemStore滿 -> Flush成一個StoreFile,直至增長到一定閾值 -> 出發(fā)Compact合并操作 -> 多個StoreFile合并成一個StoreFile,同時進行版本合并和數(shù)據(jù)刪除 -> 當(dāng)StoreFiles Compact后,逐步形成越來越大的StoreFile -> 單個StoreFile大小超過一定閾值后,觸發(fā)Split操作,把當(dāng)前Region Split成2個Region,Region會下線,新Split出的2個孩子Region會被HMaster分配到相應(yīng)的HRegionServer 上,使得原先1個Region的壓力得以分流到2個Region上由此過程可知,HBase只是增加數(shù)據(jù),有所得更新和刪除操作,都是在Compact階段做的,所以,用戶寫操作只需要進入到內(nèi)存即可立即返回,從而保證I/O高性能。

對上述流程的補充:
補充1:HStore存儲是HBase存儲的核心,其中由兩部分組成,一部分是MemStore,一部分是StoreFiles。

補充2:HLog的功能:

在分布式系統(tǒng)環(huán)境中,無法避免系統(tǒng)出錯或者宕機,一旦HRegionServer以外退出,

MemStore中的內(nèi)存數(shù)據(jù)就會丟失,引入HLog就是防止這種情況。

工作機制:每 個HRegionServer中都會有一個HLog對象,HLog是一個實現(xiàn)Write Ahead Log的類,每次用戶操作寫入Memstore的同時,也會寫一份數(shù)據(jù)到HLog文件,HLog文件定期會滾動出新,并刪除舊的文件(已持久化到 StoreFile中的數(shù)據(jù))。當(dāng)HRegionServer意外終止后,HMaster會通過Zookeeper感知,HMaster首先處理遺留的 HLog文件,將不同region的log數(shù)據(jù)拆分,分別放到相應(yīng)region目錄下,然后再將失效的region(帶有剛剛拆分的log)重新分配,領(lǐng)取到這些region的 HRegionServer在Load Region的過程中,會發(fā)現(xiàn)有歷史HLog需要處理,因此會Replay HLog中的數(shù)據(jù)到MemStore中,然后flush到StoreFiles,完成數(shù)據(jù)恢復(fù)。

補充3:Region就是StoreFiles,StoreFiles里由HFile構(gòu)成,Hfile里由hbase的data塊構(gòu)成,一個data塊里面又有很多keyvalue對,每個keyvalue里存了我們需要的值。

補充4:

我們觀察上面這一幅圖:

一 張表,有兩個列族(紅顏色的一個,黃顏色的一個),一個列族有兩個列,從圖中可以看出,這就是列式數(shù)據(jù)庫的最大特點,同一個列族的數(shù)據(jù)在在一起的,我們還 發(fā)現(xiàn)如果是有多個版本,同時也會存多個版本。最后我們還發(fā)現(xiàn)里面存了這樣的值:r1:鍵值,cf1:列族的名字,c1:列明。t1:版本號,value值 (最后一幅圖說明的是value值可以存放的位置)。通過這樣的看法,我們發(fā)現(xiàn)如果我們設(shè)計表的時候把這幾個東西:r1:鍵值,cf1:列族的名 字,c1:列明的名字取短一點是不是我們會省出好多存儲的空間!

還有,我們從這一幅圖中還應(yīng)該得到這樣的認(rèn)識:

我 們看倒數(shù)第二張圖,字段篩選的效率從左到右明顯下降,所以在keyvalue的設(shè)計時用戶可以考慮把一些重要的篩選信息左移到合適的位置,從而在不改變數(shù) 據(jù)量的情況下,提高查詢性能。那么簡單的說就是用戶應(yīng)當(dāng)盡量把查詢維度或信息存儲在行健中,因為它篩選數(shù)據(jù)的效率最高。

得到上面的認(rèn)識后,我們應(yīng)該還要會有這樣的覺悟:

HBase 的數(shù)據(jù)存儲時會被有順序的存儲到一個特定的范圍,因為我們存儲的時候一般都是按順序的,所以會一直存到同一個region上,由于一個region只能由 一個服務(wù)器管理,這樣我們老是添加到同一個region上,會造成讀寫熱點,從而使集群性能下降。那么解決這個的辦法還是有的,我能想到的就是,比如我們 有9臺服務(wù)器,那么我們就回去當(dāng)前時間,然后摸9,加到行健前綴,這樣就會被平均的分到不同的region服務(wù)器上了,這樣帶來的好處是,因為相連的數(shù)據(jù) 都分布到不同的服務(wù)器上了,用戶可以多線程并行的讀取數(shù)據(jù),這樣查詢的吞吐量會提高。

關(guān)于我們版本的控制,我們要么就讓多臺服務(wù)器上的時間都同步,要么干脆就在put插入數(shù)據(jù)的時候,就設(shè)置一個客戶端的時間戳來代替。(因為我們要是不顯示的添加,人家就給我們在自己的服務(wù)器上添加了自己的時間了。)

補充5:

設(shè) 計表的時候,有兩種設(shè)計方式,一種是高表設(shè)計,一種是胖表設(shè)計。根據(jù)HBase的拆分規(guī)則,我們的高表設(shè)計更容易拆分(使用組合鍵),不過,如果我們設(shè)計 成胖表,而我們的這個胖里的數(shù)據(jù)需要經(jīng)常修改,這樣設(shè)計是很合理的,因為我們的HBase保證了行級的原子性,如果設(shè)計成高表,反而就不合適了,因為不能 保證跨行的原子性。

補充6:

寫緩存

每 一個put的操作實際上是RPC的操作,它將客戶端的數(shù)據(jù)傳送到服務(wù)器然后返回,這只適合小數(shù)據(jù)量的操作,如果有個應(yīng)用程序需要每秒存儲上千行數(shù)據(jù)到 HBase表中,這樣處理就不太合適了。HBase的API配備了一個客戶端的寫緩沖區(qū),緩沖區(qū)負責(zé)收集put操作,然后調(diào)用RPC操作一次性將put送 往服務(wù)器。默認(rèn)情況下,客戶端緩沖區(qū)是禁止的。可以通過自動刷寫設(shè)置為FALSE來激活緩沖區(qū)。 table.setAutoFlush(false);void flushCommits () throws IOException這個方法是強制 將數(shù)據(jù)寫到服務(wù)器。用戶還可以根據(jù)下面的方法來配置客戶端寫緩沖區(qū)的大小。 void setWritaeBufferSize(long writeBufferSize) throws IOException;默認(rèn)大小是 2MB,這個也是適中的,一般用戶插入的數(shù)據(jù)不大,不過如果你插入的數(shù)據(jù)大的話,可能要考慮增大這個值。從而允許客戶端更高效地一定數(shù)量的數(shù)據(jù)組成一組通 過一次RPC請求來執(zhí)行。給每個用戶的HTable設(shè)置一個寫緩沖區(qū)也是一件麻煩的事,為了避免麻煩,用戶可以在

Hbase-site.xml中給用戶設(shè)置一個較大的預(yù)設(shè)值。

<property>

<name>hbase.client.write.buffer</name>

<value>20971520</value>

</property>

補充7:

hbase支持大量的算法,并且支持列族級別以上的壓縮算法,除非有特殊原因,不然我們應(yīng)該盡量使用壓縮,壓縮通常會帶來較好的 性能。通過一些測試,我們推薦使用SNAPPY這種算法來進行我們hbase的壓縮。

Hbase讀數(shù)據(jù):
client->zookeeper->.ROOT->.META-> 用戶數(shù)據(jù)表zookeeper記錄了.ROOT的路徑信息(root只有一個region),.ROOT里記錄了.META的region信息, (.META可能有多個region),.META里面記錄了region的信息。

補充1:

在 HBase中,所有的存儲文件都被劃分成了若干個小存儲塊,這些小存儲塊在get或scan操作時會加載到內(nèi)存中,他們類似于RDBMS中的存儲單元頁。 這個參數(shù)的默認(rèn)大小是64K。通過以上方式設(shè)置:void setBlocksize(int s);(HBase中Hfile的默認(rèn)大小就是64K跟 HDFS的塊是64M沒關(guān)系)HBase順序地讀取一個數(shù)據(jù)塊到內(nèi)存緩存中,其讀取相鄰的數(shù)據(jù)時就可以再內(nèi)存中讀取而不需要從磁盤中再次讀取,有效地減少 了磁盤I/O的次數(shù)。這個參數(shù)默認(rèn)為TRUE,這意味著每次讀取的塊都會緩存到內(nèi)存中。但是,如果用戶順序讀取某個特定的列族,最好將這個屬性設(shè)置為 FALSE,從而禁止使用緩存快。上面這樣描述的原因:如果我們訪問特定的列族,但是我們還是啟用了這個功能,這個時候我們的機制會把我們其它不需要的列 族的數(shù)據(jù)也加載到了內(nèi)存中,增加了我們的負擔(dān),我們使用的條件是,我們獲取相鄰數(shù)據(jù)。 void setBlockCacheEnabled(boolean blockCacheEnable);

補充2:

1:禁止自動刷寫。

我們有大批數(shù)據(jù)要插入時,如果我們沒有禁止,Put實例會被逐個的傳送到regio服務(wù)器

,如果用戶禁止了自動刷寫的功能,put操作會在寫緩沖區(qū)被填滿時才會被送出。

2:使用掃描緩存。

如果HBase被用作一個mapreduce作業(yè)的輸入源,請最好將作為mapreduce作業(yè)輸入掃描

器實例的緩存用setCaching()方法設(shè)置為比默認(rèn)值1更大的數(shù)。使用默認(rèn)值意味著map

任務(wù)會在處理每條記錄時都請求region服務(wù)器。不過,這個值要是500的話,則一次

可傳送500條數(shù)據(jù)到客戶端進行處理,當(dāng)然了這數(shù)據(jù)也是根據(jù)你的情況定的。

這個是行級的,在我們的119頁有說明。

3:限定掃描范圍。

這個是很好理解的,比如我們要處理大量行(特別是作為mapreduce的輸入源),其中

用到scan的時候我們有Scan.addFamily();的方法,這個時候我們?nèi)绻皇切枰?/p>

這個列族中的幾個列,那么我們一定要精確。因為過多的列會導(dǎo)致效率的損失。

4:關(guān)閉resultScanner

當(dāng)然了這個不能提高我們的效率,但是如果沒關(guān)就會對效率有影響。

5:塊緩存的用法

首先我們的塊緩存是通過Scan.setCacheBolcks();的啟動的,那些被頻繁訪問的行

我們應(yīng)該使用緩存塊,但是mapreduce作業(yè)使用掃描大量的行,我們就不該使用這個

了。(這個塊緩存跟我在第四節(jié)中提到的那個塊是不一樣的)。

6:優(yōu)化獲取行健的方式

當(dāng)然用這個的前提是,我們只需要表中的行健時,才能用。那么怎么用在411頁有說明。

7:關(guān)閉Put上的WAL

書上是這么說,但是我個人覺得這個功能還是不用的好,因為我們關(guān)閉了這個功能,

服務(wù)器就不會把put寫入到WAL,而是直接寫到memstore里,這樣一旦服務(wù)器出現(xiàn)故障

我們的數(shù)據(jù)就丟失了。

感謝各位的閱讀,以上就是“Hbase寫數(shù)據(jù)和存數(shù)據(jù)的過程”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Hbase寫數(shù)據(jù)和存數(shù)據(jù)的過程這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI