巨量資料技術之HBase原理與實戰歸納分享-上

2022-10-09 21:01:38

@

概述

定義

HBase 官網地址 https://hbase.apache.org/

HBase 官網檔案 https://hbase.apache.org/book.html

HBase GitHub原始碼地址 https://github.com/apache/hbase

Apache HBase™是以HDFS為資料儲存分散式的、可伸縮的Hadoop NoSQL資料庫。最新版本為2.5.0

HBase支援對巨量資料進行隨機、實時的讀寫存取,可以在商用硬體叢集上託管非常大的表——數十億行X數百萬列。Apache HBase是一個開源的、分散式的、版本化的、非關聯式資料庫,模仿了谷歌開發的Bigtable結構化資料的分散式儲存系統,與Bigtable利用了谷歌檔案系統提供的分散式資料儲存一樣,Apache HBase在Hadoop和HDFS的基礎上提供了類似Bigtable的功能。

特點

  • 可延伸性。
  • 讀寫嚴格一致。
  • 自動和可設定的表分片。
  • regionserver之間的自動故障轉移支援。
  • 使用Apache HBase表支援Hadoop MapReduce作業。
  • 易於使用Java API進行使用者端存取。
  • 塊快取和Bloom過濾器用於實時查詢。
  • 通過伺服器端過濾器下推查詢謂詞。
  • Thrift閘道器和一個支援XML、Protobuf和二進位制資料編碼選項的rest Web服務。
  • 可延伸的基於jruby (JIRB)的shell。
  • 支援通過Hadoop指標子模組匯出指標。

資料模型

概述

  • HBase的設計理念依據Coogle 的BigTable論文,論文中說到Bigtable 是一個稀疏的,分散式的,持久的多維排序map。
  • 對映由行鍵,列鍵和時間戳索引;對映中的每一個值都是一個未解釋的位元組陣列。
  • HBase資料模型和BigTable的對應關係如下
    • HBase 使用於 BigTable非常相似的資料模型,使用者將資料行儲存在帶標籤的表中,資料行具有可排序的鍵和任意數量的列。
    • 該表儲存稀疏,因此如果使用者喜歡,同一表中的行可以具有瘋狂變化的列

HBase 資料模型的關鍵在於稀疏、分散式、多維、排序的對映。其中對映 map 指代非關係型資料庫的 key-Value 結構。

邏輯結構

HBase 可以用於儲存多種結構的資料,以 JSON 為例:

