從頭學習大數據培訓課程 NOSQL 資料庫 hbase(一)Hbase 概述與安裝、Hbase 原理和簡單的 shell 操作

1. HBASE安裝:

HMaster regionserver

(1).上傳hbase的壓縮包

(2).分發壓縮包

(3).解壓hbase的壓縮包

(4).創建軟連接

(5).修改所屬用戶

(6).修改環境變數

(7).備份配置目錄

(8).修改配置

regionservers 配置那些機器運行regionserver

hbase-env.sh

hbase-site.xml

(9).啟動與關閉

先啟動zookeeper

再啟動hdfs

start-hbase.sh

stop-hbase.sh

hbase-daemons.sh

(10).查看hbase的web界面

http://nn1.hadoop:60010

(11).hbase shell簡單測試

2. Hbase數據單元

RowKey:是Byte array,是表中每條記錄的「主鍵」,方便快速查找,Rowkey的設計非常重要

Column Family:列族,擁有一個名稱(string),包含一個或者多個相關列

Column:屬於某一個columnfamily,familyName:columnName,每條記錄可動態添加

Version Number:類型為Long,默認值是系統時間戳,可由用戶自定義

Value(Cell):Byte array

3. Hbase物理存儲結構

每個column family存儲在HDFS上的一個單獨文件中,空值不會被保存

Key 和 Version number在每個 column family中均有一份

HBase 為每個值維護了多級索引,即:<key, column family, column name, timestamp>

在物理層面上,表格的數據是通過StoreFile來存儲的,每個StoreFile相當於一個可序列化的Map,Map的key和value都是可解釋型字元數組

Column Family

是一組Column的組合,在HBase中,Schema的定義主要為Column Family的定義,同大多數nosql資料庫一樣,HBase也是支持自由定義Schema,但是前提要先定義出具體的Column Family,而在隨後的column定義則沒有任何約束

其次,HBase的訪問許可權控制,磁碟及內存統計等功能都是基於Column Family層面完成的

Timestamp

HBase提供基於Cell的版本管理功能,版本號默認通過timestamp來標識,並且呈倒敘排列

4. Hbase的整體架構

5. Hbase主要組件

Client:

包含訪問HBase的介面,並維護cache來加快對HBase的訪問,比如region的位置信息

Master

為Region server分配region

負責Region server的負載均衡

發現失效的Region server並重新分配其上的region

管理用戶對table的增刪改查操作

Region Server

維護region,處理對這些region的IO請求

Regionserver負責切分在運行過程中變得過大的region

Zookeeper

通過選舉保證集群中只有一個Master,Master與RegionServers 啟動時會向ZooKeeper註冊

存儲所有Region的定址入口

實時監控Region server的上線和下線信息,並實時通知給Master

存儲HBase的schema和table元數據

Zookeeper的引入使得Master不再是單點故障

6. 讀寫過程

尋找RegionServer

ZooKeeper--> -ROOT-(單Region)--> .META.--> 用戶表

根據namespace、表名和rowkey在meta表中找到對應的region信息

找到這個region對應的regionserver

讀操作

查找對應的region,先從MemStore找數據,如果沒有,再到StoreFile上讀

寫操作

把數據分別寫到HLog和MemStore上一份

MemStore達到一個閾值後則把數據刷成一個StoreFile文件

當多個StoreFile文件達到一定的大小後,會觸發Compact合併操作,合併為一個StoreFile,這裡同時進行版本的合併和數據刪除

當Compact後,逐步形成越來越大的StoreFIle後,會觸發Split操作

7. regionserver

HRegionServer內部管理了一系列HRegion對象,每個HRegion對應了Table中的一個Region,HRegion中由多個HStore組成

每個HStore對應了Table中的一個Column Family的存儲,可以看出每個Column Family其實就是一個集中的存儲單元,因此最好將具備共同IO特性的column放在一個Column Family中,這樣最高效

HStore存儲由兩部分組成,一部分是MemStore,一部分是StoreFiles

容錯與恢復

每個HRegionServer中都有一個HLog對象,HLog是一個實現Write Ahead Log的類,在每次用戶操作寫入MemStore的同時,也會寫一份數據到HLog文件中,HLog文件定期會滾動出新的,並刪除舊的文件(已持久化到StoreFile中的數據)

