目錄
1. 什么是 HBase
2. 大資料中為何要使用 HBase(HBase 在大資料中的優勢)
3. HBase 與傳統的關系資料庫的區別
4. RowKey 的設計原則
5. RowKey 如何設計可以避免熱點問題
6. HRegionServer 架構
7.HBase 性能優化方法總結
表的設計
寫表操作
讀表操作
8. Hbase讀寫流程
hbase的讀操作:
hbase的寫操作:
9. HBase 物理存盤原理
10. HBase 中的 HFile 什么時候要合并成大檔案,什么時候拆分成小檔案
合并操作的時機物件與作用
拆分(對region進行拆分)
11. HBase 查詢快的原因
1. 什么是 HBase
- 是一個高可靠性、高性能、列存盤、可伸縮、實時讀寫的分布式資料庫系統,
- 適合于存盤非結構化資料,基于列的而不是基于行的模式
2. 大資料中為何要使用 HBase(HBase 在大資料中的優勢)
Hadoop可以很好地解決大規模資料的離線批量處理問題,但是,受限于HadoopMapReduce編程框架的高延遲資料處理機制,使得Hadoop無法滿足大規模資料實時處理應用的需求
HDFS面向批量訪問模式,不是隨機訪問模式
傳統的通用關系型資料庫無法應對在資料規模劇增時導致的系統擴展性和性能問題(分庫分表也不能很好解決)
傳統關系資料庫在資料結構變化時一般需要停機維護;空列浪費存盤空間
因此,業界出現了一類面向半結構化資料存盤和處理的高可擴展、低寫入/查詢延遲的系統,例如,鍵值資料庫、檔案資料庫和列族資料庫(如BigTable和HBase等)
HBase已經成功應用于互聯網服務領域和傳統行業的眾多在線式資料分析處理系統中
3. HBase 與傳統的關系資料庫的區別
資料型別:
關系資料庫采用關系模型,具有豐富的資料型別和存盤方式,HBase則采用了更加簡單的資料模型,它把資料存盤為未經解釋的字串
資料操作:
關系資料庫中包含了豐富的操作,其中會涉及復雜的多表連接,HBase操作則不存在復雜的表與表之間的關系,只有簡單的插入、查詢、洗掉、清空等,因為HBase在設計上就避免了復雜的表和表之間的關系
存盤模式:
關系資料庫是基于行模式存盤的,HBase是基于列存盤的,每個列族都由幾個檔案保存,不同列族的檔案是分離的
資料索引:
關系資料庫通常可以針對不同列構建復雜的多個索引,以提高資料訪問性能,HBase只有一個索引——行鍵(RowKey),通過巧妙的設計,HBase中的所有訪問方法,或者通過行鍵訪問,或者通過行鍵掃描,從而使得整個系統不會慢下來
資料維護:
在關系資料庫中,更新操作會用最新的當前值去替換記錄中原來的舊值,舊值被覆寫后就不會存在,而在HBase中執行更新操作時,并不會洗掉資料舊的版本,而是生成一個新的版本,舊有的版本仍然保留
可伸縮性:
關系資料庫很難實作橫向擴展,縱向擴展的空間也比較有限,相反,HBase和BigTable這些分布式資料庫就是為了實作靈活的水平擴展而開發的,能夠輕易地通過在集群中增加或者減少硬體數量來實作性能的伸縮
4. RowKey 的設計原則
長度原則:
Rowkey是一個二進制碼流,最大長度為64kb,Rowkey的長度被很多開發者建議說設計在10~100個位元組,以 byte[]形式保存,一般設定為定長,建議是越短越好,不要超過16位元組,原因如下:
- HBase的持久化檔案HFile是按照KeyValue存盤的,如果Rowkey過長比如500個位元組1000萬列資料光Rowkey就要占用500*1000萬=50億個位元組,將近1G資料,這會極大影響HFile的存盤效率;
- MemStore快取部分資料到記憶體,如果Rowkey欄位過長記憶體的有效利用率會降低,系統無法快取更多的資料,這會降低檢索效率;
- 目前作業系統都是64位系統,記憶體8位元組對齊,控制在16位元組,8位元組的整數倍利用了作業系統的最佳特性
需要指出的是不僅Rowkey的長度是越短越好,而且列族名、列名等盡量使用短名字,因為HBase屬于列式資料庫,這些名字都是會寫入到HBase的持久化檔案HFile中去,過長的Rowkey、列族、列名都會導致整體的存盤量成倍增加,
唯一原則:
必須在設計上保證其唯一性,由于在HBase中資料存盤是Key-Value形式,若HBase中同一表插入相同Rowkey,則原先的資料會被覆寫掉(如果表的version設定為1的話),所以務必保證RowKey的唯一性
排序原則:
HBase 的 RowKey 是按照 ASII 有序排序的,因此我們在設計 RowKey 的時候要充分利用這一點,例如 CSDN 的評論是按照時間倒序的,這時候 RowKey 的設計應與時間有關
散列原則:
我們設計的Rowkey應均勻的分布在各個HBase節點上,拿常見的時間戳舉例,假如Rowkey是按系統時間戳的方式遞增,Rowkey的第一部分如果是時間戳資訊的話將造成所有新資料都在一個RegionServer上堆積的熱點現象,也就是通常說的Region熱點問題, 熱點發生在大量的client直接訪問集中在個別RegionServer上(訪問可能是讀,寫或者其他操作),導致單個RegionServer機器自身負載過高,引起性能下降甚至Region不可用,常見的是發生jvm full gc或者顯示region too busy例外情況,當然這也會影響同一個RegionServer上的其他Region,
5. RowKey 如何設計可以避免熱點問題
Reverse反轉:
針對固定長度的Rowkey反轉后存盤,這樣可以使Rowkey中經常改變的部分放在最前面,可以有效的隨機Rowkey,
反轉Rowkey的例子通常以手機舉例,可以將手機號反轉后的字串作為Rowkey,這樣的就避免了以手機號那樣比較固定開頭(137x、15x等)導致熱點問題,
這樣做的缺點是犧牲了Rowkey的有序性,
Salt加鹽:
Salt是將每一個Rowkey加一個前綴,前綴使用一些隨機字符,使得資料分散在多個不同的Region,達到Region負載均衡的目標,
比如在一個有4個Region(注:以 [ ,a)、[a,b)、[b,c)、[c, )為Region起至)的HBase表中,
加Salt前的Rowkey:abc001、abc002、abc003
我們分別加上a、b、c前綴,加Salt后Rowkey為:a-abc001、b-abc002、c-abc003,可以看到,加鹽前的Rowkey默認會在第2個region中,加鹽后的Rowkey資料會分布在3個region中,理論上處理后的吞吐量應是之前的3倍,由于前綴是隨機的,讀這些資料時需要耗費更多的時間,所以Salt增加了寫操作的吞吐量,不過缺點是同時增加了讀操作的開銷,
Hash散列或者Mod:
用Hash散列來替代隨機Salt前綴的好處是能讓一個給定的行有相同的前綴,這在分散了Region負載的同時,使讀操作也能夠推斷,確定性Hash(比如md5后取前4位做前綴)能讓客戶端重建完整的RowKey,可以使用get操作直接get想要的行,
例如將上述的原始Rowkey經過hash處理,此處我們采用md5散列演算法取前4位做前綴,結果如下:
9bf0-abc001 (abc001在md5后是9bf049097142c168c38a94c626eddf3d,取前4位是9bf0)
7006-abc002
95e6-abc003
若以前4個字符作為不同磁區的起止,上面幾個Rowkey資料會分布在3個region中,實際應用場景是當資料量越來越大的時候,
這種設計會使得磁區之間更加均衡,
如果Rowkey是數字型別的,也可以考慮Mod方法,
6. HRegionServer 架構