{
	"row_key1":{
		"personal_info":{
			"name":"zhangsan",
			"city":"北京",
			"phone":"131********"
		},
		"office_info":{
			"tel":"010-1111111",
			"address":"atguigu"
		}
	},
    
	"row_key11":{
		"personal_info":{
			"city":"上海",
			"phone":"132********"
		},
		"office_info":{
			"tel":"010-1111111"
		}
	},
    
	"row_key2":{
	......
}

邏輯結構儲存資料稀疏,資料儲存多維,不同的行具有不同的列。資料儲存整體有序,按照RowKey的字典序排列,RowKey為Byte陣列,範例如下:

物理儲存結構

物理儲存結構即為資料對映關係,而在概念檢視的空單元格,底層實際根本不儲存。

資料模型

  • Name Space:名稱空間,類似於關係型資料庫的 database 概念,每個名稱空間下有多個表。HBase 兩個自帶的名稱空間,分別是 hbase 和default,hbase 中存放的是 HBase 內建的表,default表是使用者預設使用的名稱空間。
  • Table:類似於關係型資料庫的表概念。不同的是,HBase 定義表時只需要宣告列族即可,不需要宣告具體的列。因為資料儲存時稀疏的,所有往 HBase 寫入資料時,欄位可以動態、按需指定。因此和關係型資料庫相比,HBase 能夠輕鬆應對欄位變更的場景。
  • Row:HBase 表中的每行資料都由一個 RowKey 和多個 Column(列)組成,資料是按照 RowKey 的字典順序儲存的,並且查詢資料時只能根據 RowKey 進行檢索,所以 RowKey 的設計十分重要。
  • Column:HBase 中的每個列都由 Column Family(列族)和 Column Qualifier(列限定符)進行限定,例如 info:name,info:age。建表時,只需指明列族,而列限定符無需預先定義。
  • Time Stamp:用於標識資料的不同版本(version),每條資料寫入時,系統會自動為其加上該欄位, 其值為寫入 HBase 的時間。
  • Cell:由{rowkey, column Family:column Qualifier, timestamp} 唯一確定的單元。cell 中的資料全部是位元組碼形式儲存。

應用場景

  • 物件儲存:比如一些app的海量的圖片、網頁、新聞等物件,可以儲存在HBase中,有些病毒公司的病毒庫也可以儲存在HBase中。
  • 時空資料:主要是軌跡、氣象網格之類
    • 比如滴滴打車的軌跡資料主要存在HBase之中。
    • 另外巨量資料量的車聯網企業,資料也都是存在HBase中。
    • 比如網際網路出行,智慧物流與外賣遞送,感測網與實時GIS等場景。
  • 時序資料:時序資料就是分佈在時間上的一系列數值。
    • HBase之上有OpenTSDB模組,可以滿足時序類場景的需求。
    • 比如我們有很多的裝置、感測器,產生很多資料,如果規模不是特別大的廠家有幾千個風機,每個風機有幾百個指標,那麼就會有一百萬左右的時序資料,如果用取樣每一秒會產生一百萬個時間點,如果用傳統資料庫,那麼每一秒會產生一百萬次,持續地往MQ做一百萬次,它會崩裂。並且查詢也是個大問題,除了多維查詢以外,我們還會額外地增加時間緯度,檢視一段時間的資料。這時候HBase很好了滿足了時序類場景的需求。
  • 推薦畫像:特別是使用者的畫像,是一個比較大的稀疏矩陣,螞蟻的風控就是構建在HBase上。人物誌有使用者資料量大,使用者標籤多,標籤統計維度不確定等特點,適合HBase特性的發揮。
  • 訊息/訂單:在電信領域、銀行領域,不少的訂單查詢底層的儲存,另外不少通訊、訊息同步的應用構建在HBase之上。
  • Feed流:是RSS中用來接收該資訊來源更新的介面,簡單的說就是持續更新並呈現給使用者的內容。比如微信朋友圈中看到的好友的一條條狀態,微博看到的你關注的人更新的內容,App收到的一篇篇新文章的推播,都算是feed流。
  • NewSQL:HBase上有Phoenix的外掛,可以滿足二級索引、SQL的需求,對接傳統資料需要SQL非事務的需求。從NoSQL到NewSQL,Phoenix或許是新的趨勢。

基礎架構

組成角色包含如下幾個部分:

  • Master:實現類為 HMaster,負責監控叢集中所有的 RegionServer 範例。
    • 主要作用如下:
      • 管理後設資料表格 hbase:meta,接收使用者對錶格建立修改刪除的命令並執行
      • 監控 region 是否需要進行負載均衡,故障轉移和 region 的拆分。
    • 管理後設資料表格 hbase:meta,接收使用者對錶格建立修改刪除的命令並執行。
    • 監控 region 是否需要進行負載均衡,故障轉移和 region 的拆分。
    • 通過啟動多個後臺執行緒監控實現上述功能:
      • LoadBalancer 負載均衡器:週期性監控 region 分佈在 regionServer 上面是否均衡,由引數 hbase.balancer.period 控 制週期時間,預設 5 分鐘。
      • CatalogJanitor 後設資料管理器:定期檢查和清理 hbase:meta 中的資料。meta 表內容在進階介紹。
      • MasterProcWAL master 預寫紀錄檔處理器:把 master 需要執行的任務記錄到預寫紀錄檔 WAL 中,如果 master 宕機,讓 backupMaster 讀取紀錄檔繼續幹。
  • Region Server:Region Server 實現類為 HRegionServer,主要作用如下:
    • 負責資料 cell 的處理,例如寫入資料 put,查詢資料 get 等。
    • 拆分合並 region 的實際執行者,有 master 監控,有 regionServer 執行。
  • Zookeeper:HBase 通過 Zookeeper 來做 master 的高可用、記錄 RegionServer 的部署資訊、並且儲存 有 meta 表的位置資訊。 HBase 對於資料的讀寫操作時直接存取 Zookeeper 的,在 2.3 版本推出 Master Registry 模式,使用者端可以直接存取 master。使用此功能,會加大對 master 的壓力,減輕對 Zookeeper 的壓力。
  • HDFS:HDFS 為 Hbase 提供最終的底層資料儲存服務,同時為 HBase 提供高容錯的支援。

安裝

前置條件

  • Zookeeper(使用前面文章已部署叢集)
  • HDFS(使用前面文章已部署叢集)

部署

# 下載最新版本HBase
wget --no-check-certificate https://dlcdn.apache.org/hbase/2.5.0/hbase-2.5.0-bin.tar.gz
# 解壓
tar -xvf hbase-2.5.0-bin.tar.gz
# 進入目錄
cd hbase-2.5.0
# 設定環境變數
vim /etc/profile
export HBASE_HOME=/home/commons/hbase-2.5.0
export PATH=$HBASE_HOME/bin:$PATH
# 將組態檔分發到另外兩臺節點上
scp /etc/profile hadoop2:/etc/
scp /etc/profile hadoop3:/etc/
# 在三臺上執行環境變數生成命令
source /etc/profile
# 修改conf目錄下組態檔hbase-env.sh,
vim conf/hbase-env.sh
# false 取消 不需要自己管理範例 用zookeeper
export HBASE_MANAGES_ZK=false
# 宣告JAVA_HOME
export JAVA_HOME=/home/commons/jdk8
# HBase的jar包和Hadoop的jar包有衝突,導致服務沒有起來,報錯如object is not an instance of declaring class可以設定這個
export HBASE_DISABLE_HADOOP_CLASSPATH_LOOKUP="true"
  • 修改conf目錄下組態檔vim conf/hbase-site.xml
##修改,
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>
##去掉
  <property>
    <name>hbase.tmp.dir</name>
    <value>./tmp</value>
  </property>
  <property>
    <name>hbase.unsafe.stream.capability.enforce</name>
    <value>false</value>
  </property>
##增加
 <property>
   <name>hbase.zookeeper.quorum</name>
   <value>zk1,zk2,zk3</value>
   <description>The directory shared by RegionServers.
   </description>
 </property> 
<!-- <property>-->
<!-- <name>hbase.zookeeper.property.dataDir</name>-->
<!-- <value>/export/zookeeper</value>-->
<!-- <description> 記得修改 ZK 的組態檔 -->
<!-- ZK 的資訊不能儲存到臨時資料夾-->
<!-- </description>-->
<!-- </property>-->
 <property>
   <name>hbase.rootdir</name>
   <value>hdfs://hadoop2:9000/hbase</value>
     <!--8020這個埠號,要跟hadoop的NameNode一樣-->
   <description>The directory shared by RegionServers.
   </description>
 </property>
  • 修改regionservers設定vim conf/regionservers
hadoop1
hadoop2
hadoop3
  • 將Hadoop的組態檔core-site.xml和hdfs-site.xml拷貝到HBase的conf目錄下
cp /home/commons/hadoop/etc/hadoop/core-site.xml conf/
cp /home/commons/hadoop/etc/hadoop/hdfs-site.xml conf/
  • 分發HBase目錄到其他兩個節點上
scp -r /home/commons/hbase-2.5.0 hadoop2:/home/commons
scp -r /home/commons/hbase-2.5.0 hadoop3:/home/commons

啟動服務

# 單點啟動
bin/hbase-daemon.sh start master 
bin/hbase-daemon.sh start regionserver
# 群啟
bin/start-hbase.sh 
# 停止服務
bin/stop-hbase.sh

群啟後檢視服務程序

啟動成功後,可以通過「host:port」的方式來存取 HBase 管理頁面, http://hadoop1:16010

高可用

在 HBase 中 HMaster 負責監控 HRegionServer 的生命週期,均衡 RegionServer 的負載, 如果 HMaster 掛掉了,那麼整個 HBase 叢集將陷入不健康的狀態,並且此時的工作狀態並不 會維持太久。所以 HBase 支援對 HMaster 的高可用設定。

# 先關閉上面啟動的HBase叢集
bin/stop-hbase.sh 
# 在 conf 目錄下建立 backup-masters 檔案
touch conf/backup-masters 
# 在 backup-masters 檔案中設定高可用 HMaster 節點
echo hadoop2 > conf/backup-masters 
# 將conf/backup-masters scp 到其他節點
scp /home/commons/hbase-2.5.0/conf/backup-masters hadoop2:/home/commons/hbase-2.5.0/conf
scp /home/commons/hbase-2.5.0/conf/backup-masters hadoop3:/home/commons/hbase-2.5.0/conf
# 重啟 hbase
bin/start-hbase.sh 

群啟後檢視服務程序,發現多了一個master程序

[外連圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-EteyEUXe-1665312413397)(image-20221009125044450.png)]

