这是我参与「第四届青训营 」笔记创作活动的第5天
课前 (必须)
分布式系统理论基础
HBase 核心数据模型
- HBase 是存储计算分离架构,以 HDFS 作为分布式存储底座。数据实际存储在 HDFS。
- HBase 依赖 Zookeeper 实现元数据管理和服务发现。Client 通过 Zookeeper 配置连接到 HBase集群
- Log-Structured Merge Tree 了解 LSM tree 的基本结构和特性。
-
HBase 写流程:
- 数据先写入 WAL 持久化,用于宕机时恢复内存里丢失的数据;
- 再写入内存态 MemStore,以一种跳表(SkipList)数据结构提供有序的数据和高效的随机读写;
- 当满足特定条件时(比如内存中数据过多,或间隔时间过长),MemStore 数据以 HFile 格式写入 HDFS
-
HBase 读流程
- 首次读某个 rowkey 时,client 需要从 Zookeeper 获取 hbase:meta 表位于哪个 RegionServer上;
- 然后访问该 RegionServer 查询 hbase:meta 表该 rowkey 对应 region 所在的 RegionServer B;
- Client 缓存该位置信息,去 RegionServer B 读取 rowkey;
- 基于该region内可能存在该 rowkey 的 HFile 和 MemStore 构建一个最小堆,用以全局有序地 scan 数据(具体实现可搜索参考 LSM tree 设计原理)
-
Compaction
-
HBase 基于策略和定期整理 HFile 文件集合,将多个有序小文件合并成若干个有序的大文件。
-
HBase 提供两种 compaction 类型:
- Minor compaction: 指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程中不会处理已经Deleted或Expired的Cell。一次 Minor Compaction 的结果是更少并且更大的StoreFile。
- Major compaction: 指将所有的StoreFile合并成一个StoreFile,这个过程会清理三类没有意义的数据:被删除的数据、TTL过期数据、版本号超过设定版本号的数据。另外,一般情况下,major compaction时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此线上业务都会将关闭自动触发major compaction功能,改为手动在业务低峰期触发。
-
Compaction 触发条件:
- memstore flush:可以说compaction的根源就在于flush,memstore 达到一定阈值或其他条件时就会触发flush刷写到磁盘生成HFile文件,正是因为HFile文件越来越多才需要compact。HBase每次flush之后,都会判断是否要进行compaction,一旦满足minor compaction或major compaction的条件便会触发执行。
- 后台线程周期性检查: 后台线程 CompactionChecker 会定期检查是否需要执行compaction,检查周期为hbase.server.thread.wakefrequency*hbase.server.compactchecker.interval.multiplier,这里主要考虑的是一段时间内没有写入请求仍然需要做compact检查。其中参数 hbase.server.thread.wakefrequency 默认值 10000 即 10s,是HBase服务端线程唤醒时间间隔,用于log roller、memstore flusher等操作周期性检查;参数 hbase.server.compactchecker.interval.multiplier 默认值1000,是compaction操作周期性检查乘数因子。10 * 1000 s 时间上约等于2hrs, 46mins, 40sec。
- 手动触发:是指通过HBase Shell、Master UI界面或者HBase API等任一种方式 执行 compact、major_compact等命令。
-
客户端定位数据
直连HBase的客户端需要配置对应的Zookeeper信息来定位数据所在的RegionServer,具体包括zookeeper集群实例的地址列表和该hbase集群在zookeeper中对应的根路径。
直连客户端具体定位步骤如下:
- 客户端访问Zookeeper获取元信息表hbase:meta所在的regionserver地址;
- 客户端访问该regionserver查询要读/写的table的rowkey在哪个regionserver;
- 客户端访问存数据的regionserver进行读写。
通过Thrift协议访问HBase的客户端需要ThriftServer的地址,通过ThriftServer转发请求。可以通过Consul实现thriftserver的服务发现。
LSM tree
HBase将每个column family的数据独立管理,称为HStore。一个HStore包含一到多个物理文件块(称为HFile)存储到HDFS。实际存储时每个column family独立存储,一个column family对应多个HFile文件块。
每个HFile内的数据按rowkey有序存储,但HFile间没有顺序保证。这一特点是由于LSM的写入方式决定的,下面介绍LSM树的读写流程:
- 写入:写入操作先记录到Write-Ahead Log持久化(可选)保存,然后写入内存中的MemStore。WAL可以保证实例挂掉或重启后丢失的内存数据可以恢复。
- 读取:从写入逻辑可以看出HFile包含的rowkey范围会有交集,以全局rowkey顺序读取就需要以一种归并排序的形式组织所有HFile。HBase会打开该cf下所有HFile,分别构建一个迭代器用以rowkey从小到大扫对应HFile的数据。所有这些迭代器又以当前指向rowkey的大小组织成一个最小堆,这样堆顶的迭代器指向的rowkey就是下一个全局最小的rowkey。迭代该rowkey后重新调整最小堆即可。
搭建hbase集群
准备工作
HBase是依赖Hadoop的,所以hapoop不要停。
先停掉spark集群,减少资源占用情况.
在宿主机上搭建
1. 搭建HBase集群
hostnamectl set-hostname master-01-hbase-test
修改/etc/hosts
vim /etc/hosts
10.8.46.35 master-01-hbase-test
10.8.46.197 master-02-hbase-test
10.8.46.190 slave-01-hbase-test
(1)解压安装包
mkdir -p /usr/local/hbase
cd /opt
tar -zxvf hbase-2.4.4-bin.tar.gz -C /usr/local/hbase
(2)编辑全局变量
vim /etc/profile
增加以下全局变量
export HBASE_HOME=/usr/local/hbase/hbase-2.4.4
export PATH=$PATH:$HBASE_HOME/bin
export HBASE_HOME PATH SPARK_HOME SCALA_HOME
#即时生效
source /etc/profile
(3)配置hbase-env.sh
cd /usr/local/hbase/hbase-2.4.4/conf
vim hbase-env.sh
export HBASE_MANAGES_ZK=false
export JAVA_HOME=/usr/local/jdk1.8
(4)配置hbase-site.xml
vim hbase-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!--HBase数据目录位置 ?-->
<property>
<name>hbase.rootdir</name>
<value>hdfs://master-01-spark-test:9000/hbase</value>
</property>
<!--启用分布式集群-->
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<!--默认HMaster HTTP访问端口-->
<property>
<name>hbase.master.info.port</name>
<value>16010</value>
</property>
<!--默认HRegionServer HTTP访问端口-->
<property>
<name>hbase.regionserver.info.port</name>
<value>16030</value>
</property>
<!--不使用默认内置的,配置独立的ZK集群地址-->
<property>
<name>hbase.zookeeper.quorum</name>
<value>zookeeper-01-test,zookeeper-02-test,zookeeper-03-test</value>
</property>
</configuration>
(4)配置regionservers
vim regionservers
slave-01-hbase-test
将这两个文件放进去
[root@master-01-hbase-test conf]# pwd
/usr/local/hbase/hbase-2.4.4/conf
[root@master-01-hbase-test conf]#
启动HBase集群
Master节点:/usr/local/hbase/hbase-2.4.4/bin/start-hbase.sh
Slave节点:/usr/local/hbase/hbase-2.4.4/bin/hbase-daemon.sh start regionserver
hbase集群 主节点1:http://10.8.46.35:16010/master-status#alltasks 主节点2:http://10.8.46.197:16010/master-status#alltasks 从节点1:http://10.8.46.190:16030/rs-status
主节点1 | 主节点2 | 从节点1 |
---|---|---|
\