StoreFile
在HRegionServer架構圖中,StoreFile是保存實際資料的物理檔案,StoreFile是以HFile的形式存盤在HDFS上,每個Store會有一個或多個StoreFile,并且資料在每個StoreFile中都是有序的,
MemStore
它是寫快取的意思,由于HFile是要求資料是有序的,要按照存盤在HDFS上的資料需要按照rowkey排序,所以資料先存盤在MemStore中,排好序后,達到閾值后才會flush到StoreFile中,每次flush生成一個新的StoreFIle,
實作MemStore模型的資料結構是SkipList跳表,跳表它可以實作高效的查詢、插入、洗掉操作,因為跳表本質上是由有序鏈表構成的,很多KV資料庫都會使用跳表實作有序資料集合,所以呢,資料傳入MemStore后,會利用跳表實作這些資料的有序,
WAL
WAL,全稱是Write Ahead Log,預先寫日志的意思,由于資料要經MemStore排序后才能刷寫到HFile,但把資料保存在記憶體中會有很高的概率導致資料丟失的,所以為了解決這個問題,資料會先寫在一個叫做Write Ahead Log的檔案中,然后再寫入MemStore中,所以當系統出現故障的時候,資料就可以通過這個日志檔案重建,避免資料丟失,
BlockCache
它是讀快取的意思,每次查詢出來的資料會先快取在BlockCache中,方便下次查詢資料,
7.HBase 性能優化方法總結
表的設計
Pre-Creating Regions(預磁區)
默認情況下,在創建HBase表的時候會自動創建一個region磁區,當匯入資料的時候,所有的HBase客戶端都向這一個region寫資料,直到這個region足夠大了才進行切分,一種可以加快批量寫入速度的方法是通過預先創建一些空的regions,這樣當資料寫入HBase時,會按照region磁區情況,在集群內做資料的負載均衡,
RowKey
HBase中row key用來檢索表中的記錄,支持以下三種方式:
- 通過單個row key訪問:即按照某個row key鍵值進行get操作;
- 通過row key的range進行scan:即通過設定startRowKey和endRowKey,在這個范圍內進行掃描;
- 全表掃描:即直接掃描整張表中所有行記錄,
在HBase中,row key可以是任意字串,最大長度64KB,實際應用中一般為10~100bytes,存為byte[]位元組陣列,一般設計成定長的,
row key是按照字典序存盤,因此,設計row key時,要充分利用這個排序特點,將經常一起讀取的資料存盤到一塊,將最近可能會被訪問的資料放在一塊,
舉個例子:如果最近寫入HBase表中的資料是最可能被訪問的,可以考慮將時間戳作為row key的一部分,由于是字典序排序,所以可以使用Long.MAX_VALUE - timestamp作為row key,這樣能保證新寫入的資料在讀取時可以被快速命中,
Column Family
不要在一張表里定義太多的column family,目前Hbase并不能很好的處理超過2~3個column family的表,因為某個column family在flush的時候,它鄰近的column family也會因關聯效應被觸發flush,最終導致系統產生更多的I/O,
In Memory
創建表的時候,可以通過HColumnDescriptor.setInMemory(true)將表放到RegionServer的快取中,保證在讀取的時候被cache命中,
Max Version
創建表的時候,可以通過HColumnDescriptor.setMaxVersions(int maxVersions)設定表中資料的最大版本,如果只需要保存最新版本的資料,那么可以設定setMaxVersions(1),
Time To Live
創建表的時候,可以通過HColumnDescriptor.setTimeToLive(int timeToLive)設定表中資料的存盤生命期,過期資料將自動被洗掉,例如如果只需要存盤最近兩天的資料,那么可以設定setTimeToLive(2 * 24 * 60 * 60),
Compact & Split
在HBase中,資料在更新時首先寫入WAL 日志(HLog)和記憶體(MemStore)中,MemStore中的資料是排序的,當MemStore累計到一定閾值時,就會創建一個新的MemStore,并且將老的MemStore添加到flush佇列,由單獨的執行緒flush到磁盤上,成為一個StoreFile,于此同時, 系統會在zookeeper中記錄一個redo point,表示這個時刻之前的變更已經持久化了(minor compact),
StoreFile是只讀的,一旦創建后就不可以再修改,因此Hbase的更新其實是不斷追加的操作,當一個Store中的StoreFile達到一定的閾值后,就會進行一次合并(major compact),將對同一個key的修改合并到一起,形成一個大的StoreFile,當StoreFile的大小達到一定閾值后,又會對 StoreFile進行分割(split),等分為兩個StoreFile,
由于對表的更新是不斷追加的,處理讀請求時,需要訪問Store中全部的StoreFile和MemStore,將它們按照row key進行合并,由于StoreFile和MemStore都是經過排序的,并且StoreFile帶有記憶體中索引,通常合并程序還是比較快的,
實際應用中,可以考慮必要時手動進行major compact,將同一個row key的修改進行合并形成一個大的StoreFile,同時,可以將StoreFile設定大些,減少split的發生,
寫表操作
多HTable并發寫
創建多個HTable客戶端用于寫操作,提高寫資料的吞吐量
HTable引數設定
(1)Auto Flush:
通過呼叫HTable.setAutoFlush(false)方法可以將HTable寫客戶端的自動flush關閉,這樣可以批量寫入資料到HBase,而不是有一條put就執行一次更新,只有當put填滿客戶端寫快取時,才實際向HBase服務端發起寫請求,默認情況下auto flush是開啟的,
(2)Write Buffer:
通過呼叫HTable.setWriteBufferSize(writeBufferSize)方法可以設定HTable客戶端的寫buffer大小,如果新設定的buffer小于當前寫buffer中的資料時,buffer將會被flush到服務端,其中,writeBufferSize的單位是byte位元組數,可以根據實際寫入資料量的多少來設定該值,
(3)WAL Flag:
在HBase中,客戶端向集群中的RegionServer提交資料時(Put/Delete操作),首先會先寫WAL(Write Ahead Log)日志(即HLog,一個RegionServer上的所有Region共享一個HLog),只有當WAL日志寫成功后,再接著寫MemStore,然后客戶端被通知提交資料成功;如果寫WAL日志失敗,客戶端則被通知提交失敗,這樣做的好處是可以做到RegionServer宕機后的資料恢復,
因此,對于相對不太重要的資料,可以在Put/Delete操作時,通過呼叫Put.setWriteToWAL(false)或Delete.setWriteToWAL(false)函式,放棄寫WAL日志,從而提高資料寫入的性能,
值得注意的是:謹慎選擇關閉WAL日志,因為這樣的話,一旦RegionServer宕機,Put/Delete的資料將會無法根據WAL日志進行恢復,
批量寫
通過呼叫HTable.put(Put)方法可以將一個指定的row key記錄寫入HBase,同樣HBase提供了另一個方法:通過呼叫HTable.put(List<Put>)方法可以將指定的row key串列,批量寫入多行記錄,這樣做的好處是批量執行,只需要一次網路I/O開銷,這對于對資料實時性要求高,網路傳輸RTT高的情景下可能帶來明顯的性能提升,
多執行緒并發寫
在客戶端開啟多個HTable寫執行緒,每個寫執行緒負責一個HTable物件的flush操作,這樣結合定時flush和寫buffer(writeBufferSize),可以既保證在資料量小的時候,資料可以在較短時間內被flush(如1秒內),同時又保證在資料量大的時候,寫buffer一滿就及時進行flush,
讀表操作
多HTable并發讀
創建多個HTable客戶端用于讀操作,提高讀資料的吞吐量
HTable引數設定
(1)Scanner Caching
hbase.client.scanner.caching配置項可以設定HBase scanner一次從服務端抓取的資料條數,默認情況下一次一條,通過將其設定成一個合理的值,可以減少scan程序中next()的時間開銷,代價是scanner需要通過客戶端的記憶體來維持這些被cache的行記錄,
有三個地方可以進行配置:
1)在HBase的conf組態檔中進行配置;
2)通過呼叫HTable.setScannerCaching(int scannerCaching)進行配置;
3)通過呼叫Scan.setCaching(int caching)進行配置,
三者的優先級越來越高,
(2)Scan Attribute Selection
scan時指定需要的Column Family,可以減少網路傳輸資料量,否則默認scan操作會回傳整行所有Column Family的資料,
(3)Close ResultScanner
通過scan取完資料后,記得要關閉ResultScanner,否則RegionServer可能會出現問題(對應的Server資源無法釋放),
批量讀
通過呼叫HTable.get(Get)方法可以根據一個指定的row key獲取一行記錄,同樣HBase提供了另一個方法:通過呼叫HTable.get(List<Get>)方法可以根據一個指定的row key串列,批量獲取多行記錄,這樣做的好處是批量執行,只需要一次網路I/O開銷,這對于對資料實時性要求高而且網路傳輸RTT高的情景下可能帶來明顯的性能提升,
多執行緒并發讀
在客戶端開啟多個HTable讀執行緒,每個讀執行緒負責通過HTable物件進行get操作,下面是一個多執行緒并發讀取HBase
快取查詢結果
對于頻繁查詢HBase的應用場景,可以考慮在應用程式中做快取,當有新的查詢請求時,首先在快取中查找,如果存在則直接回傳,不再查詢HBase;否則對HBase發起讀請求查詢,然后在應用程式中將查詢結果快取起來,至于快取的替換策略,可以考慮LRU等常用的策略,
Blockcache
HBase上Regionserver的記憶體分為兩個部分,一部分作為Memstore,主要用來寫;另外一部分作為BlockCache,主要用于讀,
寫請求會先寫入Memstore,Regionserver會給每個region提供一個Memstore,當Memstore滿(新版128MB,老版64MB)以后,會啟動 flush重繪到磁盤,當Memstore的總大小超過限制時(heapsize * hbase.regionserver.global.memstore.upperLimit * 0.9),會強行啟動flush行程,從最大的Memstore開始flush直到低于限制,
讀請求先到Memstore中查資料,查不到就到BlockCache中查,再查不到就會到磁盤上讀,并把讀的結果放入BlockCache,由于BlockCache采用的是LRU策略,因此BlockCache達到上限(heapsize * hfile.block.cache.size * 0.85)后,會啟動淘汰機制,淘汰掉最老的一批資料,
一個Regionserver上有一個BlockCache和N個Memstore,它們的大小之和不能大于等于heapsize * 0.8,否則HBase不能啟動,默認BlockCache為0.2,而Memstore為0.4,對于注重讀回應時間的系統,可以將 BlockCache設大些,比如設定BlockCache=0.4,Memstore=0.39,以加大快取的命中率,
8. Hbase讀寫流程
hbase的讀操作:
ZooKeeper---meta--regionserver--region--memstore--storefile
- 首先從zookerper找到meta表的region的位置,然后讀取meta表中的資料,而meta中又存盤了用戶表的region資訊
- 根據namespace、表名和rowkey根據meta表中的資料找到寫入資料對于的region資訊
- 然后找到對于的regionserver
- 查找對應的region
- 先從Memstore找資料,如果沒有,再到StoreFile上讀