開啟頁面測試另一臺master顯示其為備用的Master,主master還是ckserver1也即是hadoop1,檢視http://hadoop2:16010

[外連圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-IePncDF4-1665312413398)(image-20221009125144397.png)]

手動kill -9 殺死ckserver1也即是hadoop1上的HMaster程序,再次檢視http://hadoop2:16010,發現主master已經成功的切換為ckserver2也即是hadoop2

然後再單獨啟動ckserver1也即是hadoop1上的HMaster,執行bin/hbase-daemon.sh start master,這時存取http://hadoop1:16010,發現hadoop1為備用master。

Shell操作

基礎操作

# 進入 HBase 使用者端命令列hbase shell# 檢視幫助命令夠展示 HBase 中所有能使用的命令,主要使用的命令有 namespace 命令空間相關, DDL 建立修改表格,DML 寫入讀取資料。help

命令空間

# 使用特定的 help 語法能夠檢視命令如何使用。help 'create_namespace'# 建立名稱空間 testcreate_namespace 'test'# 檢視所有的名稱空間list_namespace

DDL

# 建立表,在test名稱空間中建立表格 student,兩個列族。info 列族資料維護的版本數為 5 個, 如果不寫預設版本數為 1。create 'test:student', {NAME => 'info', VERSIONS =>  5}, {NAME => 'msg'}# 如果建立表格只有一個列族,沒有列族屬性,可以簡寫。如果不寫名稱空間,使用預設的名稱空間 default。create 'student1','info'# 檢視表檢視表有兩個命令:list 和 describe,list:檢視所有的表名,describe:檢視一個表的詳情listdescribe 'student1'

