日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

基本介紹

HBase官網:https://hbase.Apache.org/。

Apache HBase 是 Hadoop中一個支持分布式的、可擴展的大數據存儲的數據庫。

當需要對大數據進行隨機、實時讀/寫訪問時,可以用 Apache HBase。

HBase特點

列式存儲:

HBase是面向列族的非關系型數據庫,每行數據列都可以不同,并且列可以按照需求進行動態增加。

因此在開始創建HBase表時,可以只創建列族,等需要時再創建相應的列。

數據壓縮:

列式存儲意味著數據往往類型相同,可以采用某種壓縮算法進行統一的壓縮存儲。

海量存儲:

HDFS支持的海量存儲,存儲PB級數據仍能有百毫秒內的響應速度。

基本操作

Shell操作

進入HBase客戶端命令操作界面:

hbase shell

查看幫助命令:

hbase(mAIn):001:0> help

查看當前數據庫中有哪些表:

hbase(main):006:0> list

創建一張表:

創建user表, 包含base_info、extra_info兩個列族。

hbase(main):007:0> create 'user', 'base_info', 'extra_info'
 
create 'user', {NAME => 'base_info', VERSIONS => '3'},{NAME => 'extra_info'}

添加數據操作:

向user表中插入信息,row key為 rk0001,列族base_info中添加name列標示符,值為zhangsan。

hbase(main):008:0> put 'user', 'rk0001', 'base_info:name', 'zhangsan'

向user表中插入信息,row key為rk0001,列族base_info中添加age列標示符,值為20。

hbase(main):010:0>  put 'user', 'rk0001', 'base_info:age', 20

查詢數據:

通過rowkey進行查詢:

  • 獲取user表中row key為rk0001的所有信息。
hbase(main):006:0> get 'user', 'rk0001'

查看rowkey下面的某個列族的信息:

  • 獲取user表中row key為rk0001,base_info列族的所有信息。
hbase(main):007:0> get 'user', 'rk0001', 'base_info'

查看rowkey指定列族指定字段的值:

  • 獲取user表中row key為rk0001,base_info列族的name、age列標示符的信息。
hbase(main):008:0> get 'user', 'rk0001', 'base_info:name', 'base_info:age'

查看rowkey指定多個列族的信息

  • 獲取user表中row key為rk0001,base_info、extra_info列族的信息。
hbase(main):010:0> get 'user', 'rk0001', 'base_info', 'extra_info'
 
hbase(main):011:0> get 'user', 'rk0001', {COLUMN => ['base_info', 'extra_info']}
 
hbase(main):012:0> get 'user', 'rk0001', {COLUMN => ['base_info:name', 'extra_info:address']}

指定rowkey與列值查詢:

  • 獲取user表中row key為rk0001,cell的值為zhangsan的信息。
hbase(main):013:0> get 'user', 'rk0001', {FILTER => "ValueFilter(=, 'binary:zhangsan')"}

指定rowkey與列值模糊查詢:

  • 獲取user表中row key為rk0001,列標示符中含有a的信息。
hbase(main):015:0> get 'user', 'rk0001', {FILTER => "(QualifierFilter(=,'substring:a'))"}

插入一批數據:

hbase(main):016:0> put 'user', 'rk0002', 'base_info:name', 'fanbingbing'

hbase(main):017:0> put 'user', 'rk0002', 'base_info:gender', 'female'

hbase(main):018:0> put 'user', 'rk0002', 'base_info:birthday', '2000-06-06'

hbase(main):019:0> put 'user', 'rk0002', 'extra_info:address', 'Shanghai'

查詢所有數據:

  • 查詢user表中的所有信息。
hbase(main):020:0> scan 'user'

列族查詢:

  • 查詢user表中列族為 base_info 的信息。

Scan:

  • 設置是否開啟Raw模式,開啟Raw模式會返回包括已添加刪除標記但是未實際刪除的數據。
  • VERSIONS指定查詢的最大版本數。
hbase(main):021:0> scan 'user', {COLUMNS => 'base_info'}

hbase(main):022:0> scan 'user', {COLUMNS => 'base_info', RAW => true, VERSIONS => 5}

多列族查詢:

  • 查詢user表中列族為info和data的信息。
