一、Hbase的六大特點:
(1)、表大:一個表可以有數億行,上百萬列。
(2)、無模式:每行都有一個可排序的主鍵和任意多的列,列可以根據需要動態增加,同一個表中的不同行的可以有截然不同的列。
(3)、面向列:HBase是面向列的的存儲和權限控制,列族獨立索引。
(4)、稀疏:空(null)列並不占用空間,表可以設計的非常稀疏。
(5)、數據類型單一:HBase中的數據都是字符串,沒有類型。
(6)、數據多版本:每個單元中的數據可以有多個版本,默認情況下版本號自動分配,是單元格插入時的時間戳。
二、Hbase與Hive的對比:
(1)、整體對比:
(2)、Hive是一種構建在Hadoop基礎設施之上的數據倉庫,通過Hive可以使用HQL語言查詢存放在HDFS上面的數據。HBase能夠在它的數據庫上面實時運行,HBase被分區為表格,表格有進一步分割為列簇,列族必須需要用schema定義。一個列簇可以包含很多列,每個key/value在HBase中都被定義成一個cell,每一個cell都有一個rowkey,一個columnFamily,一個value值,一個timestamp。rowkey不能為空且唯一。
(3)、Hive把HQL解析成MR程序,因為它是兼容JDBC,所有可以和很多JDBC程序做集成,它只能做離線查詢,不能做實時查詢,默認查詢Hive是查詢所有的數據,這個可以通過分區來控制。HBase通過存儲的key/value來工作的,它支持主要的四種操作,增刪改查。
(4)、Hive目前不支持更新操作,花費時間長,必須要先設置schema將文件和表映射,Hive和ACID不兼容。HBase必須需要zk的支持,查詢語句需要重新學,如果要使用sql查詢,可以使用Apache Phonenix,但會以schema作為代價。
(5)、Hive適用於一段時間內的數據進行分析查詢,HBase適用於大規模數據的實時查詢。
三、Hbase的使用場景:
(1)、半結構化數據和非結構化數據,可以進行動態擴展。
(2)、記錄非常的稀疏。
(3)、多版本數據。
(4)、超大數據容量:HBase會自動水平切分擴展,跟Hadoop的無縫集成保證了其數據的可靠性和海量數據分析的高性能。
四、Hbase的rowkey設計原則:
(1)、rowkey長度原則:rowkey是一個二進制流,長度開發者建議是10-100字節,不過建議越短越好,最好不超過16字節。原因是:數據持久化文件HFile中是按照按照key/value存儲的,如果rowkey太長的話就會影響HFile的存儲效率。Memstore將緩存數據到內存,如果rowkey字段過長內存的有效利用會降低,系統將會無法緩存更多的數據,降低檢索的效率。
(2)、rowkey散列原則:如果rowkey是按照時間戳方式遞增的話,不要將時間放在二進制碼的前面,建議將rowkey的高位作為散列字段,如果沒有散列字段就會出現一個regionServer上堆積的熱點現象。
(3)、rowkey的唯一原則:rowkey不能為空且唯一。
五、Hbase的查詢方式:
1、全表查詢:scan tableName
2、基於rowkey的單行查詢:get tableName,'1'
3、基於rowkey的范圍掃描:scan tableName, {STARTROW=>'1',STOPROW=>'2'}
4、get和scan方法:
(1)、按指定的rowkey獲取唯一一條數據,get方法:分為兩種,分別是設置了closestRowBefore和沒有設置的rowlock,只要保證行的事務性,即每一個get是以一個row來標記的,一個row中可以有多個family和column。
(2)、按指定的條件獲取一批記錄,條件查詢。1、scan可以通過setCaching和setBatch方法來提高速度;2、scan也可以通過setStartRow和setEndRow來限定范圍(左閉右開),3、scan還可以通過setFileter方法來添加過濾器。
ps:setCache和setBatch方法:
setCache方法:這個方法設置即一次RPC請求放回的行數,對於緩存操作來說,如果返回行數太多了,就可能內存溢出,那么這個時候就需要setBatch方法,。
setBatch:設置這個之后客戶端可以選擇取回的列數,如果一行包括的列數超過了設置的值,那么就可以將這個列分片。例如:如果一行17列,如果batch設置為5的話,就會返回四組,分別是5,5,5,2。、
※:Cache設置了服務器一次返回的行數,而Batch設置了服務器一次返回的列數。
ps:Batch參數決定了一行數據分為幾個result,它只針對一行數據,Cache決定了一次RPC返回的result個數。
RPC請求次數 = (行數 * 每行列數) / Min(每行的列數,批量大小) / 掃描器緩存
六、Hbase的cell結構:
1、什么是Hbase中的cell:Hbase中通過row和columns確定一個存貯單元成為cell,cell由{{rowkey, column(=<family> + <label>,version)}構成。
2、Hbase中表示行的集合,行是列族的集合,列族是列的集合,列是鍵值對的集合,如圖:
七、Hbase的讀寫流程:
1、HBase的讀流程:
(1)、HRegisonServer保存着.meta.表及數據表,首先client先訪問zk,訪問-ROOT-表,然后在zk上面獲取.meta.表所在的位置信息,找到這個meta表在哪個HRegionServer上面保存着。
(2)、接着client訪問HRegionServer表從而讀取.meta.進而獲取.meta.表中存放的元數據。
(3)、client通過.meta.中的元數據信息,訪問對應的HRegionServer,然后掃描HRegionServer的Memstore和StoreFile來查詢數據。
(4)、最后把HRegionServer把數據反饋給client。
2、HBase的寫流程:
(1)、client訪問zk中的-ROOT-表,然后后在訪問.meta.表,並獲取.meta.中的元數據。
(2)、確定當前要寫入的HRegion和HRegionServer。
(3)、clinet向HRegionServer發出寫相應的請求,HRegionServer收到請求並響應。
(4)、client先將數據寫入到HLog中,以防數據丟失。
(5)、然后將數據寫入到MemStore中。
(6)、如果HLog和MemStore都寫入成功了,那么表示這個條數據寫入成功了。
(7)、如果MemStore寫入的數據達到了閾值,那么將會flush到StoreFile中。
(8)、當StoreFile越來越多,會觸發Compact合並操作,將過多的StoteFile合並成一個大的StoreFile。
(9)、當StoreFile越來越多時,Region也會越來越大,當達到閾值時,會觸發spilit操作,將這個Region一分為二。
ps:HBase中所有的更新和刪除操作都會在后續的compact中進行,使得用戶的寫操作只需要進入內存中就行了。實現了HBase的 I/O高性能。
八、Hbase的結構:
1、HMaster:
(1)、為所有的RegionServer分配Region。
(2)、負責RegionServer的負載均衡。
(3)、發現失效的RegionServer並重新分配其上的Region。
(4)、HDFS上的垃圾文件。
(5)、處理Schema更新請求(表的創建,刪除,修改,列族的增加等)。
2、HRegionServer:
(1)HRegion:
(1)、簡介:Table在行的方向上分隔為多個Region,Region是HBase中分布式存儲和負載均衡的最小單元,即不同的Region可以分在不同的RegionServer上面,但同一個Region是不會拆分到多個Server上面的。隨着數據的增多,某個列族的達到一個閾值就會分成兩個新的Region。結構:<表名,startRowkey,創建時間>,由目錄表(-ROOT-,.META.)記錄該Region的endRowkey
(2)、Store:
(1)簡介:每一個Region由一個或則多個Store組成,至少是一個Store,HBase會把訪問的數據存放在Store中,即每一個列族建一個Store,如果有多個ColumnFamily,就多多個Store,一個Store由一個MemStore和0或則多個StoreFile組成。HBase通過Store的大小判斷是否需要切分Region。
(2)MemStore:它是放在內存中的,保存修改的數據,即key/values。當MemStore的大小達到一定的閾值的時候(默認128M),MemStore會被Flush到文件,即生成一個快照StoreFile,Flush過程由一個線程完成。
(3)StoreFile:StoreFile底層是HFile,HFile是Hadoop的二進制格式文件,
(2)HLog:WAL文件,用來災難恢復使用,HLog記錄數據的所有變更,一旦RegionServer宕機,就從HLog中進行恢復,HLog文件就是一個普通的Hadoop Sequence File,Sequence File記錄了寫入數據的歸屬信息,除了Table和Region名字外,還同時包括了Sequence Number和TimeStamp,Sequence File的value是HBase的key/value對象,即對應的HFile中的key/value。
3、Zookeeper:
(1)、保證任何時候集群中只有一個活躍的Master。
(2)、存儲所有的Region的尋址入口,知道哪個Region在哪台機器上。
(3)、實時監控RegionServer的狀態,將RegionServer的上下線的信息匯報給HMaster,RegionServer不直接向HMaster匯報信息,減輕HMaster的壓力,而是通過向ZK發送信息。
(4)、存儲HBase的元數據結構(schema),知道集群中有哪些Table,每個Table有哪些Column Family。
4、結構圖:
九、Hbase中的Compact機制:
1、當HBase中的memstore數據flush到磁盤的時候,就會形成一個storefile,當storefile的數量達到一定程度的時候,就需要將storefile文件進行compaction操作,Compact作用:合並文件、清楚過期,多余版本數據、提高讀寫效率。
2、compact操作的實現:①minor:Minor 操作只用來做部分文件的合並操作以及包括 minVersion=0 並且設置 ttl 的過期版本清理,不做任何刪除數據、多版本數據的清理工作。②major:Major 操作是對 Region 下的HStore下的所有StoreFile執行合並操作,最終的結果是整理合並出一個文件。
十、Hbase中的數據模型:
1、邏輯視圖:轉載:
2、物理視圖:(1)、每個columnFamily存儲在HDFS上的一個單獨文件,空值不會被保留。(2)、key和versionNumber在每個columnFamily中單獨一份。(3)、HBase每個值維護多級索引,即<key,columnFamily,columnName,timeStamp>。(4)、表在行的方向上分割為多個Region。(5)、Region是HBase分布式存儲和負載均衡的最小單元,不同Region分布在不同的RegionServer中。(6)、Region雖然是分布式存儲的最小單元,但並不是最小存儲單元,一個Region中包含多個Store對象,每個Store包含一個MemStore和若干個StoreFile,StoreFile包含一個或多個HFile。MemStore存放在內存中,StoreFile存儲在HDFS上面。
3、HBase中的-ROOT-表和.META.表:HBase中的Region元數據都存儲在.META.表中,隨着Region的增加,.META.表也會越來越多。為了定位.META.表中各個Region的位置,把.META.表中所有Region的元數據保存在-ROOT-表中,最后由Zookeeper記錄-ROOT-表的位置信息。所有客戶端訪問用戶數據前,需要首先訪問Zookeeper獲得-ROOT-的位置,然后訪問-ROOT-表獲得.META.表的位置,最后根據.META.表中的信息確定用戶數據存放的位置。-ROOT-表是不會分割的,它只有一個Region。為了加快訪問速度,.META.表的所有Region全部保存在內存中。客戶端會將查詢過的位置信息緩存起來,且緩存不會主動失效。如果客戶端根據緩存信息還訪問不到數據,則詢問相關.META.表的Region服務器,試圖獲取數據的位置,如果還是失敗,則詢問-ROOT-表相關的.META.表在哪里。
十一、Hbase中的優化:
1、讀寫性能優化:
(1)、開啟bloomfilter過濾器。
(2)、在條件允許的情況下,給HBase足夠的內存。修改配置文件hbase-env.sh中的export HBASE_HEAPSIZE=1000
(3)、增加RPC的數量。通過修改hbase-site.xml中的hbase.regionserver.handler.count屬性可以適當的放大RPC數量,默認是10。
(4)、HBase中的region太小會造成多次spilit,region就會下線。如果HBase中的region過大,就會發生多次的compaction,將數據讀一遍重寫一遍到HDFS上面,占用io。
2、預設分區:
(1)、shell方法:例如:create 'tb_split',{NAME=>'cf', VERSION=>3},{SPLITS=>['10','20','30']}
(2)、java程序控制:https://blog.csdn.net/javajxz008/article/details/51913471
3、其他優化方法:
(1)、減少調整:可以調整region和HFile。因為region的分裂會導致I/O開銷,如果沒有預設分區的話,隨着region中條數的增,region會進行分裂,解決方法就是根據rowkey設計來進行預建分區,減少region的動態分裂。HFile會隨着memstore進行刷新時生成一個HFile,當HFile增加到一定量的時候,會將屬於一個region的HFile合並,HFile是不可避免的,但是如果HFile大於設置得值,就會導致HFile分裂,這樣就會導致I/O的開銷增大。
(2)、減少啟停:對於HBase會有compact機制,會合並HFile,但是我們可以手動關閉compact,減少I/O。如果是批量數據的寫入,我們可以用BulkLoad來批量插入數據。(BulkLoad的使用:https://blog.csdn.net/shixiaoguo90/article/details/78038462)
(3)、減少數據量:開啟過濾,提高查詢效率。(開啟BloomFilter,這個是列簇級別的過濾,在生成一個StoreFile同時會生成一個MetaBlock,用於查詢時的過濾)。使用壓縮,一般使用snappy和lzo壓縮。
(4)、合理設計:rowkey的設計:(散列性、簡短性、唯一性、業務性),列族的設計:(多列族的優勢是:在進行查表的時候,只需要掃描那一列就行了,就不需要全盤掃描,減少I/O,劣勢是:降低了寫的I/O,原因是:數據寫到stroe以后會緩存到memstore中,)