當HRegionServer意外終止後,HMaster會通過Zookeeper感知到,HMaster首先會處理遺留的HLog文件,將其中不同Region的Log數據進行拆分,分別放到相應region的目錄下,然後再將失效的region重新分配,領取到這些region的HRegionServer在LoadRegion的過程中,會發現有歷史HLog需要處理,因此會ReplayHLog中的數據到MemStore中,然後flush到StoreFiles,完成數據恢復

每個Region Server維護一個Hlog,而不是每個Region一個。這樣做的目的是不斷追加單個文件相對於同時寫多個文件而言,可以減少磁碟定址次數,因此可以提高對table的寫性能。帶來的麻煩是,如果一台Region Server下線,為了恢復其上的Region,需要將Region Server上的log進行拆分,然後分發到其它Region Server上進行恢復

8. Split 策略

上限配置

hbase.regionserver.regionSplitLimit 單台region數上限,默認值 2147483647

IncreasingToUpperBoundRegionSplitPolicy,默認region split策略。根據公式min(r^2*flushSize,maxFileSize)確定split的maxFileSize,其中r為在線region個數,maxFileSize由hbase.hregion.max.filesize指定

ConstantSizeRegionSplitPolicy,僅僅當region大小超過常量值(hbase.hregion.max.filesize大小)時,才進行拆分

DelimitedKeyPrefixRegionSplitPolicy,保證以分隔符前面的前綴為splitPoint,保證相同RowKey前綴的數據在一個Region中.如果定義rowkey時,採用_作為欄位分隔符(如:userid_eventid),則採用該策略拆分之後,能夠確保具有相同userid的記錄隸屬於同一Region

KeyPrefixRegionSplitPolicy,保證具有相同前綴的row在一個region中(要求設計中前綴具有同樣長度)。指定rowkey前綴位數劃分region,通過讀取table的prefix_split_key_policy.prefix_length屬性,該屬性為數字類型,表示前綴長度,在進行split時,按此長度對splitPoint進行截取。此種策略比較適合固定前綴的rowkey。當table中沒有設置該屬性,或其屬性不為Integer類型時,指定此策略效果等同與使用IncreasingToUpperBoundRegionSplitPolicy

hbase配置文件中定義全局的拆分策略,設置hbase.regionserver.region.split.policy,也可以在創建和修改表時候指定

如果想關閉自動拆分改為手動拆分,建議同時修改hbase.hregion.max.filesize和hbase.regionserver.region.split.policy值

9. hbase數據結構

傳統關係型數據普通索引就是採用B+樹的方式

B+樹最大的性能問題是會產生大量的隨機IO,隨著新數據的插入,葉子節點會慢慢分裂,邏輯上連續的葉子節點在物理上往往不連續,甚至分離的很遠,但做範圍查詢時,會產生大量讀隨機IO

LSM樹

為了克服B+樹的弱點,HBase引入了LSM樹的概念,即Log-Structured Merge-Trees

LSM樹本質上就是在讀寫之間取得平衡,和B+樹相比,它犧牲了部分讀性能,用來大幅提高寫性能

基本過程:把一顆大樹拆分成N棵小樹, 它首先寫入到內存中(內存沒有尋道速度的問題,隨機寫的性能得到大幅提升),在內存中構建一顆有序小樹,隨著小樹越來越大,內存的小樹會flush到磁碟上。當讀時,由於不知道數據在哪棵小樹上,因此必須遍歷所有的小樹,但在每顆小樹內部數據是有序的

為什麼要有WAL(Write Ahead Log)

因為數據是先寫到內存中,如果斷電,內存中的數據會丟失,因此為了保護內存中的數據,需要在磁碟上先記錄LogFile,當內存中的數據flush到磁碟上時,就可以拋棄相應的LogFile

什麼是MemStore, StoreFile

LSM樹就是一堆小樹,在內存中的小樹即MemStore,每次flush,內存中的MemStore變成磁碟上一個新的StoreFile

為什麼會有compact

隨著小樹越來越多,讀的性能會越來越差,因此需要在適當的時候,對磁碟中的小樹進行merge,多棵小樹變成一顆大樹

10. rowkey的設計

Row Key特點

Row Key可以是任意字元串,最大長度64KB,實際應用中一般為10~100bytes

