HBase的原型是Google的BigTable
論文,受到了該論文思想的啟發,目前作為Hadoop的頂級項目來開發維護,用于支持結構化的數據存儲。
HBase是一個高可靠性
、高性能
、面向列
、可伸縮
的分布式存儲
系統,利用HBASE技術可在廉價PC Server上搭建起大規模結構化存儲集群。
HBase的目標是存儲
并處理
大型的數據,更具體來說是僅需使用普通的硬件配置,就能夠處理由成千上萬的行和列所組成的大型數據?!痉谴笪鹩谩?/p>
HBase是Google Bigtable的開源實現,但是也有很多不同之處。比如:Google Bigtable利用GFS作為其文件存儲系統,HBase利用Hadoop HDFS作為其文件存儲系統;Google運行MAPREDUCE來處理Bigtable中的海量數據,HBase同樣利用Hadoop MapReduce來處理HBase中的海量數據;Google Bigtable利用Chubby作為協同服務,HBase利用Zookeeper作為對應。
簡單粗暴的總結:就是一款NoSQL
數據庫,面向列存儲
,用于存儲處理海量數據。
核心在于它是一個存數據的地方,可是在此之前學習過了HDFS和MySQL,那HBase為什么還會出現呢?
先說一下Mysql,我們都知道Mysql是一個關系型數據庫,平時開發使用的非常頻繁。一個網站或者系統最核心的表就是用戶表,而當用戶表的數據達到幾千萬甚至幾億級別的時候,對單條數據的檢索將會耗費數秒甚至分鐘級別。實際的清空可能更加復雜不堪。
看下邊一張表:
假如根據id=1查詢出來這條數據對應的用戶姓名,很簡單,會給我們返回zhangsan。但是,當我們查的時候,想一下,查名字的時候age和email會不會被查出來?答案是肯定的,Mysql的數據存儲是以行為單位的,面向行存儲。那問題就出現了,我只需要找出zhangsan的名字,卻需要查詢一整行的數據,如果列非常多,那么查詢效率可想而知了。
查詢的操作速度會受到以下兩個因素的制約:
表被并發的插入、編輯以及刪除操作。
查詢語句通常不是簡單的對一個表進行操作,有可能是多個表關聯后的復雜查詢,甚至有可能是group by或者order by操作,此時,性能下降很明顯。
如果一張表的列過多
,會影響查詢效率,我們稱這樣表為寬表。怎么優化呢,拆開來,豎直拆分
:
這樣的情況下,我們要查找username的時候只需要查找user_basic表,沒有多余的字段,查詢效率就會很快。如果一張表的行過多
,會影響查詢效率,我們將這樣的表稱之為高表
,可以采用水平拆表
的方式提高效率:
這種水平拆分應用比較多的 場景就是日志表
,日志信息每天產生很多,可以按月
進行水平拆分,這樣就實現了高表變矮。
ok,這種拆分方式貌似可以解決寬表和高表的問題,但是如果有一天公司的業務變了,比如原來沒有微信,現在有了微信,需要加入用戶的微信字段。這時候需要改變表的結構信息,該怎么辦?最簡單的想法是多加一列,像這樣:
多考慮一下就知道這樣做很不妥帖,比如說有些早期用戶沒有微信,這一列是設置默認值還是采取其他的做法就得權衡一下。如果需要擴展很多的列出來,而且不是所有的用戶都有這些屬性,那么拓展起來就更加復雜了。
這時候,想到了JSON格式的字符串,這是一種以字符串的形式表示的對象(將若干可選擇填寫信息匯總),而且屬性字段可以動態拓展,于是有了下邊這種做法,兩種做法加以對比:
ok,這樣存儲數據它不挺好的嘛,HBase出來干嘛??Mysql有一點,數據達到一定的閾值(一般是500W),無論怎么優化,它都無法達到高性能的發揮。而大數據領域的數據,動輒PB級,這種存儲應用明顯是不能很好的滿足需求的。針對上邊的問題,HBase都有很好的解決方案~~
先不說為什么用,接著上邊說到的幾個問題:高表寬表,數據列動態擴展,把提到的幾個解決辦法:水平垂直切分
,列擴展方法
雜糅在一起。
有這么一張表,怕它又寬又高,又會動態擴展列,那么在設計之初,就把這個表給他拆開,為了列的動態拓展
,直接存儲JSON格式:
這樣就解決了寬表問題,高表怎么辦呢?一個表的兩部分,各存一部分行:
解決了高表,寬表,動態擴展列的問題,如果還要進一步提高性能怎么辦?Mysql->Redis !!! 緩存啊!
查詢出來的數據放入到緩存中,下一次查詢直接從緩存中拿數據。插入數據怎么辦呢?也可以這樣理解,我把要插入的數據放進緩存中,再也不用管了,直接由數據庫從緩存拿數據插入到數據庫。此時程序不需要等待數據插入成功,提高了并行工作的效率。
可是這樣做有了很大的風險,服務器宕機的話,緩存中的數據沒來得及插入到數據庫中,那不就丟數據了嘛。參考Redis的持久化策略,可以給插入數據這個操作添加一個操作日志,用于持久化插入操作,宕機重啟后從日志恢復。
這樣設計架構就變成了這個樣子:
上邊這種解決方式,實際上就是HBase實現的大致思路,詳細的內容會在后邊慢慢說。
簡單粗暴總結:HBase就是一個面向列存儲的非關系型數據庫
。兩者的區別主要是:
HBase是的存儲時基于HDFS
的,HDFS有著高容錯性的特點,被設計用來部署在低廉的硬件上,而且它提供高吞吐量以訪問應用程序的數據,基于Hadoop意味著HBase與生俱來的超強的擴展性
和吞吐量
。
HBase采用的時key/value
的存儲方式,這意味著,即使隨著數據量的增大,也幾乎不會導致查詢性能的下降。HBase又是一個面向列
存儲的數據庫,當表的字段很多時,可以把其中幾個字段獨立出來放在一部分機器上,而另外幾個字段放到另一部分機器上,充分分散了負載的壓力。如此復雜的存儲結構和分布式的存儲方式,帶來的代價就是:即便是存儲很少的數據,也不會很快。
HBase并不是足夠快,而是數據量很大的時候它慢的不明顯。什么時候使用HBase呢,主要是以下兩種情況:
單表數據量超過千萬,而且并發量很大;
數據分析需求較弱,或者不需要那么實時靈活。
官方網站:http://hbase.apache.org
HBase的原型是Google的BigTable論文,受到了該論文思想的啟發,目前作為Apache的頂級項目來開發維護,用于支持結構化的數據存儲。
海量存儲
Hbase適合存儲PB級別的海量數據,在PB級別的數據以及采用廉價PC存儲的情況下,能在幾十到百毫秒內返回數據。這與Hbase的極易擴展性息息相關。正是因為Hbase良好的擴展性,才為海量數據的存儲提供了便利。
列式存儲
這里的列式存儲其實說的是
列族
存儲,Hbase是根據列族
來存儲數據的。列族下面可以有非常多的列,列族在創建表的時候就必須指定。
極易擴展
Hbase的擴展性主要體現在兩個方面,一個是基于上層處理能力(RegionServer)的擴展,一個是基于存儲的擴展(HDFS)。
通過橫向添加RegionSever的機器,進行水平擴展,提升Hbase上層的處理能力,提升Hbsae服務更多Region的能力。
備注:RegionServer的作用是管理region、承接業務的訪問,這個后面會詳細的介紹通過橫向添加Datanode的機器,進行存儲層擴容,提升Hbase的數據存儲能力和提升后端存儲的讀寫能力。
高并發
由于目前大部分使用Hbase的架構,都是采用的廉價PC,因此單個IO的延遲其實并不小,一般在幾十到上百ms之間。這里說的高并發,主要是在并發的情況下,Hbase的單個IO延遲下降并不多。能獲得高并發、低延遲的服務。
稀疏
稀疏主要是針對Hbase列的靈活性,在列族中,你可以指定任意多的列,在列數據為空的情況下,是不會占用存儲空間的。
先從邏輯思維上對HBase的存儲有個大致的理解:
Table(表):
一個表由一個或者多個`列族構成。數據的屬性。比如:name、age、TTL(超時時間)等等都在列族里邊定義。定義完列族的表是個空表,只有添加了數據行以后,表才有數據。
Column Family(列族):
在HBase里,可以將多個列
組合
成一個列族。建表的時候不用創建列,因為列是可增減變化
的,非常靈活。唯一需要確定的就是列族
,也就是說一個表有幾個列族是一開始就定好的。此外表的很多屬性,比如數據過期時間、數據塊緩存以及是否使用壓縮等都是定義在列族上的,而不是定義在表上或者列上。這一點與以往的關系型數據庫有很大的差別。列族存在的意義是
:HBase會把相同列族的列盡量放在同一臺機器上,所以說想把某幾個列放在一臺服務器上,只需要給他們定義相同的列族。
Row(行):
一個行包含多個列,這些列通過列族來分類。行中的數據所屬的列族從該表所定義的列族中選取,不能選擇這個表中不存在的列族。由于HBase是一個
面向列存儲的數據庫
,所以一個行中的數據可以分布在不同的服務器上
。
RowKey(行鍵):
rowkey和MySQL數據庫的主鍵比起來簡單很多,rowkey
必須要有
,如果用戶不指定的話,會有默認的。rowkey完全是由用戶指定的一串不重復的字符串,另外,rowkey按照字典排序
。一個rowkey對應的是一行數據!!!
Region:
Region就是一段數據的
集合
。之前提到過高表的概念,把高表進行水平切分,假設分成兩部分,那么這就形成了兩個Region。注意一下Region的幾個特性:Region
不能
跨服務器,一個RegionServer可以有多個Region。
數據量小的時候,一個Region可以存儲所有的數據;但是當數據量大的時候,HBase會拆分
Region。
當HBase在進行負載均衡
的時候,也有可能從一臺RegionServer上把Region移動到另一服務器的RegionServer上。
Region是基于HDFS的,它的所有數據存取操作都是調用HDFS客戶端完成的。
RegionServer:
RegionServer就是
存放Region的容器
,直觀上說就是服務器上的一個服務。負責管理維護Region。
NameSpace:
命名空間,類似于關系型數據庫的
DatabBase
概念,每個命名空間下有多個表。HBase有兩個自帶的命名空間,分別是hbase
和default
,hbase 中存放的是 HBase 內置的表,default 表是用戶默認使用的命名空間。
Row:
HBase 表中的每行數據都由一個
RowKey
和多個Column
(列)組成,數據是按照 RowKey 的字典順序存儲的,并且查詢數據時只能根據 RowKey 進行檢索
,所以 RowKey 的設計十分重要。
Column :
HBase 中的每個列都由 Column Family(列族)和 Column Qualifier(列限定符)進行限 定,例如 info:name,info:age。建表時,只需指明列族,而列限定符無需預先定義。
TimeStamp:
時間戳,用于標識數據的不同版本(version),每條數據寫入時,如果不指定時間戳,系統會自動為其加上該字段,其值為寫入 HBase 的時間。并且讀取數據的時候一般只拿出數據的Type符合,時間戳最新的數據。HBase中通過Type來標識數據是否可用。
因為HBase是基于HDFS的而HDFS是可以增刪查而不支持改的
。
Cell:
單元格,由{rowkey, column Family:column Qualifier, time Stamp} 唯一確定的單元。cell 中的數據是
沒有
類型的,全部是字節碼
形式存儲。
傳統關系型數據庫的表結構圖如下:
其中每行都是不可分割的,也正是體現了數據庫第一范式的原子性,也就是說三個列必須在一起,而且要被存儲在同一臺服務器上,甚至是同一個文件里面。
HBase的表架構如圖所示:
HBase的每一個行都是離散的,因為列族的存在,所以一個行里面不同的列甚至被分配到了不同的服務器上。行的概念被減弱到了一個抽象的存在。在實體上,把多個列定義為一個行的關鍵詞rowkey,也就是行這個概念在HBase中的唯一體現。
HBase的存儲語句中必須·精確·的寫出要將數據存放到哪個單元格,單元格由表:列族:行:列來唯一確定。用人話說就是要寫清楚數據要被存儲在哪個表的哪個列族的哪個行的哪個列。如果一行有10列,那么存儲一行的數據就需要寫明10行的語句。
從這張圖上可以看到是一個HBase集群由一個Master
(也可配置成多個,搞成HA)和多個RegionServer
組成,之后再詳細介紹RegionServer的架構。上面的圖示說明了HBase的服務器角色構成,下邊給出具體的介紹:
Master:
負責啟動的時候分配
Region
到具體的RegionServer
,執行各種管理操作,比如Region的分割
與合并
。在HBase中,master的角色地位比其他類型的集群弱很多。數據的讀寫操作與他沒有關系,它掛了之后,集群照樣運行。具體的原因后邊后詳細介紹。但是master也不能宕機太久,有很多必要的操作,比如創建表、修改列族配置主要是DDL
,以及更重要的分割
與合并
都需要它的操作。
RegionServer:
RegionServer就是一臺機器,在它上邊有多個
region
。我們讀寫的數據就存儲在Region
中。
Region:
它是表拆分出來的一部分,HBase是一個會自動切片的數據庫。當數據庫過高時,就會進行拆分。
HDFS:
HBase的數據存儲是基于HDFS的,它是真正承載數據的載體。
Zookeeper:
在本集群中負責存儲
hbase:meata
的位置存儲信息,客戶端在寫數據時需要先讀取元數據信息。
在宏觀架構圖的最后一個RegionServer
中可以看到 ,它的內部是多個Region的集合:
現在我們放大一下這個RegionServer的內部架構:
一個WAL:
跟HDFS中的edits文件存在的意義一樣
WAL時
Write-Ahead Log
的縮寫,翻譯為預寫入日志
。從名字大概也能猜出它的作用,當操作到達Region的時候,HBase先把操作寫入到WAL中,然后把數據放入到基于內存實現的MemStore
中,等到一定的時機再把數據刷寫
形成HFile文件,存儲到HDFS上。WAL是一個保險機制,數據在寫到MemStore之前,先寫到WAL中,這樣如果在刷寫過程中出現事故,可以從WAL恢復數據。
多個Region:
Region已經多次提到了,它就時是數據庫的一部分,每一個Region都有起始的rowkey和結束的rowkey,代表了它存儲的row的范圍。
我們再放大Region的內部結構:
從圖中可以看的出來,一個Region包含 多個Store:一個Region有多個Store,一個Store就是對應一個列族的數據
,如圖就有三個列族
。再從最后一個Store中我們又可以看出,Store是由MemStore和HFile
組成的。
預寫入日志就是設計來解決宕機之后的操作恢復問題的,WAL是保存在HDFS上的持久化文件。數據到達Region的時候,先寫入WAL,然后被加載到MemStore中。這樣就算Region宕機了,操作沒來得及執行持久化,也可以再重啟的時候從WAL加載操作并執行。
如何啟用WAL?
WAL是默認開啟的,也可以手動關閉它,這樣增刪改操作會快一點。但是這樣做犧牲的是數據的安全性,所以不建議關閉。
關閉方法:
Mutation.setDurability(Durability.SKIP_WAL)
異步寫入WAL
如果不惜通過關閉WAL來提高性能的話,還可以考慮一下折中的方案:異步寫入WAL。
正常情況下,客戶端提交的put、delete、append操作來到Region的時候,先調用HDFS的客戶端寫到WAL中。哪怕只有一個改動,也會調用HDFS的接口來寫入數據??梢韵胂蟮?這種方式盡可能的保證了數據的安全性,代價這種方式頻繁的消耗資源。
如果不想關閉WAL,又不想每次都耗費那么大的資源,每次改動都調用HDFS客戶端,可以選擇異步
的方式寫入WAL:
Mutation.setDurability(Durability.ASYNC_WAL)
這樣設定以后,Region會等到條件滿足的時候才將操作寫到WAL。這里的條件指的是間隔多久,寫一次,默認的時間間隔是1s。
如果異步寫入數據的時候出錯了怎么辦呢?比如客戶端的操作現在在Region內存中,由于時間間隔未到1s,操作還沒來得及寫入到WAL,Region掛了(邪門不?就差那么一丟丟不到1s)。出錯了是沒有任何事務可以保證的。
WAL滾動
之前學習過MapReduce的shuffle
機制,所以猜得到WAL是一個喚醒的滾動日志數據結構
,因為這種結構不會導致占用的空間持續變大,而且寫入效率也最高。
通過wal日志切換,這樣可以避免產生單獨的過大的wal日志文件,這樣可以方便后續的日志清理(可以將過期日志文件直接刪除)另外如果需要使用日志進行恢復時,也可以同時解析多個小的日志文件,縮短恢復所需時間。
WAL的檢查間隔由hbase.regionserver.logroll.period定義,默認值是一個小時。檢查的內容是把當前WAL中的操作跟實際持久化到HDFS上的操作做比較,看哪些操作已經被持久化了,如果已經被持久化了,該WAL就會被移動到HDFS上的.oldlogs文件夾下。
一個WAL實例包含多個WAL文件。WAL文件的最大數量可以手動通過參數配置。
其它的觸發滾動的條件是:
WAL的大小超過了一定的閾值。
WAL文件所在的HDFS文件塊快要滿了。
WAL歸檔和刪除
歸檔:WAL創建出來的文件都會放在/hbase/.log下,在WAL文件被定為歸檔時,文件會被移動到/hbase/.oldlogs下
刪除:判斷:是否此WAL文件不再需要,是否沒有被其他引用指向這個WAL文件
會引用此文件的服務:
TTL進程:該進程會保證WAL文件一直存活直到達到hbase.master.logcleaner.ttl定義的超時時間(默認10分鐘)為止。
備份(replication)機制:如果你開啟了HBase的備份機制,那么HBase要保證備份集群已經完全不需要這個WAL文件了,才會刪除這個WAL文件。這里提到的replication不是文件的備份數,而是0.90版本加入的特性,這個特性用于把一個集群的數據實時備份到另外一個集群。如果你的手頭就一個集群,可以不用考慮這個因素。
只有當該WAL文件沒有被以上兩種情況引用的時候,才會被系統徹底清除掉
解釋完了WAL,放大一下Store的內部架構:
Store有兩個重要的部分:
MemStore:
每個Store都有一個MemStore實例。數據寫入到WAL之后就會被放入MemStore中。MemStore是內存的存儲對象,只有到達一定的時機才會被刷寫到HFile中去。
HFile:
在Store中有多個HFile,每次刷寫都會形成一個HFile文件落盤在HDFS上。HFile直接跟HDFS打交道,它是數據存儲的實體。
這里提出一點疑問:
客戶端的操作到達Region時,先將數據寫到WAL中,而WAL是存儲在HDFS上的。所以就相當于數據已經持久化了,那么為什么還要從WAL加載到MemStore中,再刷寫形成HFile存到HDFS上呢?
簡單的說就是:數據進入HFile之前就已經被持久化了,為什么還要放入MemStore?
這是因為HDFS支持文件的創建、追加、刪除,但是不能修改
。對于一個數據庫來說,數據的順序是非常重要的。第一次WAL的持久化是為了保證數據的安全性,無序的。再讀取到MemStore中,是為了排序后存儲
。所以MemStore的意義在于維持數據按照rowkey的字典序排列
,而不是做一個緩存提高寫入效率。
補一張圖,對比著來看,關于MemStore刷寫:
從圖中可以看出Hbase是由Client
、Zookeeper
、Master
、HRegionServer
、HDFS
等幾個組件組成,并且如果做DML的操作是不需要關心HMaster的,只需要從ZK中獲得必備meta數據地址,然后從RegionServer
中增刪查數據即可。下面來介紹一下幾個組件的相關功能:
Client
Client包含了訪問Hbase的接口,另外Client還維護了對應的cache來加速Hbase的訪問,比如cache的.META.元數據的信息。
Zookeeper
HBase通過Zookeeper來做master的
高可用
、RegionServer的監控
、元數據的入口以及集群配置的維護等工作。具體工作如下:
通過Zoopkeeper來保證集群中只有
1個master在運行,如果master異常,會通過競爭機制產生新的master提供服務
通過Zoopkeeper來監控RegionServer的狀態,當RegionSevrer有異常的時候,通過回調的形式通知MasterRegionServer上下線的信息
通過Zoopkeeper存儲元數據
的統一入口地址
Hmaster
master節點的主要職責如下:
為RegionServer分配Region
維護整個集群的負載均衡
維護集群的元數據信息
發現失效的Region,并將失效的Region分配到正常的RegionServer上
當RegionSever失效的時候,協調對應Hlog的拆分
HregionServer
HregionServer直接對接用戶的讀寫請求,是真正的干活
的節點。它的功能概括如下:
管理master為其分配的Region
處理來自客戶端的讀寫請求
負責和底層HDFS的交互,存儲數據到HDFS
負責Region變大以后的拆分
負責Storefile的合并工作
HDFS
HDFS為Hbase提供最終的底層數據存儲服務,HBase底層用HFile格式(跟hadoop底層的數據存儲格式類似)將數據存儲到HDFS中,同時為HBase提供高可用(Hlog存儲在HDFS)的支持,具體功能概括如下:
提供元數據和表數據的底層分布式存儲服務
數據多副本,保證的高可靠和高可用性
“Hbase是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注本站網站,小編將為大家輸出更多高質量的實用文章!
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...
2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...
:喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...
樓面地價的計算方式是什么?地價也可以簡單理解為在土地上建房后單價中包含的土地成本。1.地價的計算公式:樓層價格=總地價規劃建筑面積=單位地價規劃容積率。規劃建筑面積=土地面積容積率。容積率=地上建筑總面積規劃用地面積。2.例如:2009年12月26日拍賣的2009-22號地塊。土地面積13145平方米,綠地率 25%,建筑密度 25%,建筑高度80米,容積率3.2。最后,成交價格為4.63億元。底...
什么是支付手段?支付手段是指貨幣用于清償債務、支付賦稅、租金、工資等的職能。這一職能是為適應商品生產和商品交換發展的需要而發展起來的。由于商品生產和商品交換在時空上的差異,就產生了商品使用價值的讓渡與商品價值的實現在時間上分離開來的客觀必然性。某些商品消費者在需要購買時沒有貨幣,只有到將來某一時間才有支付能力,同時,某些商品生產者又急需出售其商品,于是就產生了賒購賒銷。支付手段是指在交易過程中交易...
據了解,2021年12月31日20:30,羅振宇將準時獨自登臺,為大家奉上一場“特殊的跨年演講”,深圳衛視、抖音、西瓜視頻和得到APP全程直播。12月28日消息,得到App微博宣布,因疫情防控,得到App創始人羅振宇的跨年演講《時間的朋友》將不能安排觀眾進場,已啟動退票程序。不過羅振宇將準時登臺,他將面對12000個空座位用最大的心力為大家奉上一場特殊的跨年演講。對于此次跨...