HBase简介
HBase定义
- 一种分布式、可扩展、支持海量数据存储的NoSQL数据库
HBase逻辑结构
HBase物理存储结构
数据模型
- Name Space
- 类似于database,每个命名空间下有多个表
- HBase有两个自带的命名空间,分别是hbase和default
- hbase存放的是HBase内置的表
- default表是用户默认使用的命名空间
- Table
- HBase定义表时只需要声明列族即可,不需要声明具体的列
- Row
- 表中的每行数据都有一个RowKey和多个Column组成
- 数据按照RowKey的字典序存储
- 查询数据时只能根据RowKey进行检索
- Column
- 每个列都由Column Family()列族和Column Qualifier(列限定符)进行限定
- Time Stamp
- 用于标识数据的不同版本(version),其值为写入HBase的时间
- Cell
- 由{rowkey, column Family:column Qualifier, time Stamp} 唯一确定的单元
- cell中的数据全部是字节码形式存储
HBase基本架构
- Region Server
- Region的管理者,其实现类为HRegionServer
- 对于数据的操作:get、put、delete
- 对于Region的操作:splitRegion、compactRegion
- Master
- 所有Region Server的管理者,其实现类为HMaster
- 对表的操作:create、delete、alter
- 对Region Server的操作
- 分配regions到每个RegionServer
- 监控每个RegionServer的状态,负载均衡和故障转移
HBase安装部署
# Zookeeper正常部署
bin/zkServer.sh start
# Hadoop正常部署
sbin/start-dfs.sh
sbin/start-yarn.sh
# HBase解压
tar -zxvf hbase-2.0.5-bin.tar.gz -C /opt/module
mv /opt/module/hbase-2.0.5 /opt/module/hbase
# 配置环境变量
sudo vim /etc/profile.d/my_env.sh
#HBASE_HOME
export HBASE_HOME=/opt/module/hbase
export PATH=$PATH:$HBASE_HOME/bin
# 修改hbase-env.sh
export HBASE_MANAGES_ZK=false
# 修改hbase-site.xml
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://node01:8020/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>node01,node02,node03</value>
</property>
</configuration>
# regionservers
node01
node02
node03
# 分发到其他集群
xsync.sh hbase
HBase服务的启动
# 单点启动
bin/hbase-daemon.sh start master
bin/hbase-daemon.sh start regionserver
# 群启
bin/start-hbase.sh
# 查看HBase页面
http://node01:16010
高可用
# 在conf目录下创建backup-masters文件
touch conf/backup-masters
# 在backup-masters文件中配置高可用HMaster节点
node01
node02
node03
# 将整个conf目录scp到其他节点
HBase Shell操作
基本操作
# 进入客户端
bin/hbase shell
# 查看帮助命令
help
namespace的操作
# 查看namespace
list_namespace
# 创建namespace
create_namespace "test"
create_namespace "test01" {"author"=>"liuxan", "create_time"=>"2022-2-7"}
# 查看namespace
describe_namespace "test01"
# 修改namespace的信息(添加或者修改属性)
alter_namespace "test01",{METHOD => 'set', 'author'=>'lx'}
# 删除属性
alter_namespace "test01",{METHOD => 'unset', 'author'=>'lx'}
# 删除namespace
# 要删除的namespace必须是空的,其下没有表
drop_namespace "test01"
表的操作
# 查看当前数据库有哪些表
list
# 创建表
create 'stident','info'
# 插入数据到表
put 'student','1001','info:sex','male'
put 'student','1001','info:age','18'
put 'student','1002','info:name','Janna'
put 'student','1002','info:sex','female'
put 'student','1002','info:age','20'
# 扫描查看表数据
scan 'student'
scan 'student', {STARTROW =>'1001', STOPROW =>'1001'}
scan 'student', {STARTROW =>'1001'}
# 查看表结构
describe 'student'
# 更新指定字段的数据
put 'student','1001','info:name','Nick'
put 'student','1001','info:age','100'
# 查看指定行或指定列的数据
get 'student','1001'
get 'student','1001','info:name'
# 统计表数据行数
count 'student'
# 删除数据
# 删除某rowkey的全部数据
deleteall 'student','1001'
# 删除某rowkey的某一列数据
delete 'student','1002','info:sex'
# 清空表数据
# 先disable,再truncate
disable 'student'
truncate 'student'
# 删除表数据
disable 'student'
drop 'student'
# 变更表信息
# 将info列族中的数据存放3个版本
alter 'student', {NAME=>'info',VERSIONS =>3}
get 'student','1001',{COLUMN=>'info:name',VERSIONS=>3}
HBase进阶
RegionServer架构
写流程
- Clinet先访问Zookeeper,获取hbase:meta表位于哪个Region Server
- 访问对应的RegionServer,获取hbaset:meta表
- 根据请求的namespace:table/rowkey,查询出目标数据位于哪个RegionServer的哪个Region中
- 并将该table的region信息以及meta表的位置信息缓存再客户端的meta cache,方便下次访问
- 与目标RegionServer进行通讯
- 将数据顺序写入(追加)到WAL
- 将数据写入对应的MemStore,数据会在MemStore进行排序
- 向客户端发送ack
- 等达到MemStore的刷写时机后,将数据刷写到HFile
MemStore Flush
-
当某个memstore的大小达到了
hbase.hregion.memstore.flush.size(默认值128M)
,其所在region的所有memstore都会刷写 -
当memstore的大小达到了
hbase.hregion.memstore.flush.size(默认值128M)*hbase.hregion.memstore.block.multiplier(默认值4)
,会阻止继续往该memstore写数据 -
当region server中memstore的总大小达到
java_heapsize*hbase.regionserver.global.memstore.size(默认值0.4)*hbase.regionserver.global.memstore.size.lower.limit(默认值0.95)
,region会按照其所有memstore的大小顺序(由大到小)依次进行刷写,直到region server中所有memstore的总大小减小到上述值以下 -
当region server中memstore的总大小达到
java_heapsize*hbase.regionserver.global.memstore.size(默认值0.4)
,会阻止继续往所有的memstore写数据 -
到达自动刷写的时间,也会触发memstore flush,
hbase.regionserver.optionalcacheflushinterval(默认1小时)
-
当WAL文件的数量超过32时,region会按照时间顺序依次进行刷写
读流程
- 分别在MemStore和StoreFile(HFile)中查询目标数据,并将查到 的所有数据进行合并
- 所有数据是指不同版本(time stamp),或者不同类型(put/delete)
- 将查询到的新的数据块(block,HFile数据存储的单元,默认大小为64KB)缓存到Block Cache
- 将合并后的最后结果返回给客户端
StoreFile Compaction
- Memstore每次刷写都会生成一个新的HFile
- 且同一字段不同版本和不同类型有可能会分布在不同的HFile中
- 因此查询时需要遍历所有的HFile
- 为了减少HFile的个数,以及清理掉过期和删除的数据,会进行StoreFile Compaction
- Compaction分为Minor Compaction和Major Compaction
- Minor Compaction会将临近的若干个较小的HFile合并成一个较大的HFile,并清理掉部分过期和删除的数据
- Major Compaction会将一个Store下所有的HFile合并成一个大HFile,并且会清理掉所有过期和删除的数据
Region Split
- 默认情况下,起初每个Table只有一个Region
- 随着数据的不断写入,Region会自动进行拆分
- 刚拆分时,两个子Region都位于当前的Region Server
- 但出于负载均衡的考虑,HMaster有可能会将某个Region转移给其它的Region Server
- 如果当前Region Server上该表只有一个Region,按
2 * hbase.hregion.memstore.flush.size
,否则按hbase.hregion.max.filesize
分裂