目录
在大数据处理领域,Hadoop已经成为了不可或缺的重要框架,而HBase作为Hadoop生态系统中的关键组件,为海量数据的存储和高效访问提供了强大的支持。本文将深入探讨HBase的相关知识,包括其数据模型、基本架构、安装配置过程、Shell操作以及Java API的使用,并结合实际案例展示其在大数据处理中的应用。
一、HBase简介
(一)数据模型
HBase的数据模型与传统关系型数据库有很大不同,它采用了一种基于列族的数据存储方式,具有以下核心概念:
- 命名空间(NameSpace):类似于关系型数据库中的database概念,用于对表进行业务划分,方便组织和管理表。例如,可以根据不同的业务模块或项目创建不同的命名空间,将相关的表放在同一个命名空间下。
- 表(Table):类似关系型数据库中的table表概念,但在HBase中定义表时只需声明列族,无需预先定义具体的列。这使得HBase在处理半结构化和非结构化数据时具有更大的灵活性,能够适应不断变化的数据结构。
- 列(Column):由ColumnFamily(列族)和ColumnQualifier(列限定符)共同限定,例如info:name、info:age等。建表时只需指明列族,列限定符可在插入数据时动态按需增加,这种设计可以根据实际需求灵活扩展数据列。
- 行(Row):表中的每行数据由一个RowKey和多个Column组成,数据按照RowKey的字典顺序存储。RowKey的设计至关重要,因为所有对表的访问都要通过RowKey,它直接影响数据的读写性能和查询效率。合理设计RowKey可以使数据的存储和检索更加高效,例如根据经常查询的字段或范围来设计RowKey。
- 列族(ColumnFamily):创建HBase表时给定列族,在插入数据时列(字段)可以动态增加。每个列族可以有一个或多个列限定符,列族的设计应该根据数据的访问模式和存储需求来确定,将经常一起访问的列放在同一个列族中可以提高读写性能。
- 列限定符(ColumnQualifier):用于在列族内唯一标识一个列,与列族组合形成完整的列表示形式,如“列族:列限定符”。它可以根据具体的数据属性进行定义,使数据的表示更加清晰和精确。
- 行键(RowKey):在表中必须唯一且必须存在,是访问表数据的关键。通过RowKey可以进行单个RowKey访问、RowKey范围访问或全表扫描,因此RowKey的选择和设计需要综合考虑数据的分布和查询需求,以优化数据的读写操作。
- 时间戳(TimeStamp):用于标识数据的不同版本,HBase在写入数据时会自动加上当前系统时间戳作为该字段值。这使得HBase能够存储同一数据的多个历史版本,适用于需要记录数据变化历史的场景,如数据审计和版本控制。
- 单元(Cell):由{RowKey,ColumnFamily,ColumnQualifier,TimeStamp}唯一确定,Cell中的数据没有类型,全部以字节码形式储存。这种存储方式提供了高度的灵活性,能够存储各种类型的数据,但也需要在应用层进行数据类型的解析和处理。
(二)基本架构
HBase的基本架构主要由以下几个组件组成:
- master节点
- 作为集群的协调者,负责监控所有的RegionServer实例。其主要功能包括管理元数据表hbase:meta,接收并处理用户关于表的创建、修改和删除请求,以及监控region的分布情况,确保负载均衡,处理region的故障转移和拆分操作。
- 这些功能通过多个后台线程实现,如LoadBalancer周期性检查region在RegionServer上的分布是否均衡(默认周期为5分钟),CatalogJanitor负责定期检查和清理hbase:meta表中的冗余或过期数据,MasterProcWAL记录master需要执行的任务到预写日志WAL中,以确保在master故障时backupMaster能够读取日志并恢复操作。
- RegionServer节点
- 负责存储和处理HBase中的数据,主要职责包括处理数据的读写操作(如put写入和get查询),以及执行region的拆分和合并操作,这些操作在master的监控下进行。RegionServer将数据存储在本地文件系统中,并与HDFS协作,确保数据的高可用性和容错性。
- Zookeeper
- HBase利用Zookeeper来管理master的高可用性、记录RegionServer的状态和位置信息,以及存储meta表的位置。在HBase 2.3版本推出的MasterRegistry模式下,客户端可以直接与master通信,减少了对Zookeeper的依赖,但可能会增加master的负担。Zookeeper在HBase集群中起到了协调和管理的重要作用,确保集群的稳定运行。
- HDFS
- 作为HBase的底层存储系统,为HBase提供高可用和高容错的数据存储服务。HBase将数据存储在HDFS的文件中,利用HDFS的分布式存储和冗余备份机制,保证数据的可靠性和可扩展性。HDFS的分布式特性使得HBase能够处理大规模的数据存储和访问需求。
二、HBase的安装与配置
(一)安装Zookeeper
- 首先验证master、slave1、slave2等虚拟机上的java是否正常安装,通过在命令行输入
来检查。java -version
- 在master、slave1、slave2虚拟机上,将apache - zookeeper - 3.5.7 - bin.tar.gz文件拖拽到/opt目录下。
- 分别在三台虚拟机上执行
命令解压Zookeeper文件。tar - zxvf /opt/apache - zookeeper - 3.5.7 - bin.tar.gz - C /opt
- 接着执行
命令创建zkData目录。mkdir - p /opt/apache - zookeeper - 3.5.7 - bin/zkData
- 使用
命令编辑myid文件,在master上写入1,slave1上写入2,slave2上写入3。vi /opt/apache - zookeeper - 3.5.7 - bin/zkData/myid
- 将/opt/apache - zookeeper - 3.5.7 - bin/conf下的zoo_sample.cfg复制并改名为zoo.cfg,然后修改master的zoo.cfg文件,添加
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888
内容,并修改dataDir
路径为/opt/apache - zookeeper - 3.5.7 - bin/zkData/
。可以选择直接在slave1、slave2虚拟机下修改zoo.cfg文件,或者使用scp分发模式将修改后的zoo.cfg文件发送到slave1和slave2。 - 在master、slave1、slave2上均修改
vi /etc/profile.d/my_env.sh
文件,添加#ZK_HOME
export ZK_HOME=/opt/apache-zookeeper-3.5.7-bin
export PATH=$PATH:$ZK_HOME/bin
source /etc/profile
命令重启配置文件。 - 最后分别在master、slave1、slave2上使用
zkServer.sh start
开启Zookeeper服务,并使用zkServer.sh status
查看状态,其中slave2可能会成为leader。为了方便操作,可以在master上添加启动文件vi /opt/apache - zookeeper - 3.5.7 - bin/bin/my_zk.sh
,通过该文件可以群控slave1、slave2的Zookeeper服务,并添加执行权限chmod u + x /opt/apache - zookeeper - 3.5.7 - bin/bin/my_zk.sh
,使用my_zk.sh status
等命令进行验证。
(二)安装及配置HBase集群
- 确保hadoop集群和Zookeeper正常运行,可以通过在master虚拟机上执行
start - dfs.sh
、start - yarn.sh
和my_zk.sh start
等命令来启动相关服务,并检查服务状态。 - 将hbase - 2.4.11 - bin.tar.gz文件拖拽到master的/opt目录下,然后执行
命令解压HBase文件。tar - zxvf /opt/hbase - 2.4.11 - bin.tar.gz - C /opt/
- 在master上修改环境变量,编辑
vi /etc/profile.d/my_env.sh
文件,添加#HBASE_HOME
export HBASE_HOME=/opt/hbase-2.4.11
export PATH=$PATH:$HBASE_HOME/bin
,并使用source /etc/profile
命令使环境变量生效。 - 为了使用手动安装的Zookeeper,需要修改hbase - env.sh文件,在文件尾部添加
export HBASE_MANAGES_ZK = false
。 - 修改hbase - site.xml文件,清除原文件自带的所有
<property>
,并添加以下配置:<property><name>hbase.rootdir</name><value>hdfs://master:8020/hbase</value></property>
,指定HBase在HDFS上的存储路径。<property><name>hbase.master</name><value>master</value></property>
,设置HBase master节点的地址。<property><name>hbase.cluster.distributed</name><value>true</value></property>
,启用HBase的分布式模式。<property><name>hbase.zookeeper.quorum</name><value>master,slave1,slave2</value></property>
,指定Zookeeper集群的地址。<property><name>hbase.session.timeout</name><value>60000000</value></property>
,设置会话超时时间。<property><name>dfs.support.append</name><value>true</value></property>
,支持HDFS的追加操作。<property><name>hbase.unsafe.stream.capability.enforce</name><value>false</value></property>
,允许在某些情况下进行不安全的操作(仅用于开发环境)。
- 修改regionservers文件,删除原本内容,添加master、slave1、slave2等节点信息。
- 解决HBase和Hadoop的log4j兼容性问题,将HBase的jar包
slf4j - reload4j - 1.7.33.jar
修改成bak文件,执行mv /opt/hbase - 2.4.11/lib/client - facing - thirdparty/slf4j - reload4j - 1.7.33.jar /opt/hbase - 2.4.11/lib/client - facing - thirdparty/slf4j - reload4j - 1.7.33.jar.bak
命令。 - 将HBase安装好后的文件和my_env.sh文件发送给slave1、slave2,使用
等命令。scp -r root@master:/opt/hbase-2.4.11/ root@slave1:/opt
scp -r root@master:/opt/hbase-2.4.11/ root@slave2:/opt
scp root@master:/etc/profile.d/my_env.sh root@slave1:/etc/profile.d
scp root@master:/etc/profile.d/my_env.sh root@slave2:/etc/profile.d
- 分别在slave1、slave2上使用
source /etc/profile
命令重启配置文件。 - 启动HBase之前,必须先启动hdfs、yarn、zookeeper服务,然后在master上执行
start - hbase.sh
命令启动HBase。可以在浏览器中打开http://192.168.121.3:16010/
和http://192.168.121.3:16030/
(假设master的IP为192.168.121.3)查看HBase的管理界面。如果在进入hbase shell时出现hbase master is initializing
错误,可以在master主机上先停止hbase(stop - hbase.sh
),在slave1上使用zkCli.sh
并删除/hbase(rmr /hbase
),然后在master主机上重新启动hbase(start - hbase.sh
)。
三、HBase Shell实操
创建
- help命令:能够展示 HBase 中所有能使用的命令,主要使用的命令有 namespace 命令空间相关, DDL 创建修改表格,DML 写入读取数据。
- 创建命名空间,命令:create_namespace 'bigdata'
- 查看命名空间,命令:list_namespace
- 在 bigdata 命名空间中创建表格 student,两个列族分别是info和msg。info 列族数据维护的版本数为 5 个,msg列族如果不写默认版本数为 1:
- 写法1:命名空间:新表,表示在对应的命名空间下创建新表:
- 如:create 'bigdata:student1',{NAME => 'info', VERSIONS => 5}, {NAME => 'msg'}
- 写法2:新表,表示在默认空间下创建新表
- 如,create 'student1',{NAME => 'info', VERSIONS => 5}, {NAME => 'msg'}
- 写法1:命名空间:新表,表示在对应的命名空间下创建新表:
字段名 | 解释 |
NAME | 列族名 |
VERSIONS | 版本数 |
KEEP_DELETED_CELLS | 历史版本是否可见 |
... |
删除表
删除前要disable停用,disable 'bigdata:student1',然后删除表drop 'bigdata:student1'
检查表是否存在,exists 'bigdata:student1'
重新创建student表,列族为info,create 'student','info'
要修改表需先停用表,disable 'student',添加一个relationship列族,alter 'student',NAME=>'relationship',改完重新启用enable 'student'
插入数据,插入3个学生xiaoming,xiaohong,xiaozhang,行键分别是1001,1002,1003,同时relationship有father和mothe
put 'student','1001','info:name','xiaoming' |
put 'student','1001','relationship:father','zhangsan' |
put 'student','1001','relationship:mother','lisi' |
put 'student','1002','info:name','xiaohong' |
put 'student','1002','relationship:father','wangwu' |
put 'student','1002','relationship:mother','zhaoliu' |
put 'student','1003','info:name','xiaozhang' |
put 'student','1003','relationship:father','sunqi' |
put 'student','1003','relationship:mother','zhouba' |
put 'student','1003','info:name','xiaozhan' |
put 'student','1003','relationship:father','sunqi' |
put 'student','1003','relationship:mother','zhouba' |
行键 | info | relationship | |
name | father | mother | |
1001 | xiaoming | zhangsan | lisi |
1002 | xiaohong | wangwu | zhaoliu |
1003 | xiaozhang | sunqi | zhouba |
查询表
查单行(行键1003),get 'student','1003':
查多行,使用scan和STARTROW、STOPROW控制行数,scan 'student',{STARTROW=>'1002',STOPROW =>'1004'}
删除数据
删除某个单元格数据,命令:delete 'student','1003','relationship:mother'
删除某行键所有数据,命令:deleteall 'student','1003'