1. 为什么还在装 HBase 2.3.7
HBase 2.3.7 这个版本在不少团队里服役了好几年,用起来有个特点:稳。新版本功能确实多,但生产环境图的是省心,2.3.7 处于 2.x 分支相对成熟的维护期,很多底层 bug 都已经修掉,网上踩坑记录也齐全,出问题能查到答案。再加上它跟 Hadoop 3.x 系列配合默契,不少公司的老集群就是 Hadoop 3.1.2、3.2.x 搭 HBase 2.3.x 这么跑过来的,二进制的兼容性基本不用操心。
如果你的集群是 Hadoop 2.x,那也能装,但要注意配置里有些参数语义跟 3.x 不一样,后面我会专门提。JDK 方面,官方要求 JDK 8,实际部署时建议用 OpenJDK 8,不要图新鲜上 JDK 11,HBase 2.3.7 的某些反射逻辑在更高版本 JDK 下有兼容问题,没必要给自己找麻烦。
这篇文章面向的是准备在生产或测试环境里从零部署 HBase 2.3.7 的同学,不管你是第一次接触 HBase,还是之前装过 1.x 版本想升级,按下面的步骤走都能少踩不少坑。我会把从环境检查、解压部署、配置修改到启动验证的完整流程都过一遍,中间穿插我在实际安装中遇到的问题和绕过的弯路,希望能帮你一次性把集群跑起来。
2. 部署前的环境检查和版本匹配
很多人装 HBase 装到一半失败,追根溯源都是环境没对上号。HBase 对底层依赖不算苛刻,但几个关键组件的版本必须心里有数。
2.1 JDK 版本与 Hadoop 版本的硬性约束
HBase 2.3.7 官方编译是基于 JDK 8 做的,所以 JDK 8 是稳妥选择。你可以在每台节点上执行 java -version 确认版本,如果输出里有 “openjdk version 1.8.x” 或者 “java version 1.8.x”,那就没问题。如果是 JDK 11 以上,建议先装回 JDK 8,别等到启动失败再折腾。
Hadoop 版本上,HBase 2.3.7 官方文档给了两个参照:Hadoop 2.10.x 和 Hadoop 3.3.x。实际生产里用 Hadoop 3.1.2、3.2.1、3.2.2 的都有,都能跑。要注意的是 Hadoop 3.x 的 YARN 默认端口和 HBase 的 Web UI 端口没有冲突,不用刻意调。但 Hadoop 2.x 的话,NameNode 的 8020 端口和 HBase 的 RPC 默认端口 16020 可能会出现占用问题,这种一般出现在和别的组件混部的时候,后面排查章节细说。
2.2 ZooKeeper 选型:内置还是独立
HBase 强依赖 ZooKeeper 做分布式协调,不管选哪种方式,ZooKeeper 都必须存在。很多人初次部署为了省事,直接用 HBase 自带的 ZooKeeper,也就是配置里不设置 HBASE_MANAGES_ZK,让 HBase 自己启动一个 ZooKeeper 实例。这种做法在小规模测试环境上可以,快速验证功能没问题,但生产环境强烈建议使用独立的 ZooKeeper 集群,至少 3 个节点,这样 HBase 的 RegionServer 宕机后,HMaster 能通过 ZK 快速感知并做故障转移。
我实测下来,HBase 自带 ZooKeeper 最大的问题是它会在 HBase 进程退出时一并把 ZK 关掉,如果 ZK 上还跑着其他业务(比如 Kafka、Solr),会影响面就大了。独立部署 ZK 后,HBase 和 ZK 的生命周期分开管理,重启 HBase 不会影响 ZK 里的其他临时节点,排查问题时也容易区分是 HBase 挂了还是 ZK 挂了。
如果你决定用独立 ZooKeeper,注意版本:ZK 3.4.x 和 3.5.x 都支持 HBase 2.3.7,但 3.5.x 之前的版本不建议用,因为 3.5 之后 ZK 才支持动态重配置,运维上更灵活。安装方式用官方 tar 包解压就行,配置 zoo.cfg 里的 dataDir 和 server.id=host:port:port,然后每台节点写入 myid 文件,最后用 zkServer.sh start 启动,用 zkServer.sh status 检查状态。这里有个经验:ZooKeeper 的 dataDir 千万别放在 /tmp 下,系统一重启数据就没了,HBase 的 meta 表元数据会错乱,别问我怎么知道的。
2.3 主机名、hosts 与免密钥配置
HBase 集群通信全部走主机名,不要用 IP 地址写配置。每台机器上编辑 /etc/hosts,把所有节点的 IP 和主机名对应关系都加进去,格式如下:
192.168.1.10 hbase-master 192.168.1.11 hbase-region1 192.168.1.12 hbase-region2所有节点都要有完整映射,不能只写本机。HBase 启动时,HMaster 会通过主机名连接各 RegionServer,如果某台机器只配置了 localhost 映射,会出现 “UnknownHostException” 或者连接超时的诡异现象。
免密钥登录也是必须的,虽然 HBase 本身不强制要求,但它的启动脚本会通过 SSH 到所有 RegionServer 上执行远程命令。配置方法就是经典的 ssh-keygen 生成密钥,然后把公钥追加到所有节点的 authorized_keys 里。有个实用命令可以一条命令把公钥分发到所有节点:
for host in hbase-master hbase-region1 hbase-region2; do ssh-copy-id -i ~/.ssh/id_rsa.pub root@${host} done执行完用 ssh hbase-region1 date 验证,如果不用输密码就能返回时间,说明免密配置成功。
2.4 时钟同步与文件句柄数
HBase 的 RegionServer 和 HMaster 之间通过心跳维持状态,如果节点间时钟偏差超过一定阈值(默认 30000 毫秒),会出现心跳超时、RegionServer 被误判为宕机的情况。生产环境一定要配置 NTP 或 chrony 做时钟同步。Linux 上用 chronyd 比较多:
systemctl enable chronyd systemctl start chronyd chronyc tracking确认每个节点的时钟偏差控制在 10 秒以内就够用了。
另外,HBase 的 RegionServer 需要打开大量文件句柄,默认的 ulimit -n 1024 远远不够,必须调高。修改 /etc/security/limits.conf:
* soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535改完重新登录,用 ulimit -n 验证是否生效。这个不调的话,HBase 运行一段时间后就会出现 “Too many open files” 的报错,RegionServer 直接挂掉,数据块写入失败,那真是灾难现场。
3. 下载、解压与目录规划
3.1 从镜像站下载并校验完整性
HBase 2.3.7 的官方下载地址在 Apache 镜像站上,但国内直连 Apache 的速度不太稳定,建议用国内镜像。下载时顺便把对应的 .sha512 文件也拿下来,校验一下完整性,避免下载损坏。命令如下:
wget -c https://mirrors.aliyun.com/apache/hbase/2.3.7/hbase-2.3.7-bin.tar.gz echo "下载的sha512值" | sha512sum -c hbase-2.3.7-bin.tar.gz.sha512-c 参数会输出 OK 表示文件完整。注意下载的是 hbase-2.3.7-bin.tar.gz,不是 hbase-2.3.7-src.tar.gz,src 版本是源码包,需要自己编译,初学者容易选错。
3.2 解压与目录约定
我习惯把 HBase 解压到 /opt 下,然后做一个软链接指向当前版本,这样升级的时候只需要替换软链接,配置和日志的路径都跟着变,非常方便:
tar -zxvf hbase-2.3.7-bin.tar.gz -C /opt ln -s /opt/hbase-2.3.7 /opt/hbase chown -R hadoop:hadoop /opt/hbase目录设计上,我通常会把数据目录(hbase.rootdir 对应的 HDFS 路径)和本地临时目录(hbase.tmp.dir)分开。hbase.rootdir 指向 HDFS 上的路径,比如 hdfs://hbase-master:8020/hbase,这个路径会在 HDFS 上自动创建。hbase.tmp.dir 指到本地磁盘,比如 /data/hbase-tmp,注意这个目录一定要有足够的磁盘空间,RegionServer 的 MemStore 刷写和日志恢复时都会用到它。
3.3 环境变量配置
编辑 /etc/profile 或用户级 .bashrc,加入以下内容:
export HBASE_HOME=/opt/hbase export PATH=$PATH:$HBASE_HOME/bin执行 source /etc/profile 生效。这里有个细节:HBASE_HOME 最好用软链接路径而不是真实路径,后续升级版本时环境变量不用改。另外 HBase 的启动脚本会去找 HADOOP_HOME,如果你的 Hadoop 没配在系统环境变量里,还需要在 hbase-env.sh 里单独指一下,不然启动时会报 “HADOOP_HOME does not exist”。
4. 核心配置文件详解与避坑指南
配置是安装 HBase 的重头戏,80% 的启动失败问题都出在这。HBase 的配置集中在 conf 目录下的 hbase-env.sh、hbase-site.xml、regionservers 三个文件里,下面逐个拆。
4.1 hbase-env.sh:JVM 参数与运行模式
编辑 conf/hbase-env.sh,重点设置以下几个参数:
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export HBASE_MANAGES_ZK=false export HBASE_HEAPSIZE=4G export HBASE_OPTS="-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70"JAVA_HOME 必须指到 JDK 安装的真实路径,不要指望脚本自动识别,我遇到过多个环境因为 JAVA_HOME 没配对导致启动脚本找不到 java 命令。
HBASE_MANAGES_ZK=false 表示使用外部 ZooKeeper,如果设置为 true,HBase 会自己启一个 ZK,测试环境可以,生产环境建议 false。
HBASE_HEAPSIZE 是 HMaster 和 RegionServer 的默认堆大小,单位是 GB。这里有个经验值:RegionServer 的堆内存建议 8GB 起步,如果你的机器内存紧张,至少给到 4GB,不然频繁 Full GC 会导致 RegionServer 长时间停顿,HMaster 会把这个节点判定为宕机。
GC 参数上,JDK 8 用 CMS 是常见选择。不过 CMS 在 JDK 9 之后被废弃了,所以一定要确保 JDK 是 8 再配置这个参数。
4.2 hbase-site.xml:从入门到生产的关键配置
这是最核心的配置文件,每个参数都值得花时间理解。以下是我在生产环境验证过的一套完整配置:
<configuration> <property> <name>hbase.rootdir</name> <value>hdfs://hbase-master:8020/hbase</value> </property> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <property> <name>hbase.zookeeper.quorum</name> <value>hbase-master,hbase-region1,hbase-region2</value> </property> <property> <name>hbase.zookeeper.property.clientPort</name> <value>2181</value> </property> <property> <name>hbase.tmp.dir</name> <value>/data/hbase-tmp</value> </property> <property> <name>hbase.wal.provider</name> <value>filesystem</value> </property> <property> <name>hbase.regionserver.handler.count</name> <value>100</value> </property> </configuration>hbase.rootdir 必须和你的 Hadoop NameNode 的 RPC 地址匹配,如果你 Hadoop 的 fs.defaultFS 配的是 hdfs://hbase-master:8020,那这里就写同样地址加 /hbase 路径。注意端口别写错,Hadoop 3.x 默认是 9820,但很多人用的 Hadoop 3.1.x 默认还是 8020,以你的 core-site.xml 里的实际配置为准。这个地址错了,HBase 启动时连不上 HDFS,会报 “java.net.ConnectException: Connection refused” 之类的错误。
hbase.cluster.distributed 必须设置为 true,HBase 才会以分布式模式运行,否则它会尝试在本地文件系统上建数据目录,起一个伪分布式实例,不是我们要的效果。
hbase.zookeeper.quorum 填所有 ZooKeeper 节点的主机名,逗号分隔,不需要加端口。如果 ZK 跑在非默认端口,另加 hbase.zookeeper.property.clientPort 指定。
hbase.wal.provider 选 filesystem 是标准做法,写 HDFS 的 WAL(Write-Ahead Log)。有的场景会配 asyncfs,但这个要求 HDFS 支持异步 IO,老版本 Hadoop 不兼容,保守一点就用 filesystem。
hbase.regionserver.handler.count 是 RegionServer 能同时处理的 RPC 请求数,默认是 30,如果你单台机器上的 Region 数量比较多,或者客户端并发高,建议提到 100。这个值不是越大越好,太大浪费线程资源,太小则容易出现 RPC 排队。
4.3 regionservers 文件:声明 Worker 节点
conf/regionservers 文件里每一行写一个 RegionServer 的主机名,HMaster 启动时会逐个 SSH 上去拉起 HRegionServer 进程。示例如下:
hbase-region1 hbase-region2注意不要写 IP 地址,也不要在行尾加空格或注释,脚本解析很机械,多了奇怪字符会导致误判。这个文件在 2.x 版本中如果配置了多列,比如 RegionServer 和 BackupMaster 分开列的语法,要确认你的版本支持,2.3.7 用最简单的一行一个主机名最稳。
4.4 HBase 与 Hadoop 配置联动
HBase 启动时会读取 HADOOP_CONF_DIR 下的 core-site.xml 和 hdfs-site.xml,所以要么把这些配置文件软链到 HBase 的 conf 目录下,要么在 hbase-env.sh 里设置 HADOOP_CONF_DIR 环境变量。推荐后一种:
export HADOOP_CONF_DIR=/opt/hadoop/etc/hadoop不配这个的话,HBase 会找不到 HDFS 的配置,即便 hbase.rootdir 写对了,也可能因为无法获取 NameNode 地址而启动失败。
5. 启动流程与验证手段
配置写完后,启动顺序有讲究:先 Hadoop 再 ZooKeeper 最后 HBase,每步都要确认无误再继续。
5.1 确保 Hadoop 处于健康状态
执行 hdfs dfsadmin -report 确认 HDFS 各节点状态正常,如果看到 Live datanodes 数量和你实际节点数一致,说明 HDFS 没问题。如果输出异常,先别动 HBase,回到 Hadoop 排查。另外 HDFS 的安全模式要退出,执行 hdfs dfsadmin -safemode get 查看结果,如果显示 Safe mode is ON,说明 NameNode 还在启动恢复阶段,等一会再查。
5.2 启动 ZooKeeper 并验证选主
独立部署的 ZK 每台节点执行 zkServer.sh start,然后用 zkServer.sh status 检查。正常情况会输出 Mode: leader 或 Mode: follower,集群里只有一个 leader,其他都是 follower。如果没有 leader 出现,检查 zoo.cfg 里的 server.id 和 myid 是否一一对应,这个错位会导致 ZK 选举失败。
5.3 启动 HBase
在主节点执行:
/opt/hbase/bin/start-hbase.sh脚本会自动 SSH 到所有 RegionServer 节点启动 HRegionServer 进程。看到 “starting master” 和 “starting regionserver” 的输出并不代表成功了,这只是脚本把命令发出去了,进程可能立刻退出。过 10 到 30 秒后,用 jps 检查进程是否都在:
jps | grep H主节点上应该看到 HMaster,RegionServer 节点上应该看到 HRegionServer。如果缺少某个进程,去对应的 logs 目录下找 hbase-hmaster- .log 和 hbase-hregionserver- .log。日志路径默认在 HBase 解压目录的 logs 子目录下。
5.4 验证 HBase 可用性
进程都在不代表一切正常,还需要做几个功能验证。
首选检查 Web UI。HMaster 的 Web 界面默认端口是 16010,浏览器访问 http://hbase-master:16010 ,能看到 RegionServer 列表和各个 Region 的数量,说明基础状态正常。
然后进入 HBase Shell 做实际读写操作:
/opt/hbase/bin/hbase shell在 shell 里执行:
create 'test_table', 'cf1' put 'test_table', 'row1', 'cf1:name', 'test_value' scan 'test_table'这条 scan 能返回刚才 put 的数据,就说明整个链路通了:HBase 能写 HDFS、能通过 ZK 协调、RegionServer 正常服务。最后用 disable 和 drop 把测试表删掉,保持集群干净:
disable 'test_table' drop 'test_table'有些教程不做清理,留着测试表占资源,还会影响后续的监控指标判断,建议测试完就删干净。
6. 常见问题排查与实战技巧
环境搭建过程中遇到的问题千奇百怪,我把频率最高的几个整理成了一张排查表,后续会逐条展开讲讲背后的原因和解决思路。
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| HMaster 进程启动后自动退出 | hbase.rootdir 配置错误或 HDFS 未就绪 | 查看 hbase-hmaster-*.log,确认 HDFS 地址 |
| RegionServer 连不上 HMaster | 主机名解析失败 | ping 主机名,检查 /etc/hosts |
| 启动报 Address already in use | 端口被占用,可能是其他组件冲突 | 执行 netstat -tlnp or ss -tlnp 查端口 |
| hbase shell 执行失败 | ZooKeeper 状态异常 | zkServer.sh status 查看各节点状态 |
| RegionServer 频繁 Full GC | 堆内存配置不足 | 调大 HBASE_HEAPSIZE,检查 GC 日志 |
| “NoNode for /hbase/master” | HMaster 未成功注册 | 检查 HMaster 日志,看根因 |
6.1 HMaster 启动后秒退的根因分析
最常见的 HMaster 秒退场景就是 hbase.rootdir 写错。有的同学把路径写成了 file:///hbase,这会让 HBase 试图在本地文件系统上创建数据目录,但你的 hbase.cluster.distributed 又是 true,两者矛盾直接退出。另一种常见错误是把端口写成了 9000,这是 Hadoop 1.x 时代的 NameNode 端口,到了 Hadoop 3.x 必须写实际端口,以 core-site.xml 里面的 fs.defaultFS 为准。
排查时先去看日志的异常堆栈,注意日志里其实会明确告诉你哪里不对,比如 “Filesystem rootdir is not a valid HDFS path”。不要只盯着启动脚本的输出看,那是没用的,日志才是真正说话的地方。
6.2 RegionServer 连接 HMaster 失败之谜
所有 RegionServer 节点启动后,在 HBase Master 的 Web UI 上只能看到一个节点,其他节点全部显示处于连接状态。这类问题基本都是主机名解析导致的。HMaster 通过 regionservers 文件中写入的主机名去连接 RegionServer,如果 RegionServer 那边 /etc/hosts 没有配好自己的主机名和 IP 映射,会反向解析失败,导致 Master 识别不了。
解决方法是确保每个节点都 ping 得通所有其他节点的主机名,在每台机器上执行:
for i in hbase-master hbase-region1 hbase-region2; do ping -c 1 $i; done全部通了再启动服务。这个检查花不了两分钟,能省掉一小时的排查时间。
6.3 端口冲突与防火墙问题
HBase 2.3.x 有默认端口清单:HMaster Web UI 是 16010,HMaster RPC 是 16000,RegionServer Web UI 是 16030,RegionServer RPC 是 16020。这些端口在生产环境里经常和其他应用冲突,尤其是如果你在同一台机器上还装了其他分布式系统(比如 Elasticsearch 的 transport 端口 9300 不会跟这些冲突,但一些定制应用可能会占 16020)。
检查端口占用命令:
ss -tlnp | grep -E '16000|16010|16020|16030'如果端口被占,可以在 hbase-site.xml 里加配置调整,比如:
<property> <name>hbase.master.port</name> <value>16010</value> </property> <property> <name>hbase.regionserver.port</name> <value>16020</value> </property>另外防火墙也要注意:确保这些端口在防火墙白名单里,否则跨节点的 RPC 通信会被阻断,表现就是进程都在,但客户端连不上。
6.4 /hbase/master ZNode 缺失的处理
启动完成后,HBase shell 执行任意操作报 “NoNode for /hbase/master”。这个报错说明 HMaster 没有在 ZooKeeper 上注册成功。可能的原因有几个:
一是 HMaster 进程本身没起来,用 jps 确认过 HMaster 存在后再排查其他可能性。二是 ZooKeeper 集群状态异常,HMaster 连不上 ZK,自然无法注册。三是 HMaster 注册后立刻挂了,比如配置错误导致进程退出,ZK 上的临时节点就消失了。
有一个调试小技巧:用 ZK 的客户端查看 HBase 目录是否存在:
/opt/zookeeper/bin/zkCli.sh -server hbase-master:2181 ls /如果输出里没有 hbase 目录,说明 HMaster 根本没注册上。用 get /hbase/master 看是否有数据,如果有数据,把它删掉再重启 HMaster:
deleteall /hbase/master这种情况通常发生在多次重启导致旧 ZNode 残留,新 HMaster 注册不上,删掉后重新启动就正常了。
7. 几个冷门但关键的生产配置
除了常规配置外,有几个参数在安装时容易被忽略,但直接影响集群的长期稳定性。这里单独列出来,方便大家部署时直接照抄。
7.1 RegionServer 堆内内存与堆外内存
HBase 的 BlockCache 有两种实现:堆内 LruBlockCache 和堆外 BucketCache。默认方式是在堆内,如果你机器上内存充足(比如 64GB),建议给 RegionServer 分 16GB 堆内存,然后配置堆外 BucketCache 作为补充:
<property> <name>hfile.block.cache.size</name> <value>0.4</value> </property> <property> <name>hbase.bucketcache.ioengine</name> <value>offheap</value> </property> <property> <name>hbase.bucketcache.size</name> <value>8192</value> </property> <property> <name>hbase.bucketcache.combinedcache.enabled</name> <value>true</value> </property>这个配置下,堆内 LruBlockCache 占堆的 40%,堆外 BucketCache 用 8GB 内存来缓存 HFile 块,适合读多写少的场景。
7.2 MemStore 与 Region 大小调整
默认 MemStore 占堆的 40%,当达到这个比例时,Region 会开始刷写。如果你的业务写入量大,刷写频繁,可以调低 hbase.regionserver.global.memstore.size 到 0.35,给 BlockCache 留更多空间。反之如果读多写少,可以调高到 0.5。
默认 Region 大小是 10GB,如果你的单表数据量不大,可以调低:
<property> <name>hbase.hregion.max.filesize</name> <value>10737418240</value> </property>这里 10737418240 就是 10GB 的字节数,调成 5368709120(5GB)可以加快 Region 分裂的频率,提高并发度,但也会带来更多的小文件,需要定期做 Major Compaction,属于取舍问题。
7.3 预分区与建表策略
安装完成后,首次建表强烈建议做预分区。HBase 默认一个 Region 承载所有数据,当数据量达到拆分阈值才自动分裂,分裂瞬间会有短暂的停顿。为了避免这个停顿,建表时根据 rowkey 范围提前拆好 10 个 Region,比如 rowkey 是 8 位数字,可以按前缀 0-9 分 10 个区:
create 'user_info', {NAME => 'cf1', VERSION => 1}, {NUMREGIONS => 10, SPLITALGO => 'HexStringSplit'}SPLITALGO 的 HexStringSplit 会把 rowkey 空间均分成 10 段。实测预分区表写入性能比单 Region 快不少,尤其是写入量大的场景,非常值得做。
8. 我踩过的坑和优化建议
安装部署这件事,真正有价值的往往不是官方文档里的标准流程,而是那些文档里没写、实际运行中才会碰到的问题。这里把我个人踩过的坑分享出来,希望能给你省点时间。
第一个坑是 Hadoop 的 core-site.xml 没有配 fs.trash.interval。HBase 删表或删数据后,HDFS 上的数据不会进回收站,直接被物理删除。有一次我在测试环境误删了一张存有重要测试数据的表,根本恢复不了。配置方法是在 core-site.xml 里加:
<property> <name>fs.trash.interval</name> <value>1440</value> </property>这样删除的数据会在回收站里存 1 天,至少留了后悔药。
第二个坑是 RegionServer 的本地临时目录权限。hbase.tmp.dir 配到了 /data 下,但 /data 目录的属主是 root,HBase 进程用 hadoop 用户跑,启动时直接抛 Permission denied。这个报错在日志里很容易被忽略,因为它被掩埋在大量 INFO 级别日志中。后来我养成了习惯:所有 HBase 相关目录创建后立即 chown 给运行用户,一劳永逸。
第三个坑是 HMaster 和 NameNode 部署在同一台机器上时,内存需要统筹规划。NameNode 默认堆 4GB,HMaster 默认堆 4GB,加上系统占用,16GB 内存的机器容易吃紧。我的做法是 NameNode 给 6GB,HMaster 给 4GB,RegionServer 不放在这台机器上,保证专职角色有富余资源。
第四个坑是 RegionServer 的 handler.count 没调优之前,业务高峰期出现过 RPC 队列堆积,表现为 HBase Shell 操作耗时从 10ms 涨到 500ms。后来我把 handler.count 从 30 调到 100,并且配合调整了 hbase.ipc.server.read.threadpool.size,吞吐明显改善。这个参数值得刚部署完就调好,别等线上出问题再改。
第五个坑是关于配置热生效的认知。很多人改完 hbase-site.xml 后直接执行 hbase shell 命令,以为会自动生效,实际上 HBase 的参数读的是启动时加载的配置,改完必须重启相关进程。倒是 ZooKeeper 上的某些参数可以通过 HBase Shell 动态修改,比如:
update_all_config从运维角度,如果你不确定某个参数是否支持动态生效,最简单的方式是重启对应进程,稳一点比快一点更重要。
最后说一个实用的小工具组合:部署完 HBase 后,建议立刻配置监控,把 HMaster 和 RegionServer 的 JVM 指标、Region 数量、请求延迟都纳入监控范围。早期发现异常比事后处理故障要优雅得多。我习惯用 Prometheus 加 HBase exporter 来做,安装非常轻量,但带来的收益非常大。监控指标里优先看 RegionServer 的 Heap 使用率、MemStore 大小、BlockCache 命中率这三个,基本能判断出集群的健康状态。如果 BlockCache 命中率长期低于 50%,说明读请求大量落到 HDFS 上了,就要考虑加大缓存或优化 rowkey 设计。
分布式系统安装部署是门实践学科,文档固然重要,但真正让你长经验的永远是亲手踩过的坑。按这套流程走下来,你的 HBase 2.3.7 集群应该能保持稳定运行。后面我会再写几篇关于 HBase 性能调优和日常运维的文章,如果你在部署过程中碰到任何没遇到过的问题,欢迎在评论里聊聊,一起想办法解决。