一、Hbase數據庫介紹
1、簡介
HBase 是 BigTable 的開源 java 版本。是建立在 HDFS 之上,提供高可靠性、高性能、列存儲、 可伸縮、實時讀寫 NoSQL 的數據庫系統。
NoSQL = NO SQL
NoSQL = Not Only SQL
把 NoSQL 數據的原生查詢語句 封裝成 SQL
HBase Phoenix
以下五點是 HBase 這個 NoSQL 數據庫的要點:
① 它介於 nosql 和 RDBMS 之間,僅能通過主鍵(row key)和主鍵的 range 來檢索數據,僅支 持單行事務(可通過 hive 支持來實現多表 join 等復雜操作)。
② Hbase 查詢數據功能很簡單, 不支持 join 等復雜操作
③ 不支持復雜的事務(行級的事務)
④ Hbase 中支持的數據類型: byte[]
⑤ 主要用來存儲結構化和半結構化的松散數據。
結構化:數據結構字段含義確定,清晰,典型的如數據庫中的表結構.
半結構化:具有一定結構,但語義不夠確定,典型的如 HTML 網頁,有些字段是確定的(title), 有些不確定(table)
非結構化:雜亂無章的數據,很難按照一個概念去進行抽取,無規律性
與 hadoop 一樣, Hbase 目標主要依靠橫向擴展,通過不斷增加廉價的商用服務器,來增加 計算和存儲能力。
HBase 中的表一般有這樣的特點:
(1) 大:一個表可以有上十億行,上百萬列
(2) 面向列: 面向列(族)的存儲和權限控制,列(族)獨立檢索。 (同時對兩個列做處理,並不影響)
(3) 稀疏:對於為空(null)的列,並不占用存儲空間,因此,表可以設計的非常稀疏。
2、表結構邏輯視圖
HBase 以表的形式存儲數據。表有行和列組成。列划分為若干個列簇 (column family) 建表語句只需表名和列族名
3、RowKey
與 nosql 數據庫們一樣,row key 是用來檢索記錄的主鍵。訪問 hbase table 中的行,只有三種 方式:
(1) 通過單個 row key 訪問
(2) 通過 row key 的 range
(3) 全表掃描
Row key 行鍵 (Row key)可以是任意字符串(最大長度是 64KB,實際應用中長度一般為 10-100bytes), 最好是 16或者8。 在 hbase 內部, row key 保存為字節數組。 Hbase 會對表中的數據按照 rowkey 排序(字典順序)
存儲時,數據按照 Row key 的字典序(byte order)排序存儲。設計 key 時,要充分排序存儲這 個特性,將經常一起讀取的行存儲放到一起。 (位置相關性)
注意:
字典序對 int 排序的結果是
1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,„,9,91,92,93,94,95,96,97,98,99。要保持整形的自 然序,行鍵必須用 0 作左填充。
行的一次讀寫是原子操作 (不論一次讀寫多少列)。這個設計決策能夠使用戶很容易的理解 程序在對同一個行進行並發更新操作時的行為。
4、列簇
hbase 表中的每個列,都歸屬與某個列族。列族是表的 schema 的一部分(而列不是),必須在 使用表之前定義。
列名都以列族作為前綴。例如 courses:history , courses:math 都屬於 courses 這個列族。 訪問控制、磁盤和內存的使用統計都是在列族層面進行的。
列族越多,在取一行數據時所要參與 IO、搜尋的文件就越多,所以,如果沒有必要,不要 設置太多的列族
(每個列族存放在不同的文件中,建表時列族越少越好)
5、時間戳
HBase 中通過 row 和 columns 確定的為一個存儲單元稱為 cell。每個 cell 都保存着同一份數 據的多個版本。版本通過時間戳來索引。時間戳的類型是 64 位整型。時間戳可以由 hbase(在 數據寫入時自動 )賦值,此時時間戳是精確到毫秒的當前系統時間。時間戳也可以由客戶顯
式賦值。如果應用程序要避免數據版本沖突,就必須自己生成具有唯一性的時間戳。每個 cell 中,不同版本的數據按照時間倒序排序,即最新的數據排在最前面。
為了避免數據存在過多版本造成的的管理 (包括存貯和索引)負擔, hbase 提供了兩種數據版 本回收方式:
保存數據的最后 n 個版本
保存最近一段時間內的版本(設置數據的生命周期 TTL)。
用戶可以針對每個列族進行設置。
6、cell
由{row key, column( =<family> + <label>), version} 唯一確定的單元。
cell 中的數據是沒有類型的,全部是字節碼形式存貯。
二、Hbase集群架構
三、hbase集群搭建
1、安裝步驟:
先安裝zookeeper集群
10、 如果有節點相應的進程沒有啟動,那么可以手動啟動
hbase-daemon.sh start master
hbase-daemon.sh start regionserver
四、hbase命令行演示
1、 先進入 hbase shell 命令行
在你安裝的隨意台服務器節點上,執行命令: hbase shell,會進入到你的 hbase shell 客 戶端
2、 進入之后先別着急,先看一下提示。 其實是不是有一句很重要的話:
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
意在告訴怎么獲得幫助,怎么退出客戶端
help 獲取幫助
help 獲取所有命令提示
help "dml" 獲取一組命令的提示
help "put" 獲取一個單獨命令的提示幫助
exit 退出 hbase shell 客戶端
3、下面真正進入命令的演示
(1)顯示hbase中的表: list
(2) 第一個表名,多個列簇:
create 'user_info',{NAME=>'base_info',VERSION=>3 },{NAME=>'extra_info',VERSION=>1 }
put 'user_info', 'user0000', 'base_info:name', 'luoyufeng'
put 'user_info', 'user0000', 'base_info:age', '18'
put 'user_info', 'user0000', 'base_info:gender', 'female'
put 'user_info', 'user0000', 'extra_info:size', '34'
獲取數據:get 'user_info', 'user0000'
(3)查看集群狀態 status 查看集群的版本信息version
4、(1)ddl操作
列出所有表 :list
創建表:create 'user', 'info1', 'data1' 表名:user,包含info1和data1兩個列簇
或者 create 'table_test1',{NAME => 'cf1', VERSIONS => 3}, {NAME => 'cf2', VERSIONS => 2} 好處就是可以方便我們給表的每個列簇設置一些屬性,如果按照上面的方 式創建,那就表示所有的列簇的屬性都是取默認值
查看表的詳細信息:desc 'user'
alter修改表的定義:
增加列簇:alter 'table','liezu' 或者alter 'table_test', {NAME => 'another_family', VERSIONS => 4}
刪除列簇:alter 'table_test', {NAME => 'another_family', METHOD => 'delete'} 或者 alter 'table_test', 'delete' => 'add_family'
查看表存在不存在:exists 'table'
disable 使表失效
enable 啟用表
is_disabled 判斷表是否是失效狀態
is_enabled 判斷表是否是啟用狀態 (刪除表之前先使表失效)
刪除表:drop 'table'
(2)dml操作
put插入數據: put 'table_test','rk01','cf1:name','huangbo' 或者 put 'table_test','rk01','cf1:age',20,1482077777777 時間戳是可以自己指定的,如若不指定,則會自動獲取系統的當前時間的時間戳
get獲取數據:
get 'table_test','rk01 從 table_test 表中查 rowkey 為 rk01 的所有列簇的所有數據
get 'table_test','rk01','cf1:name' 從 table_test 表中查 rowkey 為 rk01 的列為 cf1:name 的最新數據
get 'table_test','rk01',{COLUMNS => 'cf1:name', VERSIONS => 3} 從 table_test 表中查 rowkey 為 rk01 的列為 cf1:name 的所有版本數據, 3 個版本
scan查看某表的數據:
scan 'table_test'
scan 'table_test',{COLUMNS => 'cf1:name'}
scan 'table_test',{COLUMNS => 'cf1:name', TIMESTAMP => 1482018424571}
scan 'user', {COLUMNS => 'info:name', VERSIONS => 5}
scan 'user', {COLUMNS => ['info', 'data'], FILTER => "(QualifierFilter(=,'substring:a'))"} 查詢 user 表中列族為 info 和 data 且列標示符中含有 a 字符的信息
scan 'people', {COLUMNS => 'info', STARTROW => 'rk0001', ENDROW => 'rk0003'} 查詢 user 表中列族為 info, rk 范圍是[rk0001, rk0003)的數據
scan 'user',{FILTER=>"PrefixFilter('rk')"} 查詢 user 表中 row key 以 rk 字符開頭的
scan 'user', {TIMERANGE => [1392368783980, 1392380169184]} 查詢 user 表中指定范圍的數據
scan 'car',{LIMIT=>10}
delete刪除數據:
delete 'people', 'rk0001', 'info:name' 刪除 user 表 row key 為 rk0001,列標示符為 info:name 的數據
delete 'user', 'rk0001', 'info:name', 1392383705316 刪除 user 表 row key 為 rk0001,列標示符為 info:name, timestamp 為 1392383705316 的數據
清空表中數據:truncate 'table'
過濾器:
get 'person', 'rk0001', {FILTER => "ValueFilter(=, 'binary:中國')"}
get 'person', 'rk0001', {FILTER => "(QualifierFilter(=,'substring:a'))"}
scan 'person', {COLUMNS => 'info:name'}
scan 'person', {COLUMNS => ['info', 'data'], FILTER => "(QualifierFilter(=,'substring:a'))"}
scan 'person', {COLUMNS => 'info', STARTROW => 'rk0001', ENDROW => 'rk0003'}
scan 'person', {COLUMNS => 'info', STARTROW => '20140201', ENDROW => '20140301'}
scan 'person', {COLUMNS => 'info:name', TIMERANGE => [1395978233636, 1395987769587]}
alter 'person', NAME => 'ffff'
alter 'person', NAME => 'info', VERSIONS => 10
get 'user', 'rk0002', {COLUMN => ['info:name', 'data:pic']}
修改表結構之前,先使表失效,修改完后,再啟用表
補充:
get和scan查看表中數據的區別:
get:指定rowkey獲取數據
scan:指定條件獲取一批數據