安装版本:hadoop 3.3.4 + hbase 2.5.2
一、HBase简介
1、HBase定义
Apache HBase是以HDFS为数据存储的,一种分布式、可扩展的NoSQL数据库(非关系型,以k,v的形式存储数据)。
HBase可以认为是以HDFS为存储的数据库。
2、HBase数据模型
(1)HBase的设计理念依据Google的BigTable论文,论文中对于数据模型的首句介绍:
Bigtable是一个稀疏的、分布式的、持久的多维排序map(代码里的hashmap是单维的,并且一定是有序的)。
(2)之后对于映射的解释如下:
该映射由行键、列键和时间戳索引;映射中的每个值都是一个未解释的字节数组。
(3)最终HBase关于数据模型和BigTable的对应关系如下:
HBase使用与Bigtable非常相似的数据模型。用户将数据行存储在带标签的表中。数据行具有可排序的键和任意数量的列。该表存储稀疏,因此如果用户喜欢,同一表中的行可以具有疯狂变化的列。
(4)最终理解HBase数据模型的关键在于稀疏、分布式、多维、排序的映射。其中映射map指代非关系型数据库的key-value结构。
二、HBase逻辑结构
1、存储数据稀疏,原数据有留空的部分。
2、数据存储多维,不同的行具有不同的列。
3、数据存储整体有序,按照RowKey的字典序排列,RowKey为Byte数组。
4、列、列族、Row key
row key是按照字典顺序排序的。
5、按照行进行拆分
拆分出Region,它会有对应的row key的一个范围。每个Region的row key范围不交叉。
将表格按照行拆分,块名称为Region,用于实现分布式结构。
6、竖着进行拆分
拆分出来的叫store。以列族为单位。
按照列族切分为store用于底层存储到不同的文件夹中,便于文件对应。
三、HBase物理存储结构
1、物理结构
物理存储结构即为数据映射关系,而在概念视图的空单元格,底层实际根本不存储。
列是:Row Key + 列族 + 列名 + 时间戳。
HDFS有一个特点,不能修改数据,只能删除、重写、追加写。
HBase要在不能改数据的基础上,实现改数据的功能,如何实现——以时间戳标记不同的版本。实际上删除、重写、追加写也是加标记。
四、数据模型概念
1、Name Space
命名空间,类似于关系型数据库的database概念,每个命名空间下有多个表。HBase两个自带的命名空间,分别是hbase和default。hbase存放的是HBase内置的表,default是用户默认使用的命名空间。
2、Table
类似于关系型数据库的表概念。不同的是,HBase定义表时只需要声明列族即可,不需要声明具体的列。因为数据存储是稀疏的,所有往HBase写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase能够轻松应对字段变更的场景。
3、Row
HBase表中的每行数据都由一个RowKey和多个Column(列)组成,数据是按照RowKey的字段顺序存储的,并且查询数据时只能根据RowKey进行检索,所以RowKey的设计十分重要。HBase这个框架是不能写SQL的。
4、Column
HBase中的每个列都由Column Family(列族)和Column Qualifier(列限定符)进行限定,例如 info: name,info: age。建表时,只需指明列族,而列限定符无需预先定义。
5、Time Stamp
用于标识数据的不同版本(version),每条数据写入时,系统会自动为其加上该字段,其值为写入HBase的时间。
6、Cell
由 {rowkey, column family: column qualifier, timestamp} 唯一确定的单元类型key。cell中的数据全部是字节码形式存储。
就是BigTable里面map的模型(K,V)。
五、HBase基础架构
1、Master
主要进程,具体实现类为HMaster,通常部署在namenode上。
功能:负责通过ZK监控RegionServer进程状态,同时是所有元数据变化的接口。内部启动监控执行Region的故障转移和拆分的线程。
2、RegionServer
主要进程,具体实现类为HRegionServer,部署在datanode上。
功能:主要负责数据cell的处理。同时在执行区域的拆分和合并的时候,由RegionServer来实际执行。
3、此处的region由3个RegionServer随机管理,尽量均衡。
表格hbase:meta是一个特例,它存储在hdfs,但是由master管理。
4、hdfs集群-存储表格数据
HBase把表格的数据存储到hdfs上面,按照namespace -> table -> region -> store 的格式划分文件夹存储。在store中存储HFile,内部为对应的cell。
六、架构角色
1、Master
实现类为HMaster,负责监控集群中所有的RegionServer实例。主要作用如下:
(1)管理元数据表格hbase:meta,接收用户对表格创建修改删除的命令并执行。
(2)监控region是否需要进行负载均衡,故障转移和region的拆分。
通过启动多个后台线程监控实现上述功能:
(1)LoadBalancer(负载均衡器)
周期性监控region分布在RegionServer上面是否均衡,由参数hbase.balancer.period控制周期时间,默认5分钟。
(2)CatalogJanitor(元数据管理器)
定期检查和清理hbase:meta中的数据。meta表内容在后面介绍。
(3)MasterProcWAL(master预写日志处理器)
把master需要执行的任务记录到预写日志WAL中,如果master宕机,让backupMaster读取日志继续干。
2、Region Server
Region Server实现类为HRegionServer,主要作用如下:
(1)负责数据cell的处理,例如写入数据put,查询数据get等。
(2)拆分合并region的实际执行者,由master监控,由RegionServer执行。
3、Zookeeper
HBase通过Zookeeper来做master的高可用、记录RegionServer的部署信息、并且存储有meta表的位置信息。
HBase对于数据的读写操作时直接访问Zookeeper的,在2.3版本推出Master Registry模式,客户端可以直接访问master。使用此功能,会加大对master的压力,减轻对Zookeeper的压力。
4、HDFS
HDFS为HBase提供最终的底层数据存储服务,同时为HBase提供高容错支持。
七、安装zookeeper
1、因为hadoop是单机伪集群环境,所以测试环境zookeeper也用单机安装
cd /tmp
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz -C /appserver/
cd /appserver
mv apache-zookeeper-3.7.1-bin/ zookeeper
2、将conf路径下的zoo_sample.cfg修改为zoo.cfg
修改:
dataDir=/appserver/zookeeper/zkData
3、操作命令
启动:bin/zkServer.sh start
查看:bin/zkServer.sh status
关闭:bin/zkServer.sh stop
八、安装HBase
1、采用伪集群安装
cd /tmp
wget https://dlcdn.apache.org/hbase/2.5.2/hbase-2.5.2-bin.tar.gz
tar -zxvf hbase-2.5.2-bin.tar.gz -C /appserver/
cd /appserver
mv hbase-2.5.2/ hbase
2、配置环境变量
vi /etc/profile
添加
export HBASE_HOME=/appserver/hbase
export PATH=$PATH:$HBASE_HOME/bin
使配置生效
source /etc/profile
3、hbase配置,hbase-env.sh,配置内部环境
进入hbase安装目录的conf目录下
vi hbase-env.sh
修改
export HBASE_MANAGES_ZK=false
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.362.b08-1.el7_9.x86_64
(1)不使用hbase自带的zookeeper
(2)如果不在hbase-env.sh指定JAVA_HOME会报错,Error: JAVA_HOME is not set,用系统环境变量不行?
4、hbase配置,hbase-site.xml,配置参数
进入hbase安装目录的conf目录下
vi hbase-site.xml
删除<configuration>内的原有内容,添加
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>hadoop001</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/appserver/zookeeper/zkData</value>
</property>
<property>
<name>hbase.rootdir</name>
<value>hdfs://hadoop001:8020/hbase</value>
</property>
<property>
<name>hbase.wal.provider</name>
<value>filesystem</value>
</property>
(1)hbase.cluster.distributed:表示我们部署分布式的hbase
(2)hbase.zookeeper.quorum:表示使用zookeeper的地址
(3)hbase.zookeeper.property.dataDir:zookeeper配置的zkData路径
(4)hbase.rootdir:把hbase数据放到hdfs的路径,这里是在根目录下建立hbase目录
(5)hbase.wal.provider:避免object is not an instance of declaring class异常,master启动不了
5、配置regionservers
就是hbase的节点
vi regionservers
hadoop001
6、解决log4j与hadoop冲突(可以不改)
mv /appserver/hbase/lib/client-facing-thirdparty/log4j-slf4j-impl-2.17.2.jar /appserver/hbase/lib/client-facing-thirdparty/log4j-slf4j-impl-2.17.2.jar.bak
7、操作命令
(1)单点启动
bin/hbase-daemon.sh start master
bin/hbase-daemon.sh start regionserver
(2)集群启动
bin/start-hbase.sh
(3)停止服务
bin/stop-hbase.sh
(4)单点停止
bin/hbase-daemon.sh stop regionserver
bin/hbase-daemon.sh stop master
8、启动日志
bin/start-hbase.sh
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/appserver/hadoop/hadoop-3.3.4/share/hadoop/common/lib/slf4j-reload4j-1.7.36.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/appserver/hbase/lib/client-facing-thirdparty/log4j-slf4j-impl-2.17.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Reload4jLoggerFactory]
running master, logging to /appserver/hbase/logs/hbase-root-master-hadoop001.out
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/appserver/hadoop/hadoop-3.3.4/share/hadoop/common/lib/slf4j-reload4j-1.7.36.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/appserver/hbase/lib/client-facing-thirdparty/log4j-slf4j-impl-2.17.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Reload4jLoggerFactory]
2023-02-07 13:39:54,922 INFO [main] master.HMaster (HMaster.java:main(3289)) - STARTING service HMaster
2023-02-07 13:39:54,924 INFO [main] util.VersionInfo (VersionInfo.java:logVersion(112)) - HBase 2.5.2
2023-02-07 13:39:54,924 INFO [main] util.VersionInfo (VersionInfo.java:logVersion(112)) - Source code repository git://86723393537f/home/zhangduo/hbase-rm/output/hbase revision=3e28acf0b819f4b4a1ada2b98d59e05b0ef94f96
2023-02-07 13:39:54,924 INFO [main] util.VersionInfo (VersionInfo.java:logVersion(112)) - Compiled by zhangduo on Thu Nov 24 02:06:40 UTC 2022
2023-02-07 13:39:54,924 INFO [main] util.VersionInfo (VersionInfo.java:logVersion(112)) - From source with checksum 5c7b894071d91dbef2c883800191e24f2bf5aba50de95836fd2c15fdb3fafc8df6784f55fcc6765eef1b41428bde68fbef626e000b21579bfdab031c3b4763e6
hadoop001: running regionserver, logging to /appserver/hbase/bin/../logs/hbase-root-regionserver-hadoop001.out
jps出现了HMaster、HRegionServer
jps
3889 HRegionServer
23218 ResourceManager
22755 DataNode
22965 SecondaryNameNode
3672 HMaster
14331 QuorumPeerMain
23547 NodeManager
22573 NameNode
4398 Jps
9、hbase管理页面
http://hadoop001:16010
九、踩坑记录
1、启动后日志出现异常
查看jps有HMaster、HRegionServer进程,但是访问16010,只看到backup master以及不显示regionserver情况,下面能看到master进程一直显示正在启动中,Initialize ServerManager and schedule SCP for crash servers
2023-02-07 13:28:05,065 WARN [RS-EventLoopGroup-1-2] concurrent.DefaultPromise: An exception was thrown by org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper$4.operationComplete()
java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.hbase.io.asyncfs.ProtobufDecoder.<init>(ProtobufDecoder.java:64)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper.processWriteBlockResponse(FanOutOneBlockAsyncDFSOutputHelper.java:342)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper.access$100(FanOutOneBlockAsyncDFSOutputHelper.java:112)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper$4.operationComplete(FanOutOneBlockAsyncDFSOutputHelper.java:424)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:590)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:557)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:492)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:185)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper.initialize(FanOutOneBlockAsyncDFSOutputHelper.java:418)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper.access$300(FanOutOneBlockAsyncDFSOutputHelper.java:112)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper$5.operationComplete(FanOutOneBlockAsyncDFSOutputHelper.java:476)
at org.apache.hadoop.hbase.io.asyncfs.FanOutOneBlockAsyncDFSOutputHelper$5.operationComplete(FanOutOneBlockAsyncDFSOutputHelper.java:471)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:590)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:583)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:559)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:492)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:636)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:625)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:105)
at org.apache.hbase.thirdparty.io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.fulfillConnectPromise(AbstractEpollChannel.java:653)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.finishConnect(AbstractEpollChannel.java:691)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.epollOutReady(AbstractEpollChannel.java:567)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:489)
at org.apache.hbase.thirdparty.io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:397)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at org.apache.hbase.thirdparty.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at org.apache.hbase.thirdparty.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:750)
是因为要删除/hbase/MasterData/oldWALs内容,提示报错。后来查到是hbase使用了AsyncFSWAL导致的:
https://blog.csdn.net/chuiguixin3900/article/details/100970566/
https://blog.csdn.net/jinluming19/article/details/122101283
网上说是版本兼容问题,其实是官方bug!!!
解决办法是添加:
<property>
<name>hbase.wal.provider</name>
<value>filesystem</value>
</property>
十、官方版本兼容图表
https://hbase.apache.org/book.html#basic.prerequisites
十一、hbase三种启动方式
1、类型
Standalone:单机
Pseudo-distributed:伪集群
Fully-distributed:完全集群
2、在单机启动backup master和多个regionserver
https://hbase.apache.org/book.html#quickstart_pseudo
启动backup master
bin/local-master-backup.sh start 2
启动regionserver
bin/local-regionservers.sh start 2 3
关闭命令
bin/local-master-backup.sh stop 2
bin/local-regionservers.sh stop 2 3
后面的数字表示,在原有默认端口号上增加的数字,比如master端口为16010,则启动的backup master端口为16012
3、管理页面
master:http://hadoop001:16010
backup master:http://hadoop001:16012
4、jps出现2个HMaster、3个HRegionServer
jps
3889 HRegionServer
23218 ResourceManager
22755 DataNode
22965 SecondaryNameNode
5143 HRegionServer
3672 HMaster
6249 Jps
14331 QuorumPeerMain
23547 NodeManager
5323 HRegionServer
22573 NameNode
4878 HMaster
十二、hbase shell
使用hbase shell检验
bin/hbase shell
hbase:005:0> status
1 active master, 1 backup masters, 3 servers, 0 dead, 0.6667 average load
Took 0.4928 seconds