RowKey是按照字典序存儲,因此,設計row key時,要充分利用這個排序特點,將經常一起讀取的數據存儲到一塊,將最近可能會被訪問的數據放在一塊

Row Key支持三種檢索方式

通過單個row key訪問:即按照某個row key鍵值進行get操作

通過row key的range進行scan:即通過設置startRowKey和endRowKey,在這個範圍內進行掃描

全表掃描:即直接掃描整張表中所有行記錄

Hbase中沒有joins的概念,大表的結構可以使得不需要joins

11. hbase的常用shell操作

常用的:

名稱

命令表達式

創建表

create 表名稱, 列簇名稱1,列簇名稱2,列簇名稱N

添加記錄

put 表名稱, 行名稱, 列名稱:, 值

查看記錄

get 表名稱, 行名稱

查看錶中的記錄總數

count 表名稱

刪除記錄

delete 表名 ,行名稱 , 列名稱

刪除一張表

先要屏蔽該表,才能對該表進行刪除,第一步 disable 表名稱 第二步 drop 表名稱

查看所有記錄

scan "表名稱"

查看某個表某個列中所有數據

scan "表名稱" , [列名稱:]

更新記錄

就是重寫一遍進行覆蓋

一般操作

(1).查詢伺服器狀態

status

(2).查詢版本

version

DDL操作

(1).創建一個表

create hainiu_table,column_famaly,column_famaly1,column_famaly2

(2).列出所有表

list

(3).獲得表的描述

describe hainiu_table

(4).刪除一個列族

alter hainiu_table,{NAME=>column_famaly,METHOD=>delete}

describe hainiu_table

(5).drop一個表

create hainiu_table1,column_famaly

list

drop hainiu_table1

(6).把表設置為disable

disable hainiu_table1

drop hainiu_table1

list

(7).查詢表是否存在

exists hainiu_table1

(8).判斷表是否enable

is_enabled hainiu_table

(9).判斷表是否disable

is_disabled hainiu_table

disable hainiu_table

is_disabled hainiu_table

DML操作

(1).插入幾條記錄

put hainiu_table,id,column_famaly1:name,hainiu

enable hainiu_table

put hainiu_table,id,column_famaly1:name,hainiu

put hainiu_table,id,column_famaly1:age,20

put hainiu_table,id,column_famaly1:sex,boy

(2).獲取一條數據

get hainiu_table,id

獲取一個id,一個列族的所有數據

get hainiu_table,id,column_famaly1

獲取一個id,一個列族中一個列的所有數據

get hainiu_table,id,column_famaly1:name

(3).更新一條記錄

put hainiu_table,id,column_famaly1:age,22

get hainiu_table,id,column_famaly1:age

(4).通過timestamp來獲取兩個版本的數據

get hainiu_table,id,{COLUMN=>column_famaly1:age,TIMESTAMP=>1496990409072}

get hainiu_table,id,{COLUMN=>column_famaly1:age,TIMESTAMP=>1496990610025}

(5).全表掃描

scan hainiu_table

(6).刪除行健為id的值的『column_famaly1:age』欄位

delete hainiu_table,id,column_famaly1:age

get hainiu_table,id

(7).刪除整行

deleteall hainiu_table,id

(8).查詢表中有多少行

count hainiu_table

put hainiu_table,id,column_famaly1:age,20

put hainiu_table,id,column_famaly1:name,hainiu

put hainiu_table,id,column_famaly2:name,hainiu2

put hainiu_table,id,column_famaly2:age,22

count hainiu_table

(9).給『id』這個行健增加column_famaly1:addr欄位,並使用counter實現遞增

incr hainiu_table,id,column_famaly1:addr

incr hainiu_table,id,column_famaly1:addr

get hainiu_table,id,column_famaly1:addr

incr hainiu_table,id,column_famaly1:addr

(10).獲取當前count的值

get_counter hainiu_table,id,column_famaly1:addr

(11).將整張表清空

truncate hainiu_table


推薦閱讀:

中華財寶:珠寶行業在大數據時代該如何前行?
AI時代:聊聊大數據中的MapReduce
獨家 | 一文帶你上手卷積神經網路實戰(附數據集&學習資料)
在輿情引導中發揮大數據技術優勢
MaxCompoute禁止Full Scan功能開放

TAG:HBase | 大數據 | NoSQL |