hbase(main):023:0> scan 'user', {COLUMNS => ['base_info', 'extra_info']}
hbase(main):024:0> scan 'user', {COLUMNS => ['base_info:name', 'extra_info:address']}

指定列族與某個列名查詢:

  • 查詢user表中列族為base_info、列標示符為name的信息。
hbase(main):025:0> scan 'user', {COLUMNS => 'base_info:name'}

指定列族與列名以及限定版本查詢:

  • 查詢user表中列族為base_info、列標示符為name的信息,并且版本最新的5個。
hbase(main):026:0> scan 'user', {COLUMNS => 'base_info:name', VERSIONS => 5}

指定多個列族與按照數據值模糊查詢:

  • 查詢user表中列族為 base_info 和 extra_info且列標示符中含有a字符的信息。
hbase(main):027:0> scan 'user', {COLUMNS => ['base_info', 'extra_info'], FILTER => "(QualifierFilter(=,'substring:a'))"}

rowkey的范圍值查詢:

  • 查詢user表中列族為info,rk范圍是[rk0001, rk0003)的數據。
hbase(main):028:0> scan 'user', {COLUMNS => 'base_info', STARTROW => 'rk0001', ENDROW => 'rk0003'}

指定rowkey模糊查詢:

  • 查詢user表中row key以rk字符開頭的。
hbase(main):029:0> scan 'user',{FILTER=>"PrefixFilter('rk')"}

更新數據值:

  • 把user表中rowkey為rk0001的base_info列族下的列name修改為zhangsansan。
hbase(main):030:0> put 'user', 'rk0001', 'base_info:name', 'zhangsansan'

指定rowkey以及列名進行刪除:

  • 刪除user表row key為rk0001,列標示符為 base_info:name 的數據。
hbase(main):032:0>  delete 'user', 'rk0001', 'base_info:name'

指定rowkey,列名以及字段值進行刪除:

  • 刪除user表row key為rk0001,列標示符為base_info:name,timestamp為1392383705316的數據。
hbase(main):033:0> delete 'user', 'rk0001', 'base_info:age', 1564745324798

刪除 base_info 列族。

hbase(main):034:0> alter 'user', NAME => 'base_info', METHOD => 'delete'
 
hbase(main):035:0> alter 'user', 'delete' => 'base_info'

刪除user表數據:

hbase(main):036:0> truncate 'user'

刪除user表:

#先disable  再drop

hbase(main):036:0> disable 'user'
hbase(main):037:0> drop 'user'

#如果不進行disable,直接drop會報錯
ERROR: Table user is enabled. Disable it first.

數據模型

邏輯結構:

HBase詳細介紹及原理解析!

物理架構:

HBase詳細介紹及原理解析!

HBase詳細介紹及原理解析!

Rowkey(行鍵):

  • Table 的主鍵,Table 中的記錄按照 Rowkey 的字典序進行排序。

Column Family(列族):

  • 表中的每個列,都歸屬與某個列族。
  • 列族是表的 Schema 的一部分,必須在使用表之前定義。

Timestamp(時間戳):

  • 每次數據操作對應的時間戳,可以看作是數據的 Version 版本號。

Column(列):

  • 列族下面的具體列。
  • 屬于某一個 ColumnFamily,類似于 MySQL 當中創建的具體的列。

Cell(單元格):

  • 由{rowkey, column, version} 唯一確定的單元。
  • Cell 中的數據沒有類型,全部是以字節數組進行存儲。

基本原理

如何支持海量數據的隨機存取

利用了HDFS的分布式存儲和Hadoop的分布式計算能力:

  • 將數據存儲在HDFS上,并利用Hadoop的MapReduce框架進行分布式計算,從而實現了高可擴展性和高并發性。

將數據按照行和列族的方式存儲在HDFS上:

  • 這種數據存儲方式使得HBase能夠實現高速的隨機讀寫功能。

利用了LSM(Log-Structured Merge-Tree)算法:

  • 該算法通過內存和順序寫磁盤的方式,使得隨機寫入成為可能,同時還能保證讀取效率。

支持數據的自動分片和負載均衡:

  • 可以支持PB級別的數據存儲和處理,從而滿足大規模數據的實時處理需求。

整體結構

HBase詳細介紹及原理解析!

