第7章 HBase優化
7.1 高可用
在HBase中Hmaster負責監控RegionServer的生命週期,均衡RegionServer的負載,如果Hmaster掛掉了,那麼整個HBase叢集將陷入不健康的狀態,並且此時的工作狀態並不會維持太久。所以HBase支援對Hmaster的高可用配置。
1.關閉HBase叢集(如果沒有開啟則跳過此步)
[atguigu@hadoop102 hbase]$ bin/stop-hbase.sh
複製程式碼
2.在conf目錄下建立backup-masters檔案
[atguigu@hadoop102 hbase]$ touch conf/backup-masters
複製程式碼
3.在backup-masters檔案中配置高可用HMaster節點
[atguigu@hadoop102 hbase]$ echo hadoop103 > conf/backup-masters
複製程式碼
4.將整個conf目錄scp到其他節點
[atguigu@hadoop102 hbase]$ scp -r conf/ hadoop103:/opt/module/hbase/
[atguigu@hadoop102 hbase]$ scp -r conf/ hadoop104:/opt/module/hbase/
複製程式碼
5.開啟頁面測試檢視
7.2 預分割槽
每一個region維護著startRow與endRowKey,如果加入的資料符合某個region維護的rowKey範圍,則該資料交給這個region維護。那麼依照這個原則,我們可以將資料所要投放的分割槽提前大致的規劃好,以提高HBase效能。
1.手動設定預分割槽
hbase> create 'staff1','info','partition1',SPLITS => ['1000','2000','3000','4000']
複製程式碼
2.生成16進位制序列預分割槽
create 'staff2','info','partition2',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
複製程式碼
3.按照檔案中設定的規則預分割槽
#建立splits.txt檔案內容如下:
aaaa
bbbb
cccc
dddd
#然後執行:
create 'staff3','partition3',SPLITS_FILE => 'splits.txt'
複製程式碼
4.使用JavaAPI建立預分割槽
//自定義演算法,產生一系列Hash雜湊值儲存在二維陣列中
byte[][] splitKeys = 某個雜湊值函式
//建立HBaseAdmin例項
HBaseAdmin hAdmin = new HBaseAdmin(HBaseConfiguration.create());
//建立HTableDescriptor例項
HTableDescriptor tableDesc = new HTableDescriptor(tableName);
//通過HTableDescriptor例項和雜湊值二維陣列建立帶有預分割槽的HBase表
hAdmin.createTable(tableDesc, splitKeys);
複製程式碼
7.3 RowKey設計
一條資料的唯一標識就是rowkey,那麼這條資料儲存於哪個分割槽,取決於rowkey處於哪個一個預分割槽的區間內,設計rowkey的主要目的 ,就是讓資料均勻的分佈於所有的region中,在一定程度上防止資料傾斜。接下來我們就談一談rowkey常用的設計方案。
1.生成隨機數、hash、雜湊值
比如:
原本rowKey為1001的,SHA1後變成:dd01903921ea24941c26a48f2cec24e0bb0e8cc7
原本rowKey為3001的,SHA1後變成:49042c54de64a1e9bf0b33e00245660ef92dc7bd
原本rowKey為5001的,SHA1後變成:7b61dec07e02c188790670af43e717f0f46e8913
在做此操作之前,一般我們會選擇從資料集中抽取樣本,來決定什麼樣的rowKey來Hash後作為每個分割槽的臨界值
2.字串反轉
20170524000001轉成10000042507102
20170524000002轉成20000042507102
這樣也可以在一定程度上雜湊逐步put進來的資料。
3.字串拼接
20170524000001_a12e
20170524000001_93i7
7.4 記憶體優化
HBase操作過程中需要大量的記憶體開銷,畢竟Table是可以快取在記憶體中的,一般會分配整個可用記憶體的70%給HBase的Java堆。但是不建議分配非常大的堆記憶體,因為GC過程持續太久會導致RegionServer處於長期不可用狀態,一般16~48G記憶體就可以了,如果因為框架佔用記憶體過高導致系統記憶體不足,框架一樣會被系統服務拖死。
7.5 基礎優化
1.允許在HDFS的檔案中追加內容
hdfs-site.xml、hbase-site.xml
屬性:dfs.support.append
解釋:開啟HDFS追加同步,可以優秀的配合HBase的資料同步和持久化。預設值為true。
2.優化DataNode允許的最大檔案開啟數
hdfs-site.xml
屬性:dfs.datanode.max.transfer.threads
解釋:HBase一般都會同一時間操作大量的檔案,根據叢集的數量和規模以及資料動作,設定為4096或者更高。預設值:4096
3.優化延遲高的資料操作的等待時間
hdfs-site.xml
屬性:dfs.image.transfer.timeout
解釋:如果對於某一次資料操作來講,延遲非常高,socket需要等待更長的時間,建議把該值設定為更大的值(預設60000毫秒),以確保socket不會被timeout掉。
4.優化資料的寫入效率
mapred-site.xml
屬性: mapreduce.map.output.compress mapreduce.map.output.compress.codec
解釋:開啟這兩個資料可以大大提高檔案的寫入效率,減少寫入時間。第一個屬性值修改為true,第二個屬性值修改為:org.apache.hadoop.io.compress.GzipCodec或者其他壓縮方式。
5.優化DataNode儲存
屬性:dfs.datanode.failed.volumes.tolerated
解釋: 預設為0,意思是當DataNode中有一個磁碟出現故障,則會認為該DataNode shutdown了。如果修改為1,則一個磁碟出現故障時,資料會被複制到其他正常的DataNode上,當前的DataNode繼續工作。
6.設定RPC監聽數量
hbase-site.xml
屬性:hbase.regionserver.handler.count
解釋:預設值為30,用於指定RPC監聽的數量,可以根據客戶端的請求數進行調整,讀寫請求較多時,增加此值。
7.優化HStore檔案大小
hbase-site.xml
屬性:hbase.hregion.max.filesize
解釋:預設值10737418240(10GB),如果需要執行HBase的MR任務,可以減小此值,因為一個region對應一個map任務,如果單個region過大,會導致map任務執行時間過長。該值的意思就是,如果HFile的大小達到這個數值,則這個region會被切分為兩個Hfile。
8.優化hbase客戶端快取
hbase-site.xml
屬性:hbase.client.write.buffer
解釋:用於指定HBase客戶端快取,增大該值可以減少RPC呼叫次數,但是會消耗更多記憶體,反之則反之。一般我們需要設定一定的快取大小,以達到減少RPC次數的目的。
9.指定scan.next掃描HBase所獲取的行數
hbase-site.xml
屬性:hbase.client.scanner.caching
解釋:用於指定scan.next方法獲取的預設行數,值越大,消耗記憶體越大。
10.flush、compact、split機制
當MemStore達到閾值,將Memstore中的資料Flush進Storefile;compact機制則是把flush出來的小檔案合併成大的Storefile檔案。split則是當Region達到閾值,會把過大的Region一分為二。
涉及屬性:
即:128M就是Memstore的預設閾值
hbase.hregion.memstore.flush.size:134217728
即:這個引數的作用是當單個HRegion內所有的Memstore大小總和超過指定值時,flush該HRegion的所有memstore。RegionServer的flush是通過將請求新增一個佇列,模擬生產消費模型來非同步處理的。那這裡就有一個問題,當佇列來不及消費,產生大量積壓請求時,可能會導致記憶體陡增,最壞的情況是觸發OOM。
hbase.regionserver.global.memstore.upperLimit:0.4
hbase.regionserver.global.memstore.lowerLimit:0.38
即:當MemStore使用記憶體總量達到hbase.regionserver.global.memstore.upperLimit指定值時,將會有多個MemStores flush到檔案中,MemStore flush 順序是按照大小降序執行的,直到重新整理到MemStore使用記憶體略小於lowerLimit
第9章 擴充套件
9.1 HBase在商業專案中的能力
每天:
-
訊息量:傳送和接收的訊息數超過60億
-
將近1000億條資料的讀寫
-
高峰期每秒150萬左右操作
-
整體讀取資料佔有約55%,寫入佔有45%
-
超過2PB的資料,涉及冗餘共6PB資料
-
資料每月大概增長300千兆位元組。
9.2 布隆過濾器
在日常生活中,包括在設計計算機軟體時,我們經常要判斷一個元素是否在一個集合中。比如在字處理軟體中,需要檢查一個英語單詞是否拼寫正確(也就是要判斷它是否在已知的字典中);在 FBI,一個嫌疑人的名字是否已經在嫌疑名單上;在網路爬蟲裡,一個網址是否被訪問過等等。最直接的方法就是將集合中全部的元素存在計算機中,遇到一個新元素時,將它和集合中的元素直接比較即可。一般來講,計算機中的集合是用雜湊表(hash table)來儲存的。它的好處是快速準確,缺點是費儲存空間。當集合比較小時,這個問題不顯著,但是當集合巨大時,雜湊表儲存效率低的問題就顯現出來了。比如說,一個像 Yahoo,Hotmail 和 Gmai 那樣的公眾電子郵件(email)提供商,總是需要過濾來自傳送垃圾郵件的人(spamer)的垃圾郵件。一個辦法就是記錄下那些發垃圾郵件的 email 地址。由於那些傳送者不停地在註冊新的地址,全世界少說也有幾十億個發垃圾郵件的地址,將他們都存起來則需要大量的網路伺服器。如果用雜湊表,每儲存一億個 email 地址, 就需要 1.6GB 的記憶體(用雜湊表實現的具體辦法是將每一個 email 地址對應成一個八位元組的資訊指紋googlechinablog.com/2006/08/blog-post.html,然後將這些資訊指紋存入雜湊表,由於雜湊表的儲存效率一般只有 50%,因此一個 email 地址需要佔用十六個位元組。一億個地址大約要 1.6GB, 即十六億位元組的記憶體)。因此存貯幾十億個郵件地址可能需要上百 GB 的記憶體。除非是超級計算機,一般伺服器是無法儲存的。
布隆過濾器只需要雜湊表 1/8 到 1/4 的大小就能解決同樣的問題。
Bloom Filter是一種空間效率很高的隨機資料結構,它利用位陣列很簡潔地表示一個集合,並能判斷一個元素是否屬於這個集合。Bloom Filter的這種高效是有一定代價的:在判斷一個元素是否屬於某個集合時,有可能會把不屬於這個集合的元素誤認為屬於這個集合(false positive)。因此,Bloom Filter不適合那些“零錯誤”的應用場合。而在能容忍低錯誤率的應用場合下,Bloom Filter通過極少的錯誤換取了儲存空間的極大節省。
下面我們具體來看Bloom Filter是如何用位陣列表示集合的。初始狀態時,Bloom Filter是一個包含m位的位陣列,每一位都置為0,如圖9-5所示。
為了表達S={x1, x2,…,xn}這樣一個n個元素的集合,Bloom Filter使用k個相互獨立的雜湊函式(Hash Function),它們分別將集合中的每個元素對映到{1,…,m}的範圍中。對任意一個元素x,第i個雜湊函式對映的位置hi(x)就會被置為1(1≤i≤k)。注意,如果一個位置多次被置為1,那麼只有第一次會起作用,後面幾次將沒有任何效果。如圖9-6所示,k=3,且有兩個雜湊函式選中同一個位置(從左邊數第五位)。
在判斷y是否屬於這個集合時,我們對y應用k次雜湊函式,如果所有hi(y)的位置都是1(1≤i≤k),那麼我們就認為y是集合中的元素,否則就認為y不是集合中的元素。如圖9-7所示y1就不是集合中的元素。y2或者屬於這個集合,或者剛好是一個false positive。
· 為了add一個元素,用k個hash function將它hash得到bloom filter中k個bit位,將這k個bit位置1。
· 為了query一個元素,即判斷它是否在集合中,用k個hash function將它hash得到k個bit位。若這k bits全為1,則此元素在集合中;若其中任一位不為1,則此元素比不在集合中(因為如果在,則在add時已經把對應的k個bits位置為1)。
· 不允許remove元素,因為那樣的話會把相應的k個bits位置為0,而其中很有可能有其他元素對應的位。因此remove會引入false negative,這是絕對不被允許的。
布隆過濾器決不會漏掉任何一個在黑名單中的可疑地址。但是,它有一條不足之處,也就是它有極小的可能將一個不在黑名單中的電子郵件地址判定為在黑名單中,因為有可能某個好的郵件地址正巧對應一個八個都被設定成一的二進位制位。好在這種可能性很小,我們把它稱為誤識概率。
布隆過濾器的好處在於快速,省空間,但是有一定的誤識別率,常見的補救辦法是在建立一個小的白名單,儲存那些可能個別誤判的郵件地址。
布隆過濾器具體演算法高階內容,如錯誤率估計,最優雜湊函式個數計算,位陣列大小計算,請參見Bloom Filter概念和原理。
9.3 HBase2.0新特性
2017年8月22日凌晨2點左右,HBase釋出了2.0.0 alpha-2,相比於上一個版本,修復了500個補丁,我們來了解一下2.0版本的HBase新特性。
舉例:
region進行了多份冗餘
主region負責讀寫,從region維護在其他HregionServer中,負責讀以及同步主region中的資訊,如果同步不及時,是有可能出現client在從region中讀到了髒資料(主region還沒來得及把memstore中的變動的內容flush)。