首页 / 资讯中心 / 文章详情

HBase 2.3.7完整安装指南:环境配置、踩坑复盘与性能调优

HBase 2.3.7完整安装指南:环境配置、踩坑复盘与性能调优 ★ FEATURED ARTICLE
HBase 2.3.7这个版本说新不新、说老也不老。我在实际项目里从2.2.x迁到2.3.7之后明显感觉到它在Region分配、Compaction调度和内存管理上都更稳了小版本迭代修掉的那批问题恰好是生产环境最容易碰到的硬骨头。这篇就围绕HBase 2.3.7的完整安装展开——从环境规划、依赖准备、配置项逐条讲清楚到启动验证、踩坑复盘最后补几个值得优先调整的性能参数。内容按从零到能建表、能查数据、能正常跑任务的标准写适合刚接手HBase部署的运维、准备搭建测试集群的开发者以及想从老版本升级的人参考。1. 先算账为什么我选2.3.7以及环境怎么匹配HBase版本选择这事儿真不是挑个最新的就完事。太新的版本社区资料少、踩坑成本高太老的版本又缺功能甚至跟当前主流的Hadoop版本都有兼容性问题。2.3.7属于2.3.x分支比较后期的修复版本既有2.x的架构能力又把很多2.2时代遗留下来的稳定性问题修得差不多。对我来说2.3.7的最大价值是它在功能完整度、社区口碑和周边生态兼容性之间找到了一个比较舒服的平衡点。1.1 版本对应关系是第一个坑安装前最容易被忽略的就是版本联动关系。HBase不是独立运行的它要躺在HDFS上面存数据要靠Zookeeper协调分布式状态还要跑在JDK之上。这三样东西的版本没匹配好后面必然出幺蛾子。下面是我实测过比较稳的组合组件推荐版本说明JDK1.88u2022.3.x对JDK8的支持最稳定JDK11需要额外调Hadoop3.x如3.2.x/3.3.x推荐Hadoop 32.7老版本需要额外配置兼容Zookeeper3.4.x / 3.5.x3.5.x开启了新的Admin接口客户端写法有差异操作系统CentOS 7 / Ubuntu 18.04glibc和文件句柄限制需要提前处理HBase 2.3.7用了较新的Protocol Buffer和HDFS客户端逻辑如果Hadoop版本太旧会出现RPC协议不兼容比如RegionServer启动时反复报连接Master失败。最稳的路线是Hadoop 3.2.2以上HBase官方编译时也默认针对Hadoop 3.x做兼容性测试。1.2 集群规模规划与机器预算先想清楚要搭单机测试、伪分布式还是真正的分布式集群。这三个模式配置差异不小单机模式所有进程Master、RegionServer、Zookeeper、HDFS都跑在一台机器上主要用于本地开发验证配置文件里很多东西不用设置。伪分布式一台机器上分别启动多个进程但彼此通过localhost通信主要用来模拟分布式环境、跑功能测试。完全分布式至少三台机器Master和RegionServer分离Zookeeper单独或复用节点是生产环境的标准形态。我给一个三节点完全分布式的最小推荐配置你可以根据自己的机器规格和预算调整节点AMaster Zookeeper HDFS NameNode4核8G起步。节点BRegionServer HDFS DataNode Zookeeper8核16GRegionServer是内存大户。节点CRegionServer HDFS DataNode Zookeeper8核16G。RegionServer的内存建议优先保证HBase读写路径上的MemStore、BlockCache都吃堆内和堆外内存给得太少Region一多就直接崩溃。如果是单机测试2核4G也能跑但别指望性能。2. 依赖环境一次备齐后面才少折腾HBase安装本身其实不太复杂麻烦都在环境上。我在这个环节吃过亏所以这次把每个依赖项的验证方式都写清楚你照着做基本能避开80%的早期问题。2.1 JDK配置和容易忽略的细节先确认JDK版本HBase 2.3.7官方文档明确要求JDK 8太新的JDK版本会导致HBase运行时反射调用异常或者JVM参数不识别。装好之后务必在每台节点上执行java -version echo $JAVA_HOME我遇到过最典型的问题是JAVA_HOME只在登录shell里生效HBase通过SSH远程启动其他节点进程时拿不到这个环境变量导致启动脚本里出现JAVA_HOME is not set错误。解决方式很简单把JAVA_HOME写进/etc/profile或者HBase的hbase-env.sh里显式指定路径。实际操作中我会直接在hbase-env.sh里写死export JAVA_HOME/usr/local/jdk1.8.0_202这样就不会依赖用户的shell环境。另外注意JDK安装完最好用readlink -f $(which java)确认软链接实际指向的目录避免JAVA_HOME指到软链接本身而失效。2.2 Hadoop 3.x的准备格式化NameNode要谨慎如果你打算基于HDFS跑HBaseHadoop必须先启动。这里有一个新手特别容易踩的坑格式化NameNode的时机。hdfs namenode -format只能在首次运行时执行一次格式化一次就会生成新的cluster ID如果你后续又重复格式化或者多个节点之间cluster ID不一致DataNode会互相拒绝连接HDFS一直处于Live Nodes为0的状态。我在测试环境里验证多次格式化没问题是因为集群上没有真实数据。如果你在已有数据的HDFS上装HBase千万不要随便重新格式化。装完Hadoop之后先用hdfs dfsadmin -report确认所有DataNode都是Live状态再继续下一环节。HDFS没ReadyHBase启动时写不了rootdirMaster会一直刷FileSystem is not ready的报错。2.3 ZookeeperHBase的分布式协调大脑HBase对Zookeeper的依赖比想象中更深Master选举、RegionServer的上下线感知、meta表位置的定位全靠Zookeeper。装好Zookeeper之后先单独启动再通过客户端验证zkServer.sh start zkCli.sh -server hostname:2181 # 进入ZK命令行后执行 ls /正常情况下应该能看到zookeeper目录。如果没有启动成功HBase的Master和RegionServer会反复重试连接日志里大量出现ConnectionLossException。我建议每个节点都把hostname和IP的映射关系写好/etc/hostsZookeeper和HBase对主机名解析非常敏感经常出现明明IP能通但服务就是注册不上的诡异问题查到最后是hostname解析错了。如果要搭伪分布式Zookeeper同样需要以单机模式启动别跳过这一层。有太多人图省事直接用HBase内置的Zookeeper结果一重启集群就出各种隔离问题实在不建议这么干。3. hbase-site.xml里那些配置项我逐条讲清楚HBase安装配置的主战场就是三个文件hbase-env.sh、hbase-site.xml和regionservers。很多人直接复制网上的配置片段但不知道每一项为什么这么写一旦出问题就很难排查。我按实际部署顺序逐条讲。3.1 hbase-env.sh堆内存、GC和JAVA_HOMEhbase-env.sh里除了设置JAVA_HOME还有几个参数建议一开局就调好。HBASE_HEAPSIZE是Master和RegionServer的默认堆大小单位是GB。默认是1G但生产环境RegionServer建议至少8G以上否则Region一多、写入压力稍大频繁Full GC就会导致RegionServer和Master之间心跳超时最后被判定下线。HBASE_REGIONSERVER_OPTS和HBASE_MASTER_OPTS是给不同角色单独配置JVM参数的入口。比如我会给RegionServer开启G1GC并限制最大堆export HBASE_REGIONSERVER_OPTS-XX:UseG1GC -Xms8g -Xmx8g -XX:MaxDirectMemorySize4gMaxDirectMemorySize这里容易被忽略。HBase的BucketCache如果开启堆外模式读写路径会大量使用直接内存不显式配置的话默认值跟堆大小有关可能不够或者超预期。如果你不确定要不要堆外Cache就先不设这个值等压测后再说。3.2 hbase-site.xml的核心字段每一行都知道在干什么这是HBase安装过程中信息量最大的文件。我把我生产环境用的配置模板拿出来去掉注释逐项解释configuration property namehbase.rootdir/name valuehdfs://hadoop-master:8020/hbase/value /property property namehbase.cluster.distributed/name valuetrue/value /property property namehbase.zookeeper.quorum/name valuenode1,node2,node3/value /property property namehbase.zookeeper.property.clientPort/name value2181/value /property property namehbase.tmp.dir/name value/data/hbase/tmp/value /property property namehbase.wal.provider/name valueasyncfs/value /property property namehbase.unsafe.stream.capability.enforce/name valuefalse/value /property /configurationhbase.rootdirHBase数据在HDFS上的根目录。注意这个路径一定要写HDFS的绝对路径如果你写file:///开头就变成单机模式了RegionServer根本起不来。很多启动后Master正常RegionServer秒退的问题都源于这里写错。hbase.cluster.distributed设置为true表示分布式模式。这个坑很小影响很大。保持默认false的话即使多个进程启动也不会走Zookeeper协调。hbase.zookeeper.quorumZookeeper节点列表逗号分隔。这里写的是hostname不要写IP也别写localhost。HBase会把列表里的第一个节点作为初始连接点后续自动发现其他节点。hbase.tmp.dirHBase本地临时目录建议放到数据盘而不是根目录/tmp因为/tmp在重启时可能被清理同时空间也有限。hbase.wal.providerWAL写入实现asyncfs是2.x之后推荐的方式能够在HDFS上做到异步批量写入性能比之前默认的hdfs模式好。hbase.unsafe.stream.capability.enforce这是一个跟Hadoop版本相关的开关。如果Hadoop版本与HBase的HDFS客户端存在流能力协商问题需要设为false。尤其在Hadoop 3.2.x和HBase 2.3.x混搭时不关掉这个开关会频繁出现StreamCapability相关的异常。3.3 regionservers文件决定哪些节点跑RegionServerregionservers文件在conf/目录下每一行写一个节点hostname。它决定了start-hbase.sh启动时会把RegionServer进程派发到哪些节点。写错或者漏写节点会导致一部分机器上根本没有RegionServer进程master页面里的RegionServer数量永远少于预期。node1 node2 node3注意这里不要写localhost。即便单机测试也建议写实际hostname因为HBase内部会拿这个主机名去注册Zookeeper节点如果写localhost后续在Master UI上看到的是乱七八糟的地址而且跨节点复制配置时也容易混乱。3.4 分发配置和目录权限配置改好之后把整个HBase目录通过rsync或者scp同步到所有节点上。我常用rsync -avz /usr/local/hbase-2.3.7/ node2:/usr/local/hbase-2.3.7/同步完以后确认所有节点上HBase目录属主和权限一致最好用同一个系统用户比如hbase用户启动。如果用root启动HDFS里面写入的数据文件属主是root后续切到普通用户再做增量操作时会出现权限问题。HDFS上的/hbase根目录HBase在首次启动时会自动创建正常情况下不需要手动hdfs dfs -mkdir。不过如果你用的是非默认用户启动HBase就得先手动建目录并授权hdfs dfs -mkdir -p /hbase hdfs dfs -chown -R hbase:hadoop /hbase4. 启动顺序、验证手段跑通第一个表配置做完接下来就是启动和验证。启动顺序这事看着简单实际很多人折腾半天起不来是因为步骤乱了。4.1 正确的启动顺序我的习惯顺序是先HDFS再Zookeeper最后HBase。HBase的Master一启动就会去HDFS上检查rootdir同时去Zookeeper注册状态如果你顺序反了会看到日志里反复出现连接拒绝虽然HBase有重试机制但你无法判断到底是网络问题还是依赖没起来。Hadoop启动start-dfs.shZookeeper依次启动三节点集群zkServer.sh start验证HDFS和Zookeeper都Ready之后再启动HBasecd /usr/local/hbase-2.3.7/bin ./start-hbase.sh执行完start-hbase.sh之后它会通过SSH到各节点执行hbase-daemon.sh start regionserver。如果节点间没配好SSH免密登录启动脚本会卡住或者报错。4.2 验证手段进程、日志、UI、shell缺一不可启动之后不要急着建表按下面几步验证第一看进程。在Master节点上执行jps正常会看到HMaster和HRegionServer在其他RegionServer节点上执行至少会看到HRegionServer。如果某个节点只有HMaster没有HRegionServer说明集群模式没有真正生效多半是hbase.cluster.distributed没设true或者rootdir写到了本地路径。第二看日志。日志目录在$HBASE_HOME/logs/下重点看Master日志是否有Master has completed initialization的关键词以及RegionServer日志是否有Initializing HRegionServer的记录。如果看到大量ERROR可以用grep -i ERROR快速过滤出关键异常。第三看Web UI。HBase Master默认端口是16010浏览器访问http://master-host:16010正常能看到Master状态、RegionServer列表、系统表hbase:meta状态。如果页面能打开但RegionServer数量为0基本可以确定是RegionServer启动失败了。第四用Shell建表做一次真实读写测试cd /usr/local/hbase-2.3.7/bin ./hbase shell进入Shell后create test_table, cf1, cf2 put test_table, row1, cf1:name, hello get test_table, row1如果能正确返回hello说明整条链路客户端-RegionServer-HDFS是通的。第一次建表会比较慢因为要等meta表分配Region多等一会儿是正常的。5. 我在2.3.7安装中实际踩过的坑逐个复盘安装HBase的过程中有一些错误属于十个人九个人会碰的典型问题。我把自己的排查过程写下来比直接甩结论更有参考价值。5.1 坑一Hadoop版本不匹配导致的RpcTimeoutException我遇到过RegionServer启动后立刻开始向Master注册但反复超时。日志里出现org.apache.hadoop.hbase.ipc.RemoteWithExtrasException: org.apache.hadoop.hbase.exceptions.RpcTimeoutException一开始怀疑是网络问题但ping各节点完全通。后来对比了Hadoop和HBase的版本发现Hadoop用的是2.7.x而HBase 2.3.7用的是新版的Protobuf RPC协议两者握手时协议不一致导致长时间等待后超时。换成Hadoop 3.2.x之后这个报错就再没出现过。这个教训告诉我安装之前第一个要查的不是配置而是版本兼容矩阵。HBase官方文档里有一张详细的兼容性表先对照一下能省大量时间。5.2 坑二hbase.rootdir配置了file:///前缀有一次装伪分布式Master进程一直正常但RegionServer起来之后几秒钟就自动退出。查日志发现RegionServer尝试连接的东西全部指向本地文件系统。问题出在hbase.rootdir的值写成了file:///hbase这会让HBase认为不需要HDFS把所有数据写到本地路径。对这个值最稳的写法是hdfs://namenode-host:8020/hbase5.3 坑三主机名解析不一致导致Zookeeper节点注册错乱还有一次比较隐蔽的问题HBase Master UI能打开但页面上显示的RegionServer地址是localhost。所有RegionServer进程都活着但Master始终认为它们离线。查了半天发现/etc/hosts里没有写实际主机名到IP的映射系统解析回环地址。把所有节点的/etc/hosts补上主机名映射并让regionservers文件里的名字和hbase.zookeeper.quorum里的名字完全一致后才恢复正常。注意HBase集群内部大量使用主机名进行节点间通信。写完配置后可以用ping逐一验证每个节点能否通过主机名访问到其他节点。5.4 坑四Zookeeper没先启动Master反复刷ConnectionLossException这个问题很基础但特别常见。我第一次搭集群的时候图省事直接跑start-hbase.sh结果Master日志里刷满了连接Zookeeper失败的异常程序进入无限重试循环。虽然HBase最终会连上但这个过程会拉长启动时间还会让部分RegionServer反复注册、反复失败。规范做法还是先确保Zookeeper集群可用再启动HBase。5.5 坑五内存给太少RegionServer进程被系统杀掉一些小规格的云主机上默认的HBASE_HEAPSIZE是1GRegionServer启动后会很快吃满机器内存然后被操作系统OOM Killer杀掉。你在dmesg里能看到Out of memory: Kill process的记录。当时我把机器内存加到8G并且把HBASE_HEAPSIZE显式设为6G才稳定下来。如果是测试环境至少给4G堆否则启动后也会频繁Full GC表现就是响应极慢。6. 启动成功只算开始三个值得优先调整的参数安装能跑通跟生产能用中间还差不少调优工作。我不会在这里堆一堆参数只讲我实际改动后收益最明显的三个方向。6.1 RegionServer端处理线程数hbase.regionserver.handler.count控制RegionServer同时处理外部请求的线程数默认是30。如果你客户端并发量高这个值设得太小请求会排队表现为吞吐上不去、P99延迟升高。我的习惯是先从50开始逐步压测观察如果CPU还有余量可以往上再加。但它不是越大越好——线程太多上下文切换成本反而拖垮性能。6.2 MemStore触发刷写的阈值hbase.hregion.memstore.flush.size默认是128MB。一旦单个Region的MemStore超过这个值就会触发flush写HFile。对于写多读少的场景可以把阈值适当调大比如256MB减少小文件产生频率但同时要关注RegionServer总MemStore占比hbase.regionserver.global.memstore.size默认0.4否则大量的Region同时到达阈值会触发全局阻塞反而拖慢写入。6.3 Region分裂和预分区策略默认情况下Region写大到一定阈值会触发自动split。如果一开始建表时没有做预分区所有写压力都集中在一个Region上随着分裂不断进行数据分布会出现热点Region问题。针对已知rowkey分布的业务我通常在建表时就手动预分区create test_table, {NAME cf1}, {SPLITS [10, 20, 30, 40]}当然这属于建表设计层面的优化安装阶段可以不用做。但如果你已经在规划生产集群建议安装验证完以后尽早把预分区方案定下来避免后面上线时大表数据倾斜、整表split风暴。7. RegionServer内存与GC跑一段时间后再看HBase单机装完能跑不代表它能连续稳定运行一星期。我把内存和GC相关的经验单独放一块说因为这是HBase运维里最隐蔽的性能杀手。7.1 RegionServer堆内布局和堆外Cache的取舍RegionServer的JVM堆主要分成三块MemStore、BlockCache和其余部分。默认情况下MemStore和BlockCache的占比相对均衡。如果你的场景是写多读少应该让MemStore占更大比例如果是读多写少BlockCache就要给足。hbase.regionserver.global.memstore.size和hfile.block.cache.size这两个参数的调优本质是在做权衡。我个人的经验是先用默认配跑一周观察指标再决定改什么。不要一上来就大改。观察的重点是RegionServer的JVM GC频率、老年代增长曲线、以及HBase Web UI里的Heap Utilization。全部分类跑一遍压测用数据说话。7.2 Full GC导致RegionServer被误判下线RegionServer在运行过程中如果抖动一次长时间的Full GC会暂停处理所有请求。停止时间超过Zookeeper的session超时默认90秒Zookeeper就认为这个RegionServer挂了Master会把它上面的Region重新分配到别的节点。你会发现某台RegionServer日志似乎没报错但Master UI上它的Region数量一直在变。避免这个问题除了把堆设大还要看GC策略。JDK8下HBase官方和很多社区实践都推荐G1GC。G1把堆分成多个Region以可预测的方式处理大堆停顿控制比CMS更稳定。我上面提到在hbase-env.sh里配置-XX:UseG1GC就是基于这个原因。7.3 善用RegionServer UI里的Memory指标每台RegionServer的Web UI端口是16030打开后能看到每个Region的内存占用、StoreFile数量、读请求数和写请求数。安装完HBase建议大家把几个核心指标的意义过一遍MemStore Size写入缓冲大小如果长期居高不下说明flush赶不上写入速度。StoreFile Count历史flush和compaction留下来的文件数量如果太多几百个查询性能会明显恶化。BlockCache Hit Ratio读缓存命中率太低说明Cache配置不合理或者访问模式偏冷。装完后不要只看进程在不在把这些指标看熟了才算是真正的部署完成。8. 配套脚本和日常维护的几个操作习惯安装完成以后我还会顺手做几件小事让后续维护轻松一点。8.1 写一个集群启停脚本正式集群一般不止三台机器手动逐台启动不现实。我习惯在Master节点写一个简单的脚本把HDFS、Zookeeper、HBase的启停串起来#!/bin/bash # hbase_cluster.sh start|stop ACTION$1 case $ACTION in start) start-dfs.sh for zk in node1 node2 node3; do ssh $zk /usr/local/zookeeper/bin/zkServer.sh start done start-hbase.sh ;; stop) stop-hbase.sh for zk in node1 node2 node3; do ssh $zk /usr/local/zookeeper/bin/zkServer.sh stop done stop-dfs.sh ;; esac注意我停止顺序和启动顺序相反先停HBase再停Zookeeper最后停HDFS。这样能保证没有客户端继续写入时再停底层服务避免留下未刷写的WAL或损坏的meta。8.2 日常检查的三个命令hbase hbck检查meta表和Region分配一致性。注意HBase 2.x里推荐用hbase hbck -details查看具体问题千万不要在集群运行繁忙时做修复操作。hdfs dfsadmin -report确认HDFS空间和DataNode状态HBase的数据文件增长很快磁盘满会导致所有RegionServer进入只读保护模式。echo status detailed | hbase shell快速看RegionServer上Region数量、请求负载判断有没有热点。这些工具不占多少资源但能让你在故障发生前就发现苗头。在我日常维护集群的经验里绝大部分严重故障都是有前兆的只是没及时看指标而已。9. 最后补一句关于后续升级和生态工具的考虑HBase 2.3.7装好基础功能跑通了我觉得还应该留个心眼后面要不要接生态组件会不会迁到更新版本。这个思考会影响你现在做的目录规划、配置命名和服务账号设计。如果计划接Phoenix或各厂家的SQL层注意它们对HBase版本的适配情况以及hbase-site.xml里配置的兼容性开关如果计划从2.3.x后续升级到2.4.x甚至3.x那现在就要做好配置项的备份管理和升级演练预案。版本升级这种事最忌讳的是没有一套可回滚的方案就硬上。从我个人这几年的使用体验看HBase 2.3.7适合作为个人学习、团队测试、中小规模生产环境的第一选择它不算最前沿但胜在稳定、资料多、周边生态完善。安装过程里那些问题其实多是环境匹配和细节疏忽导致的把基础打好后面调优和排障都会顺很多。
阅读完成 · 觉得有帮助?
咨询建站