八、HBase
🔖Day14-Hbase的入门及系统框架
重点掌握
1、掌握Hbase的数据存储结构 2、掌握Hbase的访问方式 3、掌握Hbase的系统架构
理解内容
1、Hbase的四维数据存储模型 -03 2、Hbase0.96前后数据定位方式 -24~25
8.1HBase的介绍
8.1.1HBase简介
定义理解:
HBase与其他组件的结合使用
利用HDFS作为其文件存储系统 利用Zookeeper作为其分布式系统服务 利用MapReduce来处理HBase中的海量数据 参考资料: Hbase简介与基本原理_奋斗吧,青年!的博客-CSDN博客_hbase原理
8.1.2HBase优点
容量大
HBase单表可以有百亿行、百万列,数据矩阵横向和纵向两个维度所支持的数据量级都非常具有弹性 面向列
面向列的存储和权限控制,并支持独立检索,可以动态增加列。即,可以单独对列进行各方面的操作列式存储,其数据在表中时按照某列存储的,这样在查询只需要少数的几个字段的时候,能大大减少读取的数量 下图显示了列族在面向列的数据库:
多版本
HBase的每一个列的数据存储有多个version,比如住址列,可能有多个变更,所有该列可以有多个version 稀疏性
为空的列并不占用存储空间,表可以设计的非常稀疏 不必向关系型数据库那样需要预先知道所有的列然后进行null填充 拓展性:
底层依赖HDFS,当磁盘空间不足的时候,只需要动态增加datanode节点服务(机器)就可以了 高可靠性:
WAL机制,保证数据写入的时候不会因为集群异常而导致写入数据丢失Replication机制,保证了在集群出现严重的问题时候,数据不会发生丢失或者损坏Hbase底层使用HDFS,本身也有备份。 高性能:
底层的LSM数据结构和RowKey有序排列等架构上的独特设计,使得Hbase写入性能非常高。Region切分、主键索引、缓存机制使得Hbase在海量数据下具备一定的随机读取性能,该性能针对Rowkey的查询能够到达毫秒级别,LSM树,树形结构,最末端的子节点是以内存的方式进行存储的,内存中的小树会flush到磁盘中(当子节点达到一定阈值以后,会放到磁盘中,且存入的过程会进行实时merge成一个主节点,然后磁盘中的树定期会做merge操作,合并成一棵大树,以优化读性能。) LSM树的介绍:https://www.cnblogs.com/yanghuahui/p/3483754.html
8.1.3 HBase应用
Hbase是一种NoSQL数据库,这意味着它不像传统的RDBMS数据库那样支持SQL作为查询语言。Hbase是一种分布式存储的数据库,技术上来讲,它更像是分布式存储而不是分布式数据库,它缺少很多RDBMS系统的特性,比如列类型,辅助索引,触发器,和高级查询语言等待。那Hbase有什么特性呢?如下
适合用HBase的场景
首先数据库量要足够多,如果有十亿及百亿行数据,那么Hbase是一个很好的选项,如果只有几百万行甚至不到的数据量,RDBMS是一个很好的选择。因为数据量小的话,真正能工作的机器量少,剩余的机器都处于空闲的状态 其次,如果你不需要辅助索引,静态类型的列,事务等特性,一个已经用RDBMS的系统想要切换到Hbase,则需要重新设计系统。 最后,保证硬件资源足够,每个HDFS集群在少于5个节点的时候,都不能表现的很好。因为HDFS默认的复制数量是3,再加上一个NameNode。 Hbase在单机环境也能运行,但是请在开发环境的时候使用。 实际应用场景
存储业务数据:车辆GPS信息,司机点位信息,用户操作信息,设备访问信息。。。 存储日志数据:架构监控数据(登录日志,中间件访问日志,推送日志,短信邮件发送记录。。。),业务操作日志信息 存储业务附件:UDFS系统存储图像,视频,文档等附件信息 不过在公司使用的时候,一般不使用原生的Hbase API,使用原生的API会导致访问不可监控,影响系统稳定性,以致于版本升级的不可控。
Hbase和RDBMS的比较
属性 Hbase RDBMS 数据类型 只有字符串 丰富的数据类型 数据操作 增删改查,不支持join 各种各样的函数与表连接 存储模式 基于列式存储 基于表结构和行式存储 数据保护 更新后仍然保留旧版本 替换 可伸缩性 轻易增加节点 需要中间层,牺牲性能
数据管控层(助于理解)
8.2 HBase数据模型
HBase 是一个稀疏的、分布式、持久、多维、排序的映射,它以行键(row key),列族(columnFamily),列名(Column Qualifier)和时间戳(timestamp)为索引。
8.2.1 NameSpace 命名空间
定义理解
命名空间是类十余关系数据库系统中的数据库的概念,他其实是表的逻辑分组,这种抽象为多租户相关功能奠定了基础 为了保护我们的表,创建的一个更高层级的单位 命名空间是可以管理维护的,可以创建、删除或者更改 两个特殊预定义的命名空间:
default :没有明确指定名称空间的表将会自动落入此名称空间 hbase :系统命名空间,用户包含HBase内部表
8.2.2 Table 表
定义理解
存储相同数据的一个逻辑单元 表有多个行数据组成,行有很多列组成 HBase是一个半结构化的数据库,所以每一行的列都有可能是不同的
8.2.3 RowKey 行键
定义理解
RowKey是用来检索记录的主键,是一行数据的唯一标识 RowKey(行键)可以是任意字符串(最大长度是64KB,实际应用中长度一般为 10-100bytes),RowKey以字节数组保存。 HBase按照列进行存储,所以我们查询数据的时候会看到很多RowKey相同的列 RowKey排序规则
8.2.4 Column Family 列族
定义理解
列族在物理上包含了许多的列与列的值,每个列族都有一些存储的属性可配置
例如是否使用缓存、压缩类型、存储版本等。在表中,每一行都有相同的列族,尽管有些列族什么东西也没存。 可以理解为多个列的集合,方便队列进行查找和管理 一个表的列族需要在创建之前就要声明(先创建表,后期再维护表),而且一般一个表中的列族数不要超过3个 列的存放原则
将功能属性相近的列存放在同一个列族,而且同一个列族中的列存放在同一个Store中 列、列族和表之间的关系
列属于列族,列族属于表,即 列-->列族-->表 一个表中的列族是固定的,但是列族中的列是不固定的
8.2.5 Column Qualifier
定义理解
列族额限定词,理解为列的唯一标识。但是列标识是可以改变的,因此每一行可能有不同的列标识 使用的时候必须 列族:列 列可以根据需求动态添加或者删除,同一个表中不同行的数据列都可以不同
8.2.6 TimeStamp
定义理解:
默认数据版本就是时间戳,解决HDFS不能随时修改数据的弊端 查询数据的时候默认显示最新的数据 版本回收方式
为了避免数据存在过多版本中造成管理 (包括存贮和索引)负担,HBASE 提供了两种数据版本回收方式
一是保存数据的最后n个版本 二是保存最近一段时间内的版本(比如最近七天)
8.2.7 Cell
定义理解:
Cell是由row,column family,column qualifier,version 组成的,所有的数据都是字符串 Cell中的数据是没有类型的,全部是字节码形式存贮。
8.3 HBase高可用集群搭建
8.3.1准备安装环境
[root@node01 ~]# tar -zxvf hbase-2.2.5-bin.tar.gz [root@node01 ~]# mv hbase-2.2.5 /opt/yjx/ [root@node01 ~]# cd /opt/yjx/hbase-2.2.5/conf/
8.3.2 修改集群环境
8.3.3修改配置文件
[root@node01 conf]# vim hbase-site.xml
< property>
< name> hbase.rootdir</ name>
< value> hdfs://hdfs-yjx/hbase</ value>
</ property>
< property>
< name> hbase.cluster.distributed</ name>
< value> true</ value>
</ property>
< property>
< name> hbase.zookeeper.quorum</ name>
< value> node01:2181,node02:2181,node03:2181</ value>
</ property>
< property>
< name> zookeeper.znode.parent</ name>
< value> /hbase</ value>
</ property>
< property>
< name> hbase.tmp.dir</ name>
< value> /var/yjx/hbase</ value>
</ property>
< property>
< name> hbase.unsafe.stream.capability.enforce</ name>
< value> false</ value>
</ property>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 vim regionservers
node01
node02
node03
8.3.4 备用Master节点
8.3.5 拷贝Hadoop配置文件
[root@node01 conf]# cp /opt/yjx/hadoop-3.1.2/etc/hadoop/core-site.xml /opt/yjx/hbase-2.2.5/conf/ [root@node01 conf]# cp /opt/yjx/hadoop-3.1.2/etc/hadoop/hdfs-site.xml /opt/yjx/hbase-2.2.5/conf/
8.3.6 拷贝分发软件
[root@node02 ~]# scp -r root@node01:/opt/yjx/hbase-2.2.5 /opt/yjx/ [root@node03 ~]# scp -r root@node01:/opt/yjx/hbase-2.2.5 /opt/yjx/
8.3.7 修改环境变量
8.4.8 启动集群
【123】 zkServer.sh start [root@node01 conf]# start-all.sh [root@node01 conf]# start-hbase.sh
8.4.9 web页面验证
可以看到服务器1启动和HMaster 和 HRegionServer进程,服务器2和服务器3启动和HRegionServer进程。
查看HBase的集群情况:http://192.168.88.101:16010
8.4 HBase访问方式
8.4.1 HBase shell
我们可以先用HBase提供的命令行工具,位于HBase的/bin/目录下
开启环境命令
【123】zkServer.sh start 【1】start-all.sh 【1】start-hbase.sh 进入退出HBase
关闭环境并关机命令
【1】stop-hbase.sh 【1】stop-all.sh 【123】zkServer.sh stop 【123】shutdown -h now 查看帮助信息
查询服务器状态
查询hbase版本
1. Shell实现DDL操作
创建表
语法:create ‘表名’ , {NAME => , VERSIONS => } 例如:创建表t1,有两个family name:f1,f2,且版本数均为2
create ‘t1’,{NAME => ‘f1’, VERSIONS => 2},{NAME => ‘f2’, VERSIONS=> 2} 非标准创建表的语法:创建表member,列族是member_id,address,info,版本为1
create ‘member’,‘member_id’,‘address’,‘info’ 获得表的描述信息
语法:
例如
list :查看所有的表名称(列出所有的表) describe ‘member’ :查看表的描述信息 删除一个列族
语法 alter,disable,enable
alter
我们之前建了3个列族,但是发现member_id这个列族是多余的,因为他就是主键,所以我们要将其删除 alter ‘member’,{NAME=>‘member_id’,METHOD=>‘delete’} enable
disable
drop一个表
create 'temp_table','member_id','address','info'
hbase(main):029:0>disable 'temp_table'
hbase(main):030:0>drop 'temp_table'
查询表是否存在
exists 'member'
判断表是否enable(启用)
is_enabled 'member'
判断表是否disable
is_disabled 'member'
查看文件存储路径
hdfs dfs -ls /yjx/hbase/data/default/member
truncate此命令将删除并重新创建一个表
truncate ‘t1’
表的预分区
# create table with specific split points
hbase>create 'table1','f1',SPLITS => ['\x10\x00', '\x20\x00', '\x30\x00','\x40\x00']
# create table with four regions based on random bytes keys
hbase>create 'table2','f1', { NUMREGIONS => 8 , SPLITALGO => 'UniformSplit' }
# create table with five regions based on hex keys
hbase>create 'table3','f1', { NUMREGIONS => 10, SPLITALGO => 'HexStringSplit' }
2.Shell实现DML操作
3.Shell实现DQL操作
4. Shell实现Region管理
8.4.2 Java访问HBaseAPI
8.5 HBase架构模型
HBase有三个主要组成部分:客户端库,主服务器和区域服务器。
8.5.1Client
主要功能
客户端负责发送请求到数据库,客户端连接的方式有很多种
client维护着一些cache来加快对hbase的访问,比如regione的位置信息。 发送请求的类型
DDL:数据库定义语言(表的建立,删除,添加删除列族,控制版本) DML:数据库操作语言(增删改) DQL:数据库查询语言(查询–全表扫描–基于主键–基于过滤器)
8.5.2 HMaster
定义
HBase集群的主节点,HMaster也可以实现高可用(active–standby)
作用
上下线的监督,创建表的时候为Region server分配region并负责Region server的负载均衡 负责接受客户端对table的结构DDL(创建,删除,修改)操作,DML和DQL由其他节点承担
因为HMaster没有联邦机制,业务承载能力有限,而且数据库的表结构很少会变化,大部分都是CRUD操作 表的元数据信息–>Zookeeper上面 表的数据–>HRegionServer上 负责监督HRegionServer的健康状况
当HRegionServer下线的时候,HMaster会将当前HRegionServer上的Region转移到其他的HRegionServer
8.5.3 HRegionServer
定义
HBase的具体工作节点(RegionServer属于HBase具体数据的管理者),一般一台主机就是一个RegionServer 作用
一个RegionServer中包含很多HMaster分配给RegionServer的Region,同时RegionServer处理这些Region的IO请求(DML和DQL请求) 当客户端发送DML和DQL操作的时候,HRegionServer负责和客户端建立连接 HRegionServer会实时和HMaster保持心跳,汇报当前节点的信息 当接收到Hmaster命令创建表的时候,分配一个Region对应一张表 Region server负责切分在运行过程中变得过大的region 其他:
当意外关闭的时候,当前节点的Region会被其他HRegionServer管理 图解 RegionServer、Region、store和storefile之间的关系
8.5.4 HRegion
定义理解
HRegion是HBase中分布式存储和负载均衡最小单元(HBase的表数据具体存放的位置)
最小单元就表示不同的HRegion可以分布在不同的 HRegion server上。 一个Region只属于一张表,但是一张表可以有多个Region HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据 Region的平分
最开始声明表的时候就会为这个表默认创建一个Region,一个Region只属于一张表,随着时间的推移Region会越来越大 ,当达到阈值10G时,然后Region会1分为2(逻辑上平分,尽量保证数据的完整性)
切分后的其中一个Region转移到其他的HRegionServer上管理 预分区
当table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个Regionserver 上。 为了防止前期数据的处理都集中在一个HRegionServer,我们可以根据自己的业务进行预分区
8.5.5 Store
定义理解
一个表中的一个列族对应一个Store 一个Store里面分为1个MenStore和0或多个StoreFile HRegion、Store和columns family之间的关系
HRegion是表获取和分布的基本元素,由一个或者多个Store组成,每个store保存一个columns family。 HFile
HFile是Hbase在HDFS中存储数据的格式,它包含多层的索引,这样在Hbase检索数据的时候就不用完全的加载整个文件。 StoreFile存储在HDFS上之后就称为HFile
8.5.6 StoreFile
定义理解
StoreFile是文件的硬盘存储,直接存到HDFS上,存到HDFS之后被称为HFile StoreFile是数据存储文件的映射,对应HDFS上的HFile 表、Region、Store、StoreFile之间的关系
一个table对应多个Region,一个Region对应多个Store,一个Store对应一个MEMStore和多个StoreFile,多个StoreFile内部有序,但是外部无序 集群会设置一些阈值,当达到阈值的时候开始将小文件合并成大文件
8.5.7 MenStore
定义理解
MenStore是基于内存存放数据,每个Store大概分配128M的空间 HFile中并没有任何Block,数据首先存在于MemStore中。Flush发生时,创建HFile Writer 数据最开始优先写入到MEMStore,当flush的时候才会被写入到磁盘中(之前在内存中) 默认情况下,一个MemStore的大小为128M,当客户端向数据库插入数据的时候,当内存使用到128M的时候,直接申请128M的内存空间,数据直接写到新内存中,原来已经满的数据写出到HDFS上,称为HFile MenStore与 Data Block之间的关系
当操作数据的时候,第一个空的Data Block初始化,初始化后的Data Block中为Header部分预留了空间,Header部分用来存放一个Data Block的元数据信息。 位于MemStore中的KeyValues被一个个append到位于内存中的第一个Data Block中
如果配置了Data Block Encoding,则会在Append KeyValue的时候进行同步编码,编码后的数据不再是单纯的KeyValue模式。 Data Block Encoding是HBase为了降低KeyValue结构性膨胀而提供的内部编码机制
8.5.8 Hlog
定义理解
HBase的日志机制,WAL(Write After Log)做任何操作之前先写日志,一个HRegionServer只有一个Log文档 日志也会存储到HDFS上,在任何操作之前先记录日志到HDFS,以后MenStore丢失数据或者RegionServer异常都能够通过日志进行恢复一个RegionServer对应的一个Hlog HLog文件就是一个普通的Hadoop Sequence File,SequeceFile的Key是HLogKey对象 作用
当memStore达到阈值的时候开始写出到文件之后,会在日志中对应的位置标识一个检查点 WAL记录所有的Hbase数据改变,如果一个RegionServer在MemStore进行FLush的时候挂掉了,WAL可以保证数据的改变被应用到。如果写WAL失败了,那么修改数据的完整操作就是失败的。 图解Hlog在整个HBase中的结构
8.5.9 Zookeeper
定义理解
作用
主备选举与切换 记录当前集群的状态信息,当主备切换的时候,集群的状态可以被新主节点直接读取到 记录当前集群的数据存放信息 存储HBase的元数据信息
8.6 HBase读写流程
8.6.1 公共流程(三层索引)
对于数据对应的Region位置在哪里的问题的提出
HBase中单表的数据量通常可以达到TB级或PB级,但大多数情况下数据读取可以做到毫秒级。HBase是如何做到的呢?要想实现表中数据的快速访问,通用的做法是数据保持有序并尽可能的将数据保存在内存里。HBase也是这样实现的 对于海量级的数据,首先要解决存储的问题。数据存储上,HBase将表切分成小一点的数据单位region,托管到RegionServer上,和以前关系数据库分区表类似。但比关系数据库分区、分库易用。这一点在数据访问上,HBase对用户是透明的。数据表切分成多个Region,用户在访问数据时,如何找到该条数据对应的region呢?
1. HBase 0.96以前
两个表-Root- 和 .Meta.
用户访问表的流程
client–>Zookeeper --> .root. 表–>-meta-表–>RegionServer–>Region
2.HBase 0.96以后
-ROOT-表被移除,直接将.Meta表region位置信息存放在Zookeeper中。Meta表更名为hbase:meta,
查询流程
Client—>Zookeeper—>HBase:meta—>用户表Region