HMaster:

  • HBase集群的主節點,負責監控RegionServer,處理Region分配和負載均衡。

HRegionServer:

  • 管理 Region,處理對所分配Region的IO請求,Region是表的分片,由多個Store組成。

Zookeeper:

  • 維護HBase的運行狀態信息,如Region分布信息等。
  • HMaster和RegionServer都依賴Zookeeper。

HRegion:

  • HBase表的分片,由一個或者多個Store組成,存儲實際的表數據。

Store:

  • Store以Column Family為單位存儲數據,主要組成是MemStore和StoreFile(HFile)。
  • 1個Column Family的數據存放在一個Store中,一個Region包含多個Store。

MemStore:

  • 內存存儲,用于臨時存放寫數據,達到閾值后刷入StoreFile。
  • 數據會先寫入到 MemStore 進行緩沖,然后再把數據刷到磁盤。
  • 通過內存,也加快了讀寫速度。

StoreFile(HFile):

  • 磁盤上面真正存放數據的文件。

HDFS:

  • 用來持久化存儲HFiles。

一個列族就劃分成一個 Store,如果一個表中只有 1 個列族,那么每一個 Region 中只有一個 Store。

一個 Store 里面只有一個 MemStore。

一個 Store 里面有很多個 StoreFile, 最后數據是以很多個 HFile 文件保存在 HDFS 上。

  • StoreFile是HFile的抽象對象。
  • 每次 MemStore 刷寫數據到磁盤,就生成對應的一個新的 HFile 文件出來。

HBase詳細介紹及原理解析!

HBase詳細介紹及原理解析!

負載均衡

HBase 官方目前支持兩種負載均衡策略:

  • SimpleLoadBalancer 策略和 StochasticLoadBalancer 策略。

SimpleLoadBalancer 策略:

這種策略能夠保證每個 RegionServer 的 Region 個數基本相等。

假設集群中一共有 n 個 RegionServer,m 個 Region ,那么集群的平均負載就是 average = m/n。

  • 這種策略能夠保證所有 RegionServer 上的 Region 個數都在 [floor(average),ceil(average)]之間。

因此, SimpleLoadBalancer 策略中負載就是 Region 個數,集群負載遷移計劃就是 Region 從個數較多的 RegionServer 上遷移到個數較少的 RegionServer 上。

雖然集群中每個 RegionServer 的 Region 個數都基本相同,但如果某臺 RegionServer 上的 Region 全部都是熱點數據,導致 90 %的讀寫請求還是落在了這臺 RegionServer 上,這樣沒有達到負載均衡的目的。

StochasticLoadBalancer 策略:

它對于負載的定義不再是 Region 個數這么簡單,而是由多種獨立負載加權計算的復合值,這些獨立負載包括:

  • Region 個數,Region 負載,讀請求數,寫請求數,Storefile 大小,MemStore 大小,數據本地率,移動代價。

這些獨立負載經過加權計算會得到一個代價值,系統使用這個代價值來評估當前 Region 分布是否均衡,越均衡代價值越低。

  • HBase 通過不斷隨機挑選迭代來找到一組 Region 遷移計劃,使得代價值最小。

Flush機制

MemStore的大小超過某個值的時候,會Flush到磁盤,默認為128M。

MemStore中的數據時間超過1小時,會Flush到磁盤。

HRegionServer的全局MemStore的大小超過某大小會觸發Flush到磁盤,默認是堆大小的40%。

Compact機制

HBase需要在必要的時候將小的Store File合并成相對較大的Store File,這個過程為Compaction。

  • 為了防止小文件過多,以保證查詢效率。

在HBase中主要存在兩種類型的Compaction合并。

Minor Compaction 小合并:

  • 在將Store中多個HFile合并為一個HFile。
  • 這個過程中,達到TTL(記錄保留時間)會被移除,刪除和更新的數據僅僅只是做了標記,并沒有物理移除。
  • 這種合并的觸發頻率很高。

Major Compaction 大合并:

  • 合并Store中所有的HFile為一個HFile。
  • 這個過程有刪除標記的數據會被真正移除,同時超過單元格maxVersion的版本記錄也會被刪除。
  • 合并頻率比較低,默認7天執行一次,并且性能消耗非常大,建議生產關閉(設置為0),在應用空閑時間手動觸發。
  • 一般可以是手動控制進行合并,防止出現在業務高峰期。