hbase的寫操作:
ZooKeeper---meta--regionserver--1、Hlog 1、MemStore--storefile
- 首先從zookerper找到meta表的region的位置,然后讀取meta表中的資料,而meta中又存盤了用戶表的region資訊
- 根據namespace、表名和rowkey根據meta表中的資料找到寫入資料對于的region資訊
- 然后找到對于的regionserver
- 把資料分別寫到Hlog和memstore各一份
- 當memstore達到閾值后把資料刷成一個storefile檔案,當compact后,逐漸形成越來越大的storefile后觸發spilt,把當前的StoreFile分成兩個,這里相當于把一個大的region分割成兩個region
- 若MemStore中的資料有丟失,則可以從HLog上恢復,當多個StoreFile檔案達到一定的大小后,會觸發Compact合并操作,合并為一個StoreFile,這里同時進行版本的合并和資料洗掉
9. HBase 物理存盤原理
存盤原理:
Hbase 里的一個 Table 在行的方向上分割為多個 HRegion,即HBase中一個表的資料會被劃分成很多的 HRegion,HRegion 可以動態擴展并且 HBase 保證 HRegion 的負載均衡,HRegion 實際上是行鍵排序后的按規則分割的連續的存盤空間

拆分流程圖:
HRegion是按大小分割的,在沒有設定預磁區的情況下,每個表一開始只有一個HRegion,隨著資料不斷插入表,HRegion不斷增大,當增大到一個閥值的時候,HRegion就會等分兩個新的HRegion,當table中的行不斷增多,就會有越來越多的Hregion

