Hbase和传统关系数据库的区别
Hbase | 关系型数据库 | |
---|---|---|
数据库大小 | PB级别 | GB TB |
数据类型 | Bytes | 丰富的数据类型 |
事务支持 | ACID只支持单个Row级别 | 全面的ACID支持,对Row和表 |
索引 | 只支持Row-key | 支持 |
吞吐量 | 百万写入/秒 | 数千写入/秒 |
关系型数据库中数据示例
ID | FILE NAME | FILE PATH | FILE TYPE | FILE SIZE | CREATOR |
---|---|---|---|---|---|
1 | File1.txt | /home | txt | 1024 | tom |
2 | File2.txt | /home/pics | Jpg | 5032 | jerry |
同样数据保存到列式数据库中
RowKey | FILE INFO | SAVE INFO |
---|---|---|
1 | name:file1.txt type:txt size:1024 | path:/home/pics creator:Jerry |
2 | name:file2.jpg type:jpg size:5032 | path:/home creator:Tom |
行数据库和列数据库存储方式比较
Cap定理
分布式系统的最大难点,就是各个节点的状态如何同步。CAP 定理是这方面的基本定理,也是理解分布式系统的起点。
hbase是CAP中的CP系统,即hbase是强一致性的
名称 | 命令表达式 |
---|---|
创建表 | create ‘表名’, ‘列族名1’,‘列族名2’,‘列族名n’ |
添加记录 | put ‘表名’,‘行名’,‘列名:’,'值 |
查看记录 | get ‘表名’,‘行名’ |
查看表中的记录总数 | count ‘表名’ |
删除记录 | delete ‘表名’, ‘行名’,‘列名’ |
删除一张表 | 第一步 disable ‘表名’ 第二步 drop ‘表名’ |
查看所有记录 | scan “表名称” |
查看指定表指定列所有数据 | scan ‘表名’ ,{COLUMNS=>‘列族名:列名’} |
更新记录 | 重写覆盖 |
连接集群
hbase shell
创建表
create 'user','base_info'
删除表
disable 'user'
drop 'user'
创建名称空间
create_namespace 'test'
展示现有名称空间
list_namespace
创建表的时候添加namespace
create 'test:user','base_info'
显示某个名称空间下有哪些表
list_namespace_tables 'test'
插入数据
put 'user','rowkey_10','base_info:username','Tom'
put 'user','rowkey_10','base_info:birthday','2014-07-10'
put 'user','rowkey_10','base_info:sex','1'
put 'user','rowkey_10','base_info:address','Tokyo'
put 'user','rowkey_16','base_info:username','Mike'
put 'user','rowkey_16','base_info:birthday','2014-07-10'
put 'user','rowkey_16','base_info:sex','1'
put 'user','rowkey_16','base_info:address','beijing'
put 'user','rowkey_22','base_info:username','Jerry'
put 'user','rowkey_22','base_info:birthday','2014-07-10'
put 'user','rowkey_22','base_info:sex','1'
put 'user','rowkey_22','base_info:address','Newyork'
put 'user','rowkey_24','base_info:username','Nico'
put 'user','rowkey_24','base_info:birthday','2014-07-10'
put 'user','rowkey_24','base_info:sex','1'
put 'user','rowkey_24','base_info:address','shanghai'
put 'user','rowkey_25','base_info:username','Rose'
put 'user','rowkey_25','base_info:birthday','2014-07-10'
put 'user','rowkey_25','base_info:sex','1'
put 'user','rowkey_25','base_info:address','Soul'
查询表中所有数据
scan 'user'
# HBase中一般存储数据量都很大 很少使用全表查询 scan会加上一些条件限制
Scan查询中添加限制条件
scan '名称空间:表名', {COLUMNS => ['列族名1', '列族名2'], LIMIT => 10, STARTROW => '起始的rowkey'} # 通过COLUMNS LIMIT STARTROW 等条件缩小查询范围
#LIMIT=>2 限制输出两行
scan 'user' ,{COLUMNS =>['base_info'],LIMIT=>2}
## 返回结果
ROW COLUMN+CELL
rowkey_10 column=base_info:address, timestamp=1558323139732, value=Tokyo
rowkey_10 column=base_info:birthday, timestamp=1558323139636, value=2014-07-10
rowkey_10 column=base_info:sex, timestamp=1558323139678, value=1
rowkey_10 column=base_info:username, timestamp=1558323918953, value=Tom4
rowkey_16 column=base_info:address, timestamp=1558323139963, value=beijing
rowkey_16 column=base_info:birthday, timestamp=1558323139866, value=2014-07-10
rowkey_16 column=base_info:sex, timestamp=1558323139907, value=1
#STARTROW 限制起始的Rowkey
scan 'user' ,{COLUMNS =>['base_info'],LIMIT=>2,STARTROW=>'rowkey_16'}
#返回结果:
ROW COLUMN+CELL
rowkey_16 column=base_info:address, timestamp=1558323139963, value=beijing
rowkey_16 column=base_info:birthday, timestamp=1558323139866, value=2014-07-10
rowkey_16 column=base_info:sex, timestamp=1558323139907, value=1
rowkey_22 column=base_info:address, timestamp=1558323140188, value=Newyork
rowkey_22 column=base_info:birthday, timestamp=1558323140107, value=2014-07-10
rowkey_22 column=base_info:sex, timestamp=1558323140143, value=1
rowkey_22 column=base_info:username, timestamp=1558323140036, value=Jerry
scan查询添加过滤器
ROWPREFIXFILTER rowkey 前缀过滤器
scan 'user', {ROWPREFIXFILTER=>'rowkey_22'}
#显示结果
ROW COLUMN+CELL
rowkey_22 column=base_info:address, timestamp=1558323140188, value=Newyork
rowkey_22 column=base_info:birthday, timestamp=1558323140107, value=2014-07-10
rowkey_22 column=base_info:sex, timestamp=1558323140143, value=1
rowkey_22 column=base_info:username, timestamp=1558323140036, value=Jerry
1 row(s)
Took 0.0120 seconds
查询某个rowkey的数据
get 'user','rowkey_16'
查询某个列族的数据
get 'user','rowkey_16','base_info'
get 'user','rowkey_16','base_info:username'
get 'user', 'rowkey_16', {COLUMN => ['base_info:username','base_info:sex']}
删除表中的数据
delete 'user', 'rowkey_16', 'base_info:username'
清空数据
truncate 'user'
操作列簇
alter 'user', NAME => 'f2'
alter 'user', 'delete' => 'f2'
HBase追加型数据库,会保留多个版本数据
desc 'user'
Table user is ENABLED
user
COLUMN FAMILIES DESCRIPTION
{NAME => 'base_info', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_B
HE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MI
ER => 'NONE', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOM
se', COMPRESSION => 'NONE', BLOCKCACHE => 'false', BLOCKSIZE => '65536'}
VERSIONS=>'1’说明最多可以显示一个版本 修改数据
put 'user','rowkey_10','base_info:username','Tom'
指定显示多个版本
get 'user','rowkey_10',{COLUMN=>'base_info:username',VERSIONS=>2}
修改可以显示的版本数量
alter 'user',NAME=>'base_info',VERSIONS=>10
通过时间戳查询
通过TIMERANGE 指定时间范围
scan 'user',{COLUMNS => 'base_info', TIMERANGE => [1558323139732, 1558323139866]}
get 'user','rowkey_10',{COLUMN=>'base_info:username',VERSIONS=>2,TIMERANGE => [1558323904130, 1558323918954]}
通过时间戳过滤器 指定具体时间戳的值
scan 'user',{FILTER => 'TimestampsFilter (1558323139732, 1558323139866)'}
get 'user','rowkey_10',{COLUMN=>'base_info:username',VERSIONS=>2,FILTER => 'TimestampsFilter (1558323904130, 1558323918954)'}
获取最近多个版本的数据
get 'user','rowkey_10',{COLUMN=>'base_info:username',VERSIONS=>10}
COLUMN CELL
base_info:username timestamp=1558323918953, value=Tom4
base_info:username timestamp=1558323904133, value=Tom3
base_info:username timestamp=1558323758696, value=Tom2
base_info:username timestamp=1558323139575, value=Tom
通过指定时间戳获取不同版本的数据
get 'user','rowkey_10',{COLUMN=>'base_info:username',TIMESTAMP=>1558323904133}
#返回结果如下
COLUMN CELL
base_info:username timestamp=1558323904133, value=Tom3
get 'user','rowkey_10',{COLUMN=>'base_info:username',TIMESTAMP=>1558323918953}
#返回结果如下
COLUMN CELL
base_info:username timestamp=1558323918953, value=Tom4
什么是HappyBase
HappyBase 是FaceBook员工开发的操作HBase的python库, 其基于Python Thrift, 但使用方式比Thrift简单, 已被广泛应用
启动hbase thrift server : hbase-daemon.sh start thrift
安装happy base
如何使用HappyBase
建立连接
import happybase
connection = happybase.Connection('somehost')
当连接建立时, 会自动创建一个与 HBase Thrift server的socket链接. 可以通过参数禁止自动链接, 然后再需要连接是调用 Connection.open()
:
connection = happybase.Connection('somehost', autoconnect=False)
# before first use:
connection.open()
Connection
这个类提供了一个与HBase交互的入口, 比如获取HBase中所有的表:Connection.tables()
:
print(connection.tables())
操作表
connection.create_table('users',{'cf1': dict()})
创建表之后可以传入表名获取到Table类的实例
table = connection.table('mytable')
查询操作
# api
table.scan() #全表查询
table.row('row_key') # 查询一行
table.rows([row_keys]) # 查询多行
#封装函数
def scanQuery():
# 创建和hbase的连接
connection = happybase.Connection('192.168.19.137')
#通过connection找到user表 获得table对象
table = connection.table('user')
filter = "ColumnPrefixFilter('username')"
#row_start 指定起始rowkey 缩小查询范围
#filter 添加过滤器
for key,value in table.scan(row_start='rowkey_10',filter=filter):
print(key,value)
# 关闭连接
connection.close()
def getQuery():
connection = happybase.Connection('192.168.19.137')
# 通过connection找到user表 获得table对象
table = connection.table('user')
result = table.row('rowkey_22',columns=['base_info:username'])
#result = table.row('rowkey_22',columns=['base_info:username'])
result = table.rows(['rowkey_22','rowkey_16'],columns=['base_info:username'])
print(result)
# 关闭连接
connection.close()
插入数据
#api
table.put(row_key, {'cf:cq':'value'})
def insertData():
connection = happybase.Connection('192.168.19.137')
# 通过connection找到user表 获得table对象
table = connection.table('users')
table.put('rk_01',{'cf1:address':'beijing'})
# 关闭连接
for key,value in table.scan():
print(key,value)
connection.close()
删除数据
#api
table.delete(row_key, cf_list)
def deleteData():
connection = happybase.Connection('192.168.19.137')
# 通过connection找到user表 获得table对象
table = connection.table('users')
table.delete('rk_01',['cf1:username'])
# 关闭连接
for key,value in table.scan():
print(key,value)
connection.close()
删除表
#api
conn.delete_table(table_name, True)
#函数封装
def delete_table(table_name):
pretty_print('delete table %s now.' % table_name)
conn.delete_table(table_name, True)
完整代码
import happybase
def connectHBase():
#创建和hbase的连接
connection = happybase.Connection('192.168.19.137')
#获取hbase中的所有表
print(connection.tables())
#关闭连接
connection.close()
def createTable():
connection = happybase.Connection('192.168.19.137')
connection.create_table('users',{'cf1': dict()})
print(connection.tables())
connection.close()
def scanQuery():
# 创建和hbase的连接
connection = happybase.Connection('192.168.19.137')
#通过connection找到user表 获得table对象
table = connection.table('user')
filter = "ColumnPrefixFilter('username')"
#row_start 指定起始rowkey 缩小查询范围
#filter 添加过滤器
for key,value in table.scan(row_start='rowkey_10',filter=filter):
print(key,value)
# 关闭连接
connection.close()
def getQuery():
connection = happybase.Connection('192.168.19.137')
# 通过connection找到user表 获得table对象
table = connection.table('user')
result = table.row('rowkey_22',columns=['base_info:username'])
#result = table.row('rowkey_22',columns=['base_info:username'])
result = table.rows(['rowkey_22','rowkey_16'],columns=['base_info:username'])
print(result)
# 关闭连接
connection.close()
def insertData():
connection = happybase.Connection('192.168.19.137')
# 通过connection找到user表 获得table对象
table = connection.table('users')
table.put('rk_01',{'cf1:address':'beijing'})
# 关闭连接
for key,value in table.scan():
print(key,value)
connection.close()
def deleteData():
connection = happybase.Connection('192.168.19.137')
# 通过connection找到user表 获得table对象
table = connection.table('users')
table.delete('rk_01',['cf1:username'])
# 关闭连接
for key,value in table.scan():
print(key,value)
connection.close()
def deletetable():
#创建和hbase的连接
connection = happybase.Connection('192.168.19.137')
#获取hbase中的所有表
connection.delete_table('users',disable=True)
print(connection.tables())
#关闭连接
connection.close()
def main():
#connectHBase()
#createTable()
scanQuery()
#getQuery()
#insertData()
#deleteData()
#deletetable()
if __name__ == "__main__":
main()
Client
Zookeeper
HMaster
可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master运行。
角色功能:
HRegionServer
HBase中最核心的模块,主要负责响应用户I/O请求,向HDFS文件系统中读写数据。
作用:
HStore
HBase存储的核心,由MemStore和StoreFile组成
用户写入数据的流程为:client访问ZK, ZK返回RegionServer地址-> client访问RegionServer写入数据 -> 数据存入MemStore,一直到MemStore满 -> Flush成StoreFile
HRegion
HLog