分布式HBase-1.2.1
HBase是一个分布式的列式数据库,适合键值对的数据存取或者有序的数据存取
hdfs适合批处理,不支持随机查找,不适合增量数据,不支持数据更新
hbase时hdfs的很好补充
行式存储和列式存储
如果我们大部分时间需要关注整张表的内容而不是单独几列,并且所关注的内容是不需要通过任何聚集运算的,推荐使用行式存储
如果比较关注的都是几列的内容,或者有频繁聚集需要的,通过聚集之后进行数据分析的,推荐使用列式存储
列式存储数据库以列为单位聚合数据,然后将列值顺序地存入磁盘
行式存储数据库连续地存储整行
运行模式:单机 + 分布式(伪分布式(所有守护进程都运行在单个节点上),完全分布式(进程运行在物理服务器集群中))
非关系型数据库系统Not-Only-SQL(NoSQL)
最基本的单位是列,一列或多列形成一行row,并由唯一的行键rowkey来确定存储
一个表中有若干行,所有的行按照行键字典顺序进行排序存储,其中每列可能有多个版本,在每一个单元格cell中存储了不同的值value
一个列族的所有列存储在同一个底层的存储文件里,这个存储文件叫做HFile
Region
- 本质上是一个数据表在行方向上以rowkey排序的连续存储的区间,实现分布式存储
- 每一个region都关联一个key值范围,即一个使用startkey和endkey描述的区间,事实上每一个region仅仅记录startkey就可以了,因为它的endkey就是下一个region的startkey
- 一张表初始时只有一个region,用户开始向表中插入数据时,系统会检查这个region的大小,确保其不超过配置的最大值。如果超过了限制,系统会在中间键处将这个region动态拆分成两个大致相等的子region,相反地就把多个region合并以减少存储文件数量
- 每一个region只能由一台region服务器regionserver加载,每一台regionserver可以同时加载多个region
- region等同于数据库分区中用的范围划分range partition,它们可以被分配到若干台物理服务器上与均摊负载,因此提供了较强的扩展性
- region分为meta region和user region两类
- 物理上所有数据存放在hdfs上,由Region服务器提供Region的管理
- 一台物理节点只能跑一个HRegionServer
- 一个HRegionServer可以管理多个Region实例和多个HLog
- 一个region由多个store组成,每一个store包含一个列族的所有数据
- HMaster作为总控节点
- ZooKeeper负责调度
RegionServer
- RegionServer是hbase的数据服务进程,负责处理用户数据的读写请求
- region被交由RegionServer管理,实际上所有用户数据的读写请求都是由regionserver上的region进行交互
- region可以在RegionServer之间发生转移
HLog
- 用于灾难恢复
- 预写式日志,记录所有更新操作,操作先记录进日志,数据才会写入
store
- store包括位于内存的memstore和位于硬盘的storefile
- 写操作先写入memstore,当memstore中的数据量达到某个阈值,HRegionServer会启动flashcache进程写入storefile,每次写入形成单独一个storefile
- 当storefile文件的数量增长到一定阈值后,系统会进行合并,在合并过程中会进行版本合并和删除工作,形成更大的storefile
- 当storefile大小超过一定阈值后会把当前的region分割为两个,并由HMaster分配到相应的region服务器实现负载均衡
- 客户端检索数据时先在memstore找,找不到再找storefile
HFile
数据鵆在存储文件storefile中,称为HFile,storefile通常保存在hdfs中
HFIle中存储的是经过排序的键值映射结构。文件内部由连续的块组成,块的索引信息存储在文件的尾部。当把HFIle打开并加载到内存中时,索引信息会优先加载到内存中,每个块的默认大小为64KB(可以配置)
每次更新数据时,都会优先将数据记录在预写日志(write-ahead log,WAL),然后才会将这些数据写入内存的memstore中。一旦memstore保存的写入数据的累计大小超过了一个给定的最大值,系统就会将这些数据移出内存作为HFile文件刷写到磁盘中,数据移除内存之后,系统会丢弃对应的WAL,只保留未持久化到磁盘中的WAL。在系统将数据移出memstore写入磁盘的过程中,可以不必阻塞系统的读写,通过滚动内存中的memstore就能达到这个目的,即用新的memstore获取更新数据,将满的旧memstore转换成一个文件,请注意,memstore中的数据已经按照行键排序,持久化到磁盘上的hfile也是按照这个顺序排列的,所以不必执行排序或者其它特殊处理。随着memstore中的数据不断刷写到磁盘中,会产生越来越多的hfile文件,hbase提供了一个管家机制,即用合并将多个文件合并成一个较大的文件。合并的类型:minor合并(minor compaction)和major合并(major compaction)。前者时将多个小文件重写为数量较少的大文件,减少存储文件的数量,这个过程实际上是多路归并的过程。因为hfile的每个文件都是经过归类的所以合并速度很快只受磁盘IO性能的影响。后者是将一个region中一个列族的若干个hfile重写为一个新的hfile,同时major合并能扫描所有的键值对,顺序重写全部的数据。重写数据的过程中会略过做了删除标记的数据,断言删除此时生效。
因为存储文件是不可被改变的,所以无法通过移除某个键/值对来简单地删除值,可行的解决办法是做个删除标记(delete marker,又称墓碑标记),表明给定行已被删除的事实
读回的数据是两部分数据合并的结果:memstore中还没有写入磁盘的数据 + 磁盘上的storefile。数据检索时用不着WAL,只有服务器内存中数据在服务器崩溃前没有写入到磁盘,而后进行恢复数据时才会用到WAL
有时候我们已经知道regionserver的数量startkey-endkey的范围时可以采用固定的region分区,不管数据怎么增加,region的数量都不会进行改变
每一个region会包含startkey和endkey
第一个region的startkey为空
最后一个region的engkey为空
每一个region的endkey是开区间的
当确定region的数量时可以采用以下建表的方式(创建3个region)
create ‘table01’,’cf01’,(NUMREGIONS=>3,SPLITALGO=>’HexStringSplit’)
当确定rowkey的范围时可以采用以下建表的方式(创建5个region)
create ’table02’,’cf01’,SPLITS=>[‘10’,‘20’,‘30’,‘40’]
客户端client
- 整个hbase集群的入口
- 使用hbase rpc机制和hmaster和hregionserver通信
- 与hmaster通信进行管理类的操作
- 与hregionserver通信进行读写类的操作
- 包含访问hbase的接口,并维护cache来加快对hbase的访问,与hregionserver交互
hmaster
- master进程负责管理所有regionserver(新regionserver的注册,regionserver failover处理)
- 负责跨region服务器的全局region的负载均衡,将繁忙的服务器中的region移到负载较轻的服务器中。master不是实际数据存储或检索路径的组成部分,它仅提供了负载均衡和集群管理,不为regionserver或者client提供任何的数据服务,因此是轻量级服务器。此外master还提供了元数据的管理操作,例如建表和建列族
- 负责建表,删表,修改表以及一些集群操作
- master进程负责所有region的转移操作:新表创建时的region分配,运行期间的负载均衡保障,regionserver failover后的region接管
- master进程有主备角色,集群可以配置多个
- master角色,集群启动时这些master角色通过竞争获得主master角色,主master只能有一个,所有的备master进程子集群运行期间处于休眠状态,不干涉任何集群事务
hbase容错
- master容错:zk重新选择一个新的master
无master过程中,数据读取仍然照常进行
无master过程中,region切分,负载均衡等无法进行
- regionserver容错:定时向zk汇报心跳,如果一定时间内没有出现心跳,master 将该regionserver上的region重新分配到其他regionserver上,失效服 务器上“预写”日志由主服务器进行分割并派送给新的regionserver
- zk容错:zk高可靠的服务,不存在单点故障
TABLE = RowKey + Family + Column + Timestamp + Value
配置环境变量
vi ~/.bash_profile
source ~/.bash_profile
export HBASE_HOME=/home/hadoop/hbase/hbase-1.2.1
${HBASE_HOME}/bin
修改配置文件
hbase-env.sh
export JAVA_HOME=/home/hadoop/work/jdk1.8.0_171
export HBASE_MANAGES_ZK=false
hbase-site.xml
<configuration>
<!--指定hbase在hdfs上存储的路径-->
<property>
<name>hbase.rootdir</name>
<value>hdfs://master:9000/hbasedata</value>
</property>
<!--指定hbase是分布式的-->
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<!--指定zk的地址,多个用逗号分隔-->
<property>
<name>hbase.zookeeper.quorum</name>
<value>master:2181,slave1:2181,slave2:2181</value>
</property>
</configuration>
regionservers
slave1
slave2
发送hbase到集群上其他机器
cd ~
scp -r hbase hadoop@slave1:$PWD
scp -r hbase hadoop@slave2:$PWD
设置集群上所有机器的时间,使之保持一致,hbase对实时性要求较高
sudo date -s '2018-08-24 18:20:00'
启动hdfs
启动zk
启动hbase
./start-hbase.sh
本机为master节点,regionservers文件中配置的hostname为region节点
验证hbase集群是否启动成功
netstat -nltp
http://192.168.218.133:16010/master-status
启动hbase的命令行客户端
./hbase shell
帮助
help
建表(表名为t_user_info,列族为base_info何extra_info)
create 't_user_info','base_info','extra_info'
显示表
list
插入记录
put 't_user_info','rk001','base_info:uid','1'
put 't_user_info','rk001','base_info:uname','mwt'
put 't_user_info','rk001','base_info:age','23'
查询记录
get 't_user_info','rk001'
scan 't_user_info'
创建命名空间
create_namespace 'db1'
显示命名空间
list_namespace
在namespace下建表
create 'db1:t_2','f1'
清空表
truncate 't_user_info'
hbase之java API操作