第一章 HBase 简介
1.1 HBase 定义
HBase 是一种分布式、可扩展、支持海量数据存储的 NoSQL 数据库。
1.2 HBase 数据模型
逻辑上,HBase 的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列。但从 HBase 的底层物理存储结构(K-V)来看,HBase 更像是一个 multi-dimensional map。
1.2.1 HBase 逻辑结构
HBase表由行和列组成,每个行由行键(row key)来标识,列划分为若干列族,一个列族中可以包含任意多个列,同一个列族里面的数据存储在一个文件中。
当这个文件达到一定大小后,会进行分裂形成多个region。当一个行键在不同的列族中都有相应的列值的话,不同列族中的文件都会存储这个行键的值。
也就是说,一行可能包含多个列族,一个列族有多个列,对某一行而言,某列族文件中只存储了这一行键在列族中有值的那些列(列族可能有上百个列),没有不会存储(不存null)。
1.2.2 HBase 物理存储结构
逻辑结构转成物理结构
当在t4时间put(插入)row_key1的phone数据时,原来t3的并不会马上被覆盖。当查询row_key1的phone时会返回时间戳最大的t4那一个数据(最新的)。
1.2.3 数据模型
1)Name Space
命名空间,类似于关系型数据库的 DatabBase 概念,每个命名空间下有多个表。HBase有两个自带的命名空间,分别是 hbase 和 default,hbase 中存放的是 HBase 内置的表,default 表是用户默认使用的命名空间。
命名空间的结构:
- Table:表,所有的表都是命名空间的成员,即表必属于某个命名空间,如果没有指定,则在 default 默认的命名空间中。
- RegionServer group:一个命名空间包含了默认的 RegionServer Group。
- Permission:权限,命名空间能够让我们来定义访问控制列表 ACL(Access Control List)。例如,创建表,读取表,删除,更新等等操作。
- Quota:限额,可以强制一个命名空间可包含的 region 的数量。
2)Region
类似于关系型数据库的表概念。不同的是,HBase 定义表时只需要声明列族即可,不需要声明具体的列。这意味着,往 HBase 写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase 能够轻松应对字段变更的场景。
3)Row
HBase 表中的每行数据都由一个 RowKey 和多个 Column(列)组成,数据是按照 RowKey的字典顺序存储的,并且查询数据时只能根据 RowKey 进行检索,所以 RowKey 的设计十分重要。
与 nosql 数据库们一样,RowKey 是用来检索记录的主键。访问 HBASE table 中的行,只有三种方式:
- 通过单个 RowKey 访问
- 通过 RowKey 的 range(正则)
- 全表扫描
RowKey 可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),在 HBASE 内部,RowKey 保存为字节数组。存储时,数据按照 RowKey 的字典序(byte order)排序存储。设计 RowKey 时,要充分排序存储这个特性,将经常一起读取的行存储放到一起。(位置相关性)
4)ColumnFamily
列族:HBASE 表中的每个列,都归属于某个列族。列族是表的 schema 的一部分(而列不是),必须在使用表之前定义。列名都以列族作为前缀。例如 courses:history,courses:math都属于 courses 这个列族。
HBase 中的每个列都由 Column Family(列族)和 Column Qualifier(列限定符)进行限定,例如 info:name,info:age。
建表时,只需指明列族,而列限定符无需预先定义。
5)Cell
由{rowkey, column Family:column Qualifier, time Stamp} 唯一确定的单元。cell 中的数据是没有类型的,全部是字节码形式存贮。
cell 中的数据是没有类型的,全部是字节码形式存贮。 关键字:无类型、字节码
6)Time Stamp (时间戳)
用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入 HBase 的时间。
每个 cell 都保存着同一份数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64 位整型。
时间戳可以由 HBASE(在数据写入时自动 )赋值,此时时间戳是精确到毫秒 的当前系统时间。
时间戳也可以由客户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。
每个 cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。 为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,HBASE 提供 了两种数据版本回收方式。一是保存数据的最后 n 个版本,二是保存最近一段 时间内的版本(比如最近七天)。用户可以针对每个列族进行设置。
在HBase中,timestamp是一个很重要的概念。它记录着往HBase进行增删改操作的时间(系统自动赋值),它的值越大,说明是这个操作就越新,通常我们从HBase得到的只是那个最新操作的结果,但是之前的操作(时间戳小的)会保留直到达到一定的版本数或者设定时间。
1.3 HBase 系统架构
Hbase 是由 Client、Zookeeper、Master、HRegionServer、HDFS 等几个组件组成,HBase依赖于ZooKeeper和HDFS。
Zookeeper
HBase 通过 Zookeeper 来
- 做 master 的高可用(通过 Zoopkeeper 来保证集群中只有 1 个 master 在运行,如果 master 异常,会通过竞争机制产生新的 master 提供服务。)
- RegionServer 的监控(通过 Zoopkeeper 来监控 RegionServer 的状态,当 RegionSevrer 有异常的时候,通过回调的形式通知 Master RegionServer 上下线的信息)
- 元数据的入口以及集群配置的维护等工作。(DML的请求通过ZK分发到HRegionServer不通过HMaster,HMaster是处理DDL的请求。HMaster宕机不会影响客户端的读写请求;但是取法进行create \'stu4\',\'info\'的DDL操作。当原有的Meta元数据信息改变时也无法维护。)
Hmaster
Hmaster 是所有 Region Server 的管理者,其实现类为 HMaster,主要作用如下:
- 对于表的操作:create, delete, alter
- 监控 RegionServer,为 RegionServer 分配 Region(维护整个集群的负载均衡,在空闲时间进行数据的负载均衡 )
- 维护集群的元数据信息,处理 region 的分配或转移(发现失效的 Region,并将失效的 Region 分配到正常的 RegionServer 上
- 当 RegionSever 失效的时候,协调对应 Hlog 的拆分)
HregionServer
Region Server 为 Region 的管理者,直接对接用户的读写请求,是真正的“干活”的节点。其实现类为 HRegionServer,主要作用如下:
- 管理 master 为其分配的 Region,处理来自客户端的读写请求(get, put, delete)
- 负责和底层 HDFS 的交互(存储数据到 HDFS)
- 负责 Region 变大以后的拆分
- 负责 Storefile 的合并工作 ,刷新缓存到HDFS,维护Hlog
HDFS
为 Hbase 提供最终的底层数据存储服务,同时为HBase 提供高可用(Hlog 存储在HDFS)的支持,具体功能概括如下:
- 提供元数据和表数据的底层分布式存储服务
- 保证的高可靠和高可用性 (数据多副本)
StoreFile
保存实际数据的物理文件,StoreFile 以 HFile 的形式存储在 HDFS 上。每个 Store 会有一个或多个 StoreFile(HFile),数据在每个 StoreFile 中都是有序的。
MemStore
写缓存,由于 HFile 中的数据要求是有序的,所以数据是先存储在 MemStore 中,排好序后,等到达刷写时机才会flush刷写到 HFile,每次刷写都会形成一个新的 HFile。
每次 Flush 的最小单位是 Region。每个 Column family 维护一个 MemStore。
Write-Ahead logs(WAL)
用来容灾。由于数据要经 MemStore 排序后才能刷写到 HFile,写进磁盘。但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做 Write-Ahead logfile 的文件中,然后再写入 MemStore 中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。https://www.jianshu.com/p/65cb8cd81f40
Region
Hbase表的分片,HBase 表会根据 RowKey 值被切分成不同的 region 存储在 RegionServer中,在一个 RegionServer 中可以有多个不同的 region。同一个行键的 Region 不会被拆分到多个 Region 服务器上。 一个HBase表被划分成多个Region,开始只有一个Region,后台不断分裂。
一个表中包含多个列族,一个列族一个文件存储,region的切分是横向切分的,那么包含了多个列族。
Meta表
描述HBase表的表,元数据表。有了 Region 标识符,就可以唯一标识每个 Region。为了定位每个 Region 所在的位置,可以构建一张映射表。
映射表的每个条目包含两项内容,一项是 Region 标识符,另一项是 服务器标识。
这个条目就表示 Region 和 Region 服务器之间的对应关系,从而就可以使用户知道某个 Region 存储在哪个 Region 服务器中。
这个映射表包含了关于 Region 的元数据,因此也被称为“元数据表”,又名“Meta表”。使用 scan 命令可查看 Meta 表的结构,如图所示
Meta 表中的每一行记录了一个 Region 的信息。RowKey 包含表名、起始行键和时间戳信息,中间用逗号隔开,第一个 Region 的起始行键为空。时间戳之后用.隔开的为分区名称的编码字符串,该信息是由前面的表名、起始行键和时间戳进行字符串编码后形成的。
Meta 表里有一个列族 info。info 包含了三个列,分别为 Regioninfo、Server 和 Serverstartcode。
Regionlnfo中记录了 Region 的详细信息,包括行键范围 StartKey 和 EndKey、列族列表和属性。
Server 记录了管理该 Region 的 Region 服务器的地址,如 localhost:16201。Serverstartcode 记录了 Region 服务器开始托管该 Region 的时间。
当用户表特别大时,用户表的 Region 也会非常多。Meta 表存储了这些 Region 信息,也变得非常大。Meta 表也需要划分成多个 Region,每个 Meta 分区记录一部分用户表和分区管理的情况。(有了meta表,就可以得到region和HRegionServer的对应关系,可以进行Region定位:客户端通过 ZooKeeper 获取 Meta 表(分区表)存储的地址,首先在对应的 Regionserver上获取 Meta 表的信息(meta表存在Regionserver上),得到所需的Region对应的Regionserver的信息,然后从Region 服务器上找到所需的数据)
Store
HFile 存储在 Store 中,一个 Store 对应 HBase 表中的一个列族。
HFile
这是在磁盘上保存原始数据的实际的物理文件,是实际的存储文件。StoreFile 是以 Hfile的形式存储在 HDFS 的。
Block Cache:见4.2
第二章 HBase 快速入门
2.1 HBase 安装部署
2.1.1 Zookeeper 正常部署
首先保证 Zookeeper 集群的正常部署,并启动之:
https://www.cnblogs.com/wkfvawl/p/15539847.html#scroller-16
2.1.2 Hadoop 正常部署
Hadoop 集群的正常部署并启动:
https://www.cnblogs.com/wkfvawl/p/15369416.html#scroller-52
2.1.3 HBase 的解压
解压 Hbase 到指定目录:
[atguigu@hadoop102 software]$ tar -zxvf hbase-1.3.1-bin.tar.gz -C /opt/module
2.1.4 HBase 的配置文件
修改 HBase 对应的配置文件。
1)hbase-env.sh 修改内容:
export JAVA_HOME=/opt/module/jdk1.8.0_212 export HBASE_MANAGES_ZK=false
注释掉:
2)hbase-site.xml 修改内容:
<configuration> <property> <name>hbase.rootdir</name> <value>hdfs://hadoop102:8020/HBase</value> </property> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <!-- 0.98 后的新变动,之前版本没有.port,默认端口为 60000 --> <property> <name>hbase.master.port</name> <value>16000</value> </property> <property> <name>hbase.zookeeper.quorum</name> <value>hadoop102,hadoop103,hadoop104</value> </property> <property> <name>hbase.zookeeper.property.dataDir</name> <value>/opt/module/zookeeper-3.5.7/zkData</value> </property> </configuration>
3)regionservers:
hadoop102
hadoop103
hadoop104
4)软连接 hadoop 配置文件到 HBase:
ln -s /opt/module/hadoop-3.1.3/etc/hadoop/core-site.xml /opt/module/hbase/conf/core-site.xml
ln -s /opt/module/hadoop-3.1.3/etc/hadoop/hdfs-site.xml /opt/module/hbase/conf/hdfs-site.xml
2.1.5 HBase 远程发送到其他集群
[atguigu@hadoop102 module]$ xsync hbase/
2.1.6 HBase 服务的启动
1.启动方式
[atguigu@hadoop102 hbase]$ bin/hbase-daemon.sh start master
[atguigu@hadoop102 hbase]$ bin/hbase-daemon.sh start regionserver
提示:如果集群之间的节点时间不同步,会导致 regionserver 无法启动,抛出ClockOutOfSyncException 异常。
修复提示:
a、同步时间服务
https://www.cnblogs.com/wkfvawl/p/15369416.html#scroller-54
b、属性:hbase.master.maxclockskew 设置更大的值
<property> <name>hbase.master.maxclockskew</name> <value>180000</value> <description>Time difference of regionserver from master</description> </property>
2.启动方式 2
[atguigu@hadoop102 hbase]$ bin/start-hbase.sh
对应的停止服务:
[atguigu@hadoop102 hbase]$ bin/stop-hbase.sh
2.1.7 查看 HBase 页面
HBase的端口
| HBase Master | 16000 | hbase-client-1.x.x.jar | RegionServer接入 | |
| 16010 | HTTP | http://namenode1:16010/ | 集群监控 | |
| HBase RegionServer | 16020 | N/A | 客户端接入 | |
| 16030 | HTTP | http://datanode1:16030/ | 节点监控 |
启动成功后,可以通过“host:port”的方式来访问 HBase 管理页面,例如:
http://hadoop102:16010
2.2 HBase Shell 操作
2.2.1 基本操作
1.进入 HBase 客户端命令行
[atguigu@hadoop102 hbase]$ bin/hbase shell
2.查看帮助命令
hbase(main):001:0> help
3.查看当前数据库中有哪些表
hbase(main):002:0> list
2.2.2 表的操作
1.创建表
hbase(main):002:0> create \'student\',\'info\'
2.插入数据到表
hbase(main):003:0> put \'student\',\'1001\',\'info:sex\',\'male\' hbase(main):004:0> put \'student\',\'1001\',\'info:age\',\'18\' hbase(main):005:0> put \'student\',\'1002\',\'info:name\',\'Janna\' hbase(main):006:0> put \'student\',\'1002\',\'info:sex\',\'female\' hbase(main):007:0> put \'student\',\'1002\',\'info:age\',\'20\'
3.扫描查看表数据
hbase(main):008:0> scan \'student\' hbase(main):009:0> scan \'student\',{STARTROW => \'1001\', STOPROW =>\'1001\'} hbase(main):010:0> scan \'student\',{STARTROW => \'1001\'}
4.查看表结构
hbase(main):011:0> describe ‘student’
5.更新指定字段的数据
hbase(main):012:0> put \'student\',\'1001\',\'info:name\',\'Nick\'
hbase(main):013:0> put \'student\',\'1001\',\'info:age\',\'100\'
6.查看“指定行”或“指定列族:列”的数据
hbase(main):014:0> get \'student\',\'1001\'
hbase(main):015:0> get \'student\',\'1001\',\'info:name\'
7.统计表数据行数
hbase(main):021:0> count \'student\'
8.删除数据
删除某 rowkey 的全部数据:
hbase(main):016:0> deleteall \'student\',\'1001\'
删除某 rowkey 的某一列数据:
hbase(main):017:0> delete \'student\',\'1002\',\'info:sex\'
9.清空表数据
hbase(main):018:0> truncate \'student\' Truncating \'student\' table (it may take a while): - Disabling table... - Truncating table... 0 row(s) in 3.8140 seconds
提示:清空表的操作顺序为先 disable,然后再 truncate。
10.删除表
首先需要先让该表为 disable 状态:
hbase(main):019:0> disable \'student\'
然后才能 drop 这个表:
hbase(main):020:0> drop \'student\'
提示:如果直接 drop 表,会报错:ERROR: Table student is enabled. Disable it first.
11.变更表信息 将 info 列族中的数据存放 3 个版本:
hbase(main):022:0> alter \'student\',{NAME=>\'info\',VERSIONS=>3}
hbase(main):022:0> get \'student\',\'1001\',{COLUMN=>\'info:name\',VERSIONS=>3}
https://blog.csdn.net/qq_33208851/article/details/105223419