# 修改表表名建立時寫的所有和列族相關的資訊,都可以後續通過 alter 修改,包括增加刪除列族。增加列族和修改資訊都使用覆蓋的方法alter 'student1', {NAME => 'f1', VERSIONS => 3} # 刪除資訊使用特殊的語法alter 'student1', NAME => 'f1', METHOD => 'delete' hbase:016:0> alter 'student1', 'delete' => 'f1'# shell 中刪除表格,需要先將表格狀態設定為不可用。disable 'student1' drop 'student1'

DML

# 寫入資料在 HBase 中如果想要寫入資料,只能新增結構中最底層的 cell。可以手動寫入時間戳指 定 cell 的版本,推薦不寫預設使用當前的系統時間,如果重複寫入相同 rowKey,相同列的資料,會寫入多個版本進行覆蓋。put 'test:student','1001','info:name','zhangsan' put 'test:student','1001','info:name','lisi' put 'test:student','1001','info:age','18' #讀取資料,讀取資料的方法有兩個:get 和 scan。get最大範圍是一行資料,也可以進行列的過濾,讀取資料的結果為多行 cell。get 'test:student','1001' get 'test:student','1001' , {COLUMN => 'info:name'} # 也可以修改讀取 cell 的版本數,預設讀取一個。最多能夠讀取當前列族設定的維護版本數。get 'test:student','1001' , {COLUMN => 'info:name',  VERSIONS => 6} # scan 是掃描資料,能夠讀取多行資料,不建議掃描過多的資料,推薦使用 startRow 和 stopRow 來控制讀取的資料,預設範圍左閉右開。scan 'test:student',{STARTROW => '1001',STOPROW =>  '1002'} # 刪除資料,刪除資料的方法有兩個:delete 和 deleteall;delete 表示刪除一個版本的資料,即為 1 個 cell,不填寫版本預設刪除最新的一個版本。delete 'test:student','1001','info:name'deleteall 'test:student','1001','info:name'

**本人部落格網站 **IT小神 www.itxiaoshen.com