HBase集群架构

准备工作

新建四台虚拟机

master, slave1, slave2, slave3

分别设置固定IP

确认已经搭建好Hadoop集群,见如下文章

Hadoop环境搭建

配置完成后拓扑如下,

HBase需要依赖ZooKeeper集群进行数据管理,HBase数据库也需要分别在多个节点搭建,

故HBase配置完毕之后的拓扑结构如下,

ZooKeeper集群安装

简介

Apache ZooKeeper

ZooKeeper是一个分布式服务框架,主要用来解决分布式系统中经常遇到的数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项等等。

基本工作过程

上图描述的就是一个ZooKeeper的节点计算图。

由若干个Server和若干个Client所够成,其中所有Server之间只有一个特殊的节点叫Leader,其余Server节点叫做Follower

如当某个Client对Server1发起写请求时,

  • 数据将会写入这个Server1

  • 这个Server1将会变更后传递到Leader

  • Leader将变更同步到所有的Server,同步的过程所有的Server均上写锁,待Leader同步完后释放所有节点的锁。

注意事项

  • 只要还有一半以上的节点存活ZooKeeper节点就还能提供服务

  • 配置个数一般为奇数个

    • 若有四个节点,则至少需要两个以上

    • 若有三个节点,则至少需要两个以上

    • 故搭建三个最划算

    • 同理,一般奇数个最划算

  • 当Leader出问题时,所有的Follower将会重新重新选举一个新的Leader继续工作

Zookeeper的安装配置

下载安装包

进入如下网址下载安装包

Apache ZooKeeper

我这里下载的是apache-zookeeper-3.8.0-bin.tar.gz

解压安装包

1
2
tar -zxvf apache-zookeeper-3.8.0-bin.tar.gz
mv apache-zookeeper-3.8.0-bin /opt

修改配置文件

进入zookeeper配置文件夹

cd /opt/apache-zookeeper-3.8.0-bin/conf/

将配置模板复制一份

cp zoo_sample.cfg zoo.cfg

使用vim打开zoo.cfg发现已经存在了一些配置模板和说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 心跳时间间隔
tickTime=2000
# follower与leader初次连接的超时时间,单位为心跳数
initLimit=10
# 请求响应的超时时间,单位为心跳数
syncLimit=5
# 数据存放的目录
dataDir=/usr/lib/zookeeper
# 日志存放的目录
dataLogDir=/var/log/zookeeper
# 客户端的访问端口为2181
clientPort=2181


# 配置三个server
# 格式为 主机名:leader与follower交互使用的端口:重新选举时需要用的端口
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888

注意node1, node2, node3分别为我配置的三个主机的主机名,已分别修改三台主机的hosts文件

配置各个节点

注意,以下操作若无特殊说明均在master节点操作各个slave node

发送安装包到各节点

1
2
3
scp -r /opt/apache-zookeeper-3.8.0-bin node1:/opt/apache-zookeeper-3.8.0-bin
scp -r /opt/apache-zookeeper-3.8.0-bin node2:/opt/apache-zookeeper-3.8.0-bin
scp -r /opt/apache-zookeeper-3.8.0-bin node3:/opt/apache-zookeeper-3.8.0-bin

各节点新建以下文件夹

mkdir /usr/lib/zookeeper

mkdir /var/log/zookeeper

1
2
3
4
5
6
7
8
ssh node1 "mkdir /usr/lib/zookeeper"
ssh node1 "mkdir /var/log/zookeeper"

ssh node2 "mkdir /usr/lib/zookeeper"
ssh node2 "mkdir /var/log/zookeeper"

ssh node3 "mkdir /usr/lib/zookeeper"
ssh node3 "mkdir /var/log/zookeeper"

配置各节点的myid

这些myid就代表着zoo.cfg中server.x中的x

1
2
3
ssh node1 "echo 1 > /usr/lib/zookeeper/myid"
ssh node2 "echo 2 > /usr/lib/zookeeper/myid"
ssh node3 "echo 3 > /usr/lib/zookeeper/myid"

配置各节点环境变量

基本原型

1
2
export ZK_HOME=/opt/apache-zookeeper-3.8.0-bin
export PATH=$PATH:$ZK_HOME/bin

由于master与所有的slave节点环境均一致,故环境变量也一致,可以修改master节点后将/opt/profile分别通过scp上传到各节点即可完成配置。

1
2
3
scp /etc/profile node1:/etc/profile
scp /etc/profile node2:/etc/profile
scp /etc/profile node3:/etc/profile

启动Zookeeper

分别ssh到各个slave节点上,使用zkServer.sh start即可启动zookeeper节点

使用zkServer.sh status可查看当前节点状态

1
2
3
4
5
6
7
8
9
10
11
[root@node1 ~]# zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.8.0-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED


[root@node1 ~]# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.8.0-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Error contacting service. It is probably not running.

查看结果发现此时还未正常工作,是因为zookeeper要求至少两台及以上节点启动时候,才能正常工作

启动node2

1
2
3
4
5
6
7
8
9
[root@node2 ~]# zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.8.0-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@node2 ~]# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.8.0-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader

此时发现node2成功运行,作为leader

启动node3