一張 Hbase 表,可能有多個 HRegion,每個 HRegion 達到一定大小(默認是10GB)時,進行分裂,
按照現在主流硬體的配置,每個 HRegion的大小可以是1~20GB,這個大小由hbase.hregion.max.filesize 指定,默認為10GB,HRegion 的拆分和轉移是由 HBase(HMaster)自動完成的,用戶感知不到,
HRegion 是 Hbase 中分布式存盤和負載均衡的最小單元

HRegion雖然是分布式存盤的最小單元,但并不是存盤的最小單元,
事實上,HRegion由一個或者多個HStore組成,每個Hstore保存一個columns family,
每個HStore又由一個memStore和0至多個StoreFile組成,StoreFile以HFile格式保存在HDFS上,如圖:

總結:
HRegion是分布式的存盤最小單位,StoreFile(Hfile)是存盤最小單位
10. HBase 中的 HFile 什么時候要合并成大檔案,什么時候拆分成小檔案
合并操作的時機物件與作用
合并的時機:
- hfile檔案進行更新、洗掉操作時,每操作一次生成一個hfile檔案,當有大量更新或洗掉操作后,需要對hfile檔案進行合并,生成一個新的hfile檔案;
- 新檔案生成之后,以前操作留存的檔案就會被清理,可以釋放資源,節省空間;
- 當進行大量更新或洗掉操作后,region管理范圍變小,需要對region進行合并;
- region合并后,表結構也要進行相應的更改,表也要進行合并(釋放資源)(可自動合并或手動合并,因其占用大量資源,一般選擇周末、節假日這種非作業日進行);
- 當屬性中設定了DDL(過期時間)后,一段時間之后,hfile檔案中的資料會過期,hbase會自動將檔案進行合并,釋放資源,
合并的物件:
hfile檔案、region、表,
合并的作用:
對更新、洗掉后的資料進行有效管理;釋放資源,
拆分(對region進行拆分)
為什么進行拆分
- HBase是以表的形式存盤資料的,一個表被劃分成多個region,分布咋不同的RegionServer中,單個region只能分布在一個從節點上,不能跨節點存盤;
- 當表中的資料量增多,region管理的資料也會相應增加,默認每個region的大小是128M;
- 當資料量太多,處理讀/寫請求出現熱點問題的概率會增加,當所有請求都分到了一個region上,region所在的節點可能會因負載過重而宕機;
- 此時,需要進行region的拆分,分配到不同的節點上,同時對資料進行管理,
拆分的方式:
(1)ConstantSizeRegionSplitPolicy:0.94版本前默認拆分方式
當region的大小大于某個閾值(hbase.hregion.max.filesize=10G)之后就會觸發切分,一個region會等分為2個region,但是這種切分策略卻有相當大的弊端:切分策略對于大表和小表沒有明顯的區分,閾值設定較大對大表比較友好,但是小表就有可能不會觸發分裂,極端情況下可能就1個,這對業務來說并不是什么好事,如果設定較小則對小表友好,但一個大表就會在整個集群產生大量的region,這對于集群的管理、資源使用、failover來說都不是一件好事,
(2)IncreasingToUpperBoundRegionSplitPolicy:0.94版本~2.0版本默認拆分方式
切分策略稍微有點復雜,總體看和ConstantSizeRegionSplitPolicy思路相同,一個region大小大于設定閾值就會觸發切分,但是這個閾值并不像ConstantSizeRegionSplitPolicy是一個固定的值,而是會在一定條件下不斷調整,調整規則和region所屬表在當前regionserver上的region個數有關系,
(3)SteppingSplitPolicy:2.0版本之后默認拆分方式
相比之前的IncreasingToUpperBoundRegionSplitPolicy,它會簡單一些,依然和待分裂region所屬表在當前regionserver上的region個數有關系,如果region個數等于1,切分閾值為flush size * 2,否則為MaxRegionFileSize,這種切分策略對于大集群中的大表、小表會比 IncreasingToUpperBoundRegionSplitPolicy 更加友好,小表不會再產生大量的小region,而是適可而止,
11. HBase 查詢快的原因
主要原因是由其架構和底層的資料結構決定的,即由 LSM-Tree(Log-Structured Merge-Tree) + HTable(region磁區) + Cache 決定——客戶端可以直接定位到要查資料所在的 HRegion server 服務器,然后直接在服務器的一個 region 上查找要匹配的資料,并且這些資料部分是經過 cache 快取的,
由于 HBase 會將資料保存到記憶體中,在記憶體中的資料是有序的,如果記憶體空間滿了,會刷寫到 HFile 中,而在HFile中保存的內容也是有序的,當資料寫入 HFile 后,記憶體中的資料會被丟棄,
HFile 檔案為磁盤順序讀取做了優化,按頁存盤,下圖展示了在記憶體中多個塊存盤并歸并到磁盤的程序,合并寫入會產生新的結果塊,最終多個塊被合并為更大塊,