Region拆分機制

Region 中存儲的是大量的 Rowkey 數據,當 Region 中的數據條數過多的時候,直接影響查詢效率。

  • 當 Region 過大的時候,HBase 會拆分 Region。

HBase 的 Region Split 策略一共有以下幾種。

ConstantSizeRegionSplitPolicy:

0.94版本前默認切分策略。

當Region大小大于某個閾值之后就會觸發切分,一個Region等分為2個Region。

  • 在生產線上這種切分策略有相當大的弊端:切分策略對于大表和小表沒有明顯的區分。

閾值設置較大對大表比較友好,但是小表就有可能不會觸發分裂,極端情況下可能就1個。

如果設置較小則對小表友好,但一個大表就會在整個集群產生大量的Region,這對于集群的管理、資源使用、Failover不好。

IncreasingToUpperBoundRegionSplitPolicy:

0.94版本~2.0版本默認切分策略。

總體看和ConstantSizeRegionSplitPolicy思路相同,一個Region大小大于設置閾值就會觸發切分。

  • 但這個閾值并不是一個固定的值。
  • 而是會在一定條件下不斷調整,調整規則和Region所屬表在當前RegionServer上的Region個數有關系。

Region Split的計算公式是:

  • RegionCount^3 * 128M * 2,當Region達到該size的時候進行split。

例如:

  • 第一次split:1^3 * 256 = 256MB
  • 第二次split:2^3 * 256 = 2048MB
  • 第三次split:3^3 * 256 = 6912MB
  • 第四次split:4^3 * 256 = 16384MB > 10GB,取較小的值10GB

后面每次split的size都是10GB了。

SteppingSplitPolicy:

  • 2.0版本默認切分策略。
  • 依然和待分裂Region所屬表在當前RegionServer上的Region個數有關系。
  • 如果Region個數等于1,切分閾值為flush size * 2,否則為MaxRegionFileSize。
  • 這種切分策略對于大集群中的大表。
  • 小表會比 IncreasingToUpperBoundRegionSplitPolicy 更加友好,小表不會再產生大量的小Region,而是適可而止。

KeyPrefixRegionSplitPolicy:

  • 根據RowKey的前綴對數據進行分組,這里是指定RowKey的前多少位作為前綴,比如RowKey都是16位的,指定前5位是前綴。
  • 那么前5位相同的RowKey在進行region split的時候會分到相同的Region中。

DelimitedKeyPrefixRegionSplitPolicy:

  • 保證相同前綴的數據在同一個Region中,例如RowKey的格式為:userid_eventtype_eventid,指定的delimiter為_。
  • 則split的的時候會確保userid相同的數據在同一個Region中。

DisabledRegionSplitPolicy:

不啟用自動拆分,需要指定手動拆分。

預分區

當一個table剛被創建的時候,HBase默認的分配一個Region給table。

  • 這時所有的讀寫請求都會訪問到同一個RegionServer的同一個Region中。
  • 這個時候就達不到負載均衡的效果了,集群中的其他RegionServer就可能會處于比較空閑的狀態。

解決辦法:

  • 可以用預分區(pre-splitting),在創建table的時候就配置好,生成多個Region。

如何預分區?

  • 每一個Region維護著startRow與endRowKey。
  • 如果加入的數據符合某個Region維護的RowKey范圍,則該數據交給這個Region維護。

手動指定預分區:

create 'person','info1','info2',SPLITS => ['1000','2000','3000','4000']
  • 1.

Region定位

HBase 支持 put , get , delete 和 scan 等基礎操作,所有這些操作的基礎是 region 定位。

region 定位基本步驟:

客戶端與 ZooKeeper 交互,查找 hbase:meta 系統表所在的 Regionserver。

hbase:meta 表維護了每個用戶表中 rowkey 區間與 Region 存放位置的映射關系,具體如下:

  • rowkey : table name,start key,region id。
  • value : RegionServer 對象(保存了 RegionServer 位置信息等)。

客戶端與 hbase:meta 系統表所在 RegionServer 交互,獲取 rowkey 所在的 RegionServer。