1
2
3
4
5
6
7
8
9
[root@node3 ~]# zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.8.0-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@node3 ~]# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.8.0-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower

此时发现node2成功运行,作为follower

HBase安装配置

下载安装包

Apache HBase – Apache HBase Downloads

我这里下载的版本为最新的稳定版hbase-2.4.11-bin.tar.gz

解压安装包

1
2
3
4
# 解压安装包
tar -zxvf hbase-2.4.11-bin.tar.gz
# 移动安装包
mv hbase-2.4.11 /opt

修改配置文件

hbase所有的配置文件都在/opt/hbase-2.4.11/conf文件夹下,我们逐一修改

hbase-site.xml

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
33
34
35
36
37
38
<configuration>
<!-- 此目录regionserver共享的目录,用来持久存储HBase的数据,其默认值为:${hbase.tmp.dir}/hbase,如果不修改默认值,数据将会在集群重启时丢失。 -->
<property>
<name>hbase.rootdir</name>
<!-- 设置hdfs存储路径 -->
<value>hdfs://master:8020/hbase</value>
</property>

<property>
<name>hbase.master</name>
<value>master</value>
</property>


<!-- 设置hbase集群为分布式集群 -->
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>

<!-- 设置zookeeper集群,用英文逗号分隔 -->
<property>
<name>hbase.zookeeper.quorum</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>

<!-- 设置hdfs能够追加数据 -->
<property>
<name>dfs.support.append</name>
<value>true</value>
</property>

<property>
<name>hbase.unsafe.stream.capability.enforce</name>
<value>false</value>
</property>

</configuration>

hbase-env.sh

1
2
3
4
#配置Java环境变量
export JAVA_HOME=/usr/java/jdk1.8.0_202-amd64
#关闭hbase自带的zookeeper
export HBASE_MANAGES_ZK=false

regionservers

1
2
3
node1
node2
node3

发送配置好的安装包到各个节点

1
2
3
scp -r /opt/hbase-2.4.11 node1:/opt/
scp -r /opt/hbase-2.4.11 node2:/opt/
scp -r /opt/hbase-2.4.11 node3:/opt/

设置环境变量

在所有节点分别追加以下内容到/etc/profile中

1
2
export HBASE_HOME=/opt/hbase-2.4.11
export PATH=$PATH:$HBASE_HOME/bin

修改完master环境后直接scp传送到各个slave节点

1
2
3
scp /etc/profile node1:/etc/profile
scp /etc/profile node2:/etc/profile
scp /etc/profile node3:/etc/profile

启动HBase

首先确保启动了zookeeper和hadoop集群

然后直接在master节点start-hbase.sh命令启动

即可在master节点启动HMaster

还可自动在其余slave节点启动HRegionServer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@master ~]# jps
30224 SecondaryNameNode
30529 ResourceManager
29881 NameNode
126333 HMaster
126767 Jps
[root@master ~]# ssh node1
Last login: Wed Apr 20 04:02:35 2022
[root@node1 ~]# jps
57395 Jps
49940 QuorumPeerMain
5173 DataNode
57192 HRegionServer
5305 NodeManager

NodeManager与DataNode为Hadoop

QuorumPeerMain为ZooKeeper的进程

HMaster与HRegionServer为HBase的进程

进入HBase shell

命令行输入hbase shell即可进入hbase shell界面

输入list_namespace即可查看当前的命名空间

HBase 踩坑

hbase中输入任何命令均提示ERROR: KeeperErrorCode = NoNode for /hbase/master

1
2
3
4
5
6
7
8
hbase:001:0> list_namespace
NAMESPACE

ERROR: KeeperErrorCode = NoNode for /hbase/master

For usage try 'help "list_namespace"'

Took 0.1580 seconds

jps查看进程信息发现HMaster也挂了

进入hbase安装目录下的logs查看

cd /opt/hbase-2.4.11/logs

vim hbase-root-master-master.log

在最后末尾发现了一个java异常

1
2
3
4
5
6
7
8
9
10
11
2022-04-23 23:00:31,233 ERROR [master/master:16000:becomeActiveMaster] master.HMaster: ***** ABORTING master master,16000,1650726017761: Unhandled exception. Starting shutdown. *****
java.net.ConnectException: Call From master/192.168.166.100 to master:9000 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.apache.hadoop.net.NetUtils.wrapWithMessage(NetUtils.java:824)
at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:754)
at org.apache.hadoop.ipc.Client.getRpcResponse(Client.java:1544)
at org.apache.hadoop.ipc.Client.call(Client.java:1486)
at org.apache.hadoop.ipc.Client.call(Client.java:1385)

原来是连接hdfs服务挂了,原因是端口号9000配置错误,我的hdfs端口号配置的是8020。修改hbase安装目录下的conf/hbase-site.xml,通过scp同步到各个slave节点,重启所有节点,重新启动所有服务

1
2
3
4
5
6
7
8
9
10
11
12
start-dfs.sh
start-yarn.sh
ssh node1
zkServer.sh start
exit
ssh node2
zkServer.sh start
exit
ssh node3
zkServer.sh start
exit
start-hbase.sh

现在再进入hbase shell总算成功运行命令了