多次刷寫后會產生很多小檔案,后臺執行緒會合并小檔案組成大檔案,這樣磁盤查找會限制在少數幾個資料存盤檔案中,HBase 的寫入速度快是因為它其實并不是真的立即寫入檔案中,而是先寫入記憶體,隨后異步刷入HFile,所以在客戶端看來,寫入速度很快,另外,寫入時候將隨機寫入轉換成順序寫,資料寫入速度也很穩定,
而讀取速度快是因為它使用了 LSM 樹型結構,而不是B或B+樹,磁盤的順序讀取速度很快,但是相比而言,尋找磁道的速度就要慢很多,HBase 的存盤結構導致它需要磁盤尋道時間在可預測范圍內,并且讀取與所要查詢的 rowkey 連續的任意數量的記錄都不會引發額外的尋道開銷,比如有5個存盤檔案,那么最多需要5次磁盤尋道就可以,而關系型資料庫,即使有索引,也無法確定磁盤尋道次數,而且,HBase 讀取首先會在快取(BlockCache)中查找,它采用了 LRU(最近最少使用演算法),如果快取中沒找到,會從記憶體中的 MemStore 中查找,只有這兩個地方都找不到時,才會加載 HFile 中的內容,而上文也提到了讀取 HFile 速度也會很快,因為節省了尋道開銷,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/299492.html
標籤:其他
上一篇:ES入門到寫DSL:我只會Mysql陳述句,不會es陳述句怎么辦?
下一篇:???Kettle--老板說:這套生產資料庫千萬、億級資料量遷移方案,學會就賺了???(作業學習必備,建議收藏)