客戶端與 rowkey 所在的 RegionServer 交互,執行該 rowkey 相關操作。

需要注意:

  • 客戶端首次執行讀寫操作時才需要定位 hbase:meta 表的位置。
  • 之后會將其緩存到本地,除非因 region 移動導致緩存失效,客戶端才會重新讀取 hbase:meta 表位置,并更新緩存。

HBase詳細介紹及原理解析!

讀寫流程

讀操作:

首先從 ZooKeeper 找到 meta 表的 region 位置,然后讀取hbase:meta 表中的數據,hbase:meta 表中存儲了用戶表的 region 信息。

根據要查詢的 namespace 、表名和 rowkey 信息,找到寫入數據對應的 Region 信息。

找到這個 Region 對應的 RegionServer ,然后發送請求。

查找對應的 Region。

先從 MemStore 查找數據,如果沒有,再從 BlockCache 上讀取。

  • HBase 上 RegionServer 的內存分為兩個部分:
  • 一部分作為 MemStore,主要用來寫。
  • 另外一部分作為 BlockCache,主要用于讀數據。

如果 BlockCache 中也沒有找到,再到 StoreFile(HFile) 上進行讀取。

  • 從 StoreFile 中讀取到數據之后,不是直接把結果數據返回給客戶端,而是把數據先寫入到 BlockCache 中,目的是為了加快后續的查詢,然后在返回結果給客戶端。

HBase詳細介紹及原理解析!

寫操作:

首先從 ZooKeeper 找到 hbase:meta 表的 Region 位置,然后讀取 hbase:meta表中的數據,hbase:meta 表中存儲了用戶表的 Region 信息。

根據 namespace 、表名和 rowkey 信息找到寫入數據對應的 Region 信息。

找到這個 Region 對應的 RegionServer ,然后發送請求。

把數據分別寫到 HLog (WriteAheadLog)和 MemStore 各一份。

MemStore 達到閾值后把數據刷到磁盤,生成 StoreFile 文件。

刪除 HLog 中的歷史數據。

HBase詳細介紹及原理解析!

BulkLoad機制

用戶數據位于 HDFS 中,業務需要定期將這部分海量數據導入 HBase 系統,以執行隨機查詢更新操作。

這種場景如果調用寫入 API 進行處理,極有可能會給 RegionServer 帶來較大的寫人壓力。

  • 引起 RegionServer 頻繁 flush,進而不斷 compact、split,影響集群穩定性。
  • 引起 RegionServer 頻繁GC,影響集群穩定性。
  • 消耗大量 CPU 資源、帶寬資源、內存資源以及 IO 資源,與其他業務產生資源競爭。
  • 在某些場景下,比如平均 KV 大小比較大的場景,會耗盡 RegionServer 的處理線程, 導致集群阻塞。

所以HBase提供了另一種將數據寫入HBase集群的方法:BulkLoad。

BulkLoad 首先使用 MapReduce 將待寫入集群數據轉換為 HFile 文件,再直接將這些 HFile 文件加載到在線集群中。

BulkLoad 沒有將寫請求發送給 RegionServer 處理,可以有效避免上述一系列問題。

常見問題

熱點問題

什么是熱點?

檢索 HBase 的記錄首先要通過Row Key來定位數據行。

當大量的 Client 訪問 HBase 集群的一個或少數幾個節點,造成少數 Region Server 的讀/寫請求過多、負載過大,而其他Region Server 負載卻很小,就造成了 熱點 現象。

解決方案:

預分區:

  • 目的讓表的數據可以均衡的分散在集群中,而不是默認只有一個Region分布在集群的一個節點上。

加鹽:

  • 在Rowkey的前面增加隨機數,具體就是給Rowkey分配一個隨機前綴以使得它和之前的Rowkey的開頭不同。

哈希:

  • 哈希會使同一行永遠用一個前綴加鹽。
  • 也可以使負載分散到整個集群,但是讀是可以預測的。
  • 使用確定的哈希可以讓客戶端重構完整的Rowkey,可以使用get操作準確獲取某一個行數據。

反轉:

  • 反轉固定長度或者數字格式的Rowkey。
  • 這樣可以使得Rowkey中經常改變的部分放在前面。

分享到:
標簽:HBase
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定