
HBase 这个组件我在好几个项目里都用过从最早的单机测试环境到后来的几十节点集群都趟过一遍。说实话它入门不难但真正用好、用稳坑比想象中多得多。很多教程只告诉你敲几条命令把服务起起来却没人告诉你为什么 RegionServer 会莫名其妙挂掉、WAL 预写日志报异常时该从哪里下手、端口到底要开哪些、表设计怎么避开热点。这篇内容就是把我这些年从安装配置到表设计、从 WAL 机制到常见故障排查的完整经验梳理出来适合刚接触 HBase 想快速上手的人也适合已经用过但被各种异常折腾过的同学。核心关键词围绕 HBase 安装与配置、WAL 预写日志、端口清单、表设计与数据操作展开尽量做到看完就能动手、动手就能跑通。1. 先把 HBase 的定位想清楚再动手装1.1 它到底解决的是哪类问题很多人一上来就问 HBase 和 MySQL 有什么区别其实这个问题问偏了。HBase 不是用来替代关系型数据库的它解决的是海量稀疏数据的随机实时读写问题。什么叫海量单表几十亿行、上百亿行这种量级。什么叫稀疏就是每一行可能有几百个列族里的列但实际每行只填了少数几个。什么叫随机实时就是你要按 rowkey 精确查某一行延迟要求在毫秒到几十毫秒级别而不是跑一个几分钟的离线批处理。它的底层依赖 HDFS 做存储依赖 ZooKeeper 做协调自身提供 RegionServer 来管理数据分片Region。这个架构决定了它的几个天然特性强一致性的单行读写、按 rowkey 排序存储、自动水平切分。理解这三点后面所有的配置和设计决策都能找到依据。我见过太多人拿 HBase 当 MySQL 用建一堆二级索引、做复杂的多表 join 查询最后性能惨不忍睹。所以安装之前先问自己我的数据是不是按某个 key 能唯一定位是不是写入量远大于复杂查询如果答案是肯定的HBase 才合适。1.2 部署模式的选择逻辑HBase 有三种部署模式单机模式Standalone、伪分布式Pseudo-Distributed、完全分布式Fully Distributed。选哪种不是看心情而是看你的目的。单机模式把所有进程跑在一个 JVM 里用的是本地文件系统而不是 HDFS。这种模式只适合你花十分钟验证一下 API 能不能跑通绝对不能用来做任何性能测试因为它的行为和真实集群差异巨大。伪分布式是单台机器上跑所有进程但用的是 HDFS。这个模式适合开发人员在自己电脑上搭一套完整的开发环境能体验到真实的分布式行为比如 Region 切分、WAL 写入 HDFS 等。完全分布式才是生产环境该用的。这里有个经验ZooKeeper 集群的节点数用奇数3 个或 5 个因为 ZK 的选举机制需要过半存活。HMaster 建议部署两个做高可用但同一时间只有一个 Active另一个是 Backup。RegionServer 的数量根据你的数据量和内存来定一般单节点管理 50 到 200 个 Region 比较健康。1.3 版本与依赖的匹配关系HBase 的版本和 Hadoop、JDK 之间有严格的兼容矩阵这个不能拍脑袋。我踩过最典型的一个坑是HBase 2.x 在 JDK 8 上跑得好好的换到 JDK 11 之后各种反射相关的报错因为 HBase 早期版本大量用了 JDK 内部 API。选版本的时候记住几条HBase 2.4.x 和 2.5.x 是目前比较稳的长期维护版本Hadoop 用 3.3.x 系列和 HBase 2.4 搭配比较顺JDK 老老实实用 8除非你确认用的 HBase 版本明确支持 11。另外 ZooKeeper 用 3.5 以上因为 HBase 2.x 依赖 ZK 的新特性做协调。提示不要盲目追最新版本。生产环境选版本的第一原则是社区活跃度和 bug 修复记录而不是版本号大小。去翻一下对应版本的 release notes看看有没有和你场景相关的严重 bug 被修复。2. 安装配置里那些文档不会强调的细节2.1 环境准备阶段容易忽略的三件事第一件是主机名和 hosts 解析。HBase 集群内部大量通过主机名通信如果你只在 master 节点配了 hosts其他节点解析不了就会出现 RegionServer 注册不上、HMaster 一直 initializing 的情况。正确做法是在所有节点的 /etc/hosts 里把集群内所有机器的主机名和 IP 对应关系写全。第二件是时间同步。HBase 依赖时间戳做版本控制如果节点之间时间差太大会出现数据版本混乱、WAL 回放异常。上线前务必确认所有节点都配了 NTP 同步时间偏差控制在秒级以内。第三件是文件句柄和进程数限制。HBase 是重 IO 的组件默认的 ulimit 往往不够。需要在 /etc/security/limits.conf 里把 nofile 调到 65536 甚至更高nproc 也要放开。这个不配集群跑一段时间就会报 Too many open files然后 RegionServer 直接挂掉。2.2 hbase-site.xml 里必须调的几个参数配置文件里参数几百个但真正影响稳定性的就那么几个。我列一个实战中最常调的清单参数建议值作用说明hbase.rootdirhdfs://namenode:8020/hbase数据在 HDFS 上的根目录hbase.cluster.distributedtrue完全分布式必须为 truehbase.zookeeper.quorumzk1,zk2,zk3ZK 集群地址列表hbase.zookeeper.property.dataDir/data/zookeeperZK 数据目录别用默认的 /tmphbase.regionserver.handler.count100~200RPC 处理线程数按并发调hbase.hregion.max.filesize10G单 Region 最大大小触发切分hbase.hregion.memstore.flush.size128MMemStore 刷写阈值zookeeper.session.timeout90000RS 与 ZK 会话超时网络差可调大这里重点说两个。hbase.regionserver.handler.count这个参数很多人用默认的 30结果高并发写入时请求排队严重。它的经验值是如果你的业务是读多写少可以设小一点如果是写密集设到 100 以上。但也不是越大越好线程太多会导致 GC 压力剧增。zookeeper.session.timeout这个参数决定了 RegionServer 多久没心跳就被判定为宕机。默认 90 秒如果集群网络抖动频繁可以适当调大避免误判导致不必要的 Region 迁移。但调太大也有代价真宕机时故障转移会变慢。2.3 端口清单与防火墙策略HBase 涉及的端口不少部署时如果防火墙没开对服务起得来但连不上。整理一份完整的端口清单HMaster16000RPC、16010Web UIRegionServer16020RPC、16030Web UIZooKeeper2181客户端连接、2888集群内通信、3888选举HDFS8020NameNode RPC、9870NameNode UI、9866DataNode 数据传输HBase REST/Thrift如果用8080、9090、9095内网集群之间这些端口要互通客户端只需要能访问 ZK 的 2181 和 HBase 的 RPC 端口。我遇到过最隐蔽的一个问题是ZK 的 2888 和 3888 没开导致 ZK 集群选不出 leader然后 HMaster 一直卡在 initializing 状态日志里只报连接超时排查了半天才发现是防火墙。2.4 启动顺序与验证方法启动顺序不能乱先起 ZooKeeper再起 HDFS最后起 HBase。停的时候反过来。这个顺序的原因是 HBase 启动时要往 HDFS 写元数据、往 ZK 注册节点依赖方没起来它就会失败。启动命令很简单在 HBase 的 bin 目录下执行start-hbase.sh。但验证不能只看进程在不在要分三步用jps确认 HMaster 和 HRegionServer 进程存在访问 HMaster 的 Web UI16010 端口看 RegionServer 列表是否全部在线进 hbase shell 执行status命令看集群状态和 Region 分布如果 HMaster 一直显示 initializing先查 ZK 连接再查 HDFS 权限最后查 hosts 解析。这个排查顺序是我总结出来的能覆盖 90% 的启动问题。3. WAL 预写日志HBase 不丢数据的底气所在3.1 WAL 到底在做什么WALWrite-Ahead Log预写日志是 HBase 保证数据不丢的核心机制。它的逻辑很朴素任何写入操作先顺序写一份日志到 HDFS写成功了再写内存MemStore。这样即使 RegionServer 突然宕机内存里还没落盘的数据也能通过回放 WAL 恢复回来。为什么先写日志再写内存因为 HDFS 上的顺序写很快而且有副本机制保证可靠。内存写虽然更快但断电就没了。这个设计思路和关系型数据库的 redo log 是一脉相承的本质都是用先持久化日志来换取内存操作的可靠性。WAL 文件默认存放在 HDFS 的/hbase/WALs/目录下每个 RegionServer 一个子目录里面按时间滚动生成多个 WAL 文件。你可以通过hbase wal相关命令查看当前 WAL 的状态。3.2 WAL 路径与滚动机制WAL 的路径结构是hbase.rootdir/WALs/hostname,port,startcode/。这个 startcode 是 RegionServer 启动时的时间戳每次重启都会生成新的目录。老目录里的 WAL 在数据恢复完成后会被归档到/hbase/oldWALs/这个目录需要定期清理否则会占满 HDFS 空间。WAL 的滚动roll由几个条件触发单个 WAL 文件大小超过hbase.regionserver.hlog.blocksize默认是 HDFS block 大小、或者达到hbase.regionserver.maxlogs数量上限、或者手动触发。滚动之后旧的 WAL 会被标记为可归档。这里有个实战经验如果发现 oldWALs 目录持续增长不清理通常是 WAL 回放出了问题。正常情况下 HMaster 会在启动时检查并清理已回放的 WAL如果清理逻辑卡住要么是 ZK 状态异常要么是某个 RegionServer 的 WAL 无法回放。这时候要去 HMaster 日志里搜 oldWALs 相关的记录。3.3 WAL 异常排查的完整链路WAL 报异常是最让人头疼的问题之一因为它的表现往往是 RegionServer 直接挂掉或者 HMaster 卡住。我梳理一条完整的排查链路第一步看 RegionServer 日志。搜 WAL 或 hlog 关键字重点看是写入失败还是回放失败。写入失败通常是 HDFS 问题回放失败通常是 WAL 文件损坏。第二步检查 HDFS 状态。用hdfs dfsadmin -report看 DataNode 是否全部存活有没有处于 safe mode。HDFS 进 safe mode 时 WAL 写不进去RegionServer 会报错退出。第三步检查磁盘空间。HDFS 空间满了WAL 写入直接失败。这个最容易被忽略因为很多人只盯着 HBase 自己的目录看。第四步检查 WAL 文件完整性。如果怀疑某个 WAL 损坏可以用hbase org.apache.hadoop.hbase.wal.WALPrettyPrinter工具解析 WAL 文件内容看是否能正常读出记录。第五步处理无法回放的 WAL。如果确认某个 WAL 损坏且无法回放可以把它移到 oldWALs 目录让 HMaster 跳过。但这一步要谨慎因为意味着这部分数据可能丢失。操作前务必备份。注意WAL 异常很多时候是 HDFS 问题的表象不要只盯着 HBase 调参数。我遇到过好几次都是 DataNode 磁盘故障导致 WAL 写入失败最后修的是 HDFS 而不是 HBase。3.4 关闭 WAL 的代价与适用场景HBase 允许通过setWriteToWAL(false)关闭单次写入的 WAL用来提升写入性能。但这个操作是有代价的关闭 WAL 的写入在 RegionServer 宕机时会丢失。那什么时候可以用我总结了两类场景一是可以容忍少量数据丢失的日志类、埋点类数据二是批量导入历史数据时因为数据源本身还在丢了可以重导。除此之外生产环境的核心业务数据绝对不要关 WAL。即使要用也建议用批量写入的方式Put 列表统一关闭而不是每条都调一次因为频繁切换 WAL 状态本身也有开销。4. 表设计决定 HBase 性能上限的关键4.1 rowkey 设计是重中之重HBase 的表设计80% 的功夫在 rowkey 上。因为 HBase 是按 rowkey 字典序排序存储的rowkey 设计得好读写都顺畅设计得差热点问题能让你集群直接瘫痪。热点问题的本质是如果 rowkey 是连续递增的比如时间戳、自增 ID那么所有写入都会集中在最后一个 Region 上其他 Region 闲着单个 RegionServer 被打爆。这个现象在监控上表现为某个 RS 的请求量远高于其他节点。解决办法有三种我按推荐程度排序加盐Salting在 rowkey 前面加一个随机前缀比如把 rowkey 分成 0-9 十个桶写入时随机选一个前缀。这样数据就分散到多个 Region 了。缺点是读的时候要查多个前缀适合写多读少且能接受范围查询的场景。哈希Hashing对原始 rowkey 做 MD5 或其它哈希取前几位作为前缀。比加盐更均匀但完全丧失了按原始 key 排序的能力只适合精确查询。反转Reversing把 rowkey 的字节序反转比如手机号 138xxxx 反转成 xxxx831。这样原本连续的值就分散了同时还能保留一定的前缀查询能力。适合手机号、时间戳这类场景。4.2 列族设计的原则列族Column Family的数量要严格控制一般不超过 3 个。因为 HBase 的列族是物理存储单元每个列族对应一组 StoreFile列族太多会导致MemStore 数量增多内存压力大刷写和合并Compaction频繁IO 压力大文件句柄占用多列族的划分依据是访问模式而不是业务分类。比如经常一起查询的列放一个列族很少访问的大字段放另一个列族。不要把用户信息和订单信息这种业务上相关但访问模式不同的列硬塞进一个列族。列族的几个关键属性也要调max versions保留多少个版本默认 1需要历史版本时调大TTL数据过期时间日志类数据可以设短一点自动清理compression压缩算法推荐 SNAPPY压缩比和 CPU 开销平衡得好bloomfilter布隆过滤器ROW 级别适合按 rowkey 查ROWCOL 适合按列查4.3 预分区与 Region 切分策略新建表时如果不预分区所有数据一开始都写到一个 Region 里等它涨到hbase.hregion.max.filesize默认 10G才切分。这个过程中写入性能很差因为只有一个 Region 在扛。预分区就是建表时提前把 key 范围划分好创建多个 Region。比如你知道 rowkey 是 0-9 开头的就建 10 个分区。这样写入一开始就分散了。预分区的方法有两种一是在建表命令里直接指定 SPLITS二是用RegionSplitter工具。我一般用第一种简单直接create user_table, {NAME info, VERSIONS 1}, SPLITS [1, 2, 3, 4, 5, 6, 7, 8, 9]Region 切分策略在 HBase 2.x 里默认是SteppingSplitPolicy它会根据 Region 数量动态调整切分阈值。如果业务写入量稳定也可以用ConstantSizeRegionSplitPolicy固定阈值。选哪个取决于你的数据增长模式没有绝对的好坏。4.4 一个完整的表设计实例假设要设计一个用户行为日志表需求是按用户 ID 和时间范围查询写入量大数据保留 30 天。rowkey 设计userId反转 时间戳。反转 userId 是为了打散热点时间戳放在后面保证同一用户的数据按时间排序。列族设计一个列族info包含行为类型、页面 ID、停留时长等字段。因为这些都是同时查询的放一个列族合理。预分区根据 userId 反转后的前缀分布预分 16 个 Region。TTL设成 30 天自动清理过期数据。压缩SNAPPY。这个设计能同时满足写入分散、查询高效、自动清理三个需求。实际用下来单集群写入能稳定在每秒几万条。5. 数据操作与生态工具实战5.1 Shell 常用操作速查HBase Shell 是最直接的交互方式几个高频命令必须熟练# 建表 create test_table, cf1, cf2 # 插入数据 put test_table, row1, cf1:name, zhangsan # 单行查询 get test_table, row1 # 范围查询 scan test_table, {STARTROW row1, STOPROW row5, LIMIT 10} # 统计行数 count test_table # 删除数据 delete test_table, row1, cf1:name # 删除表要先 disable disable test_table drop test_tablescan 命令要慎用不加 LIMIT 的全表扫描在生产环境可能拖垮集群。如果确实需要全表扫描用scan table, {FILTER ...}加过滤条件或者用 MapReduce 任务离线跑。5.2 用 Sqoop 做关系型数据库到 HBase 的导入Sqoop 是 HBase 和关系型数据库之间的桥梁最常见的场景是把 MySQL 的数据导入 HBase。基本命令sqoop import \ --connect jdbc:mysql://mysql_host:3306/db_name \ --username root \ --password xxx \ --table source_table \ --hbase-table target_table \ --column-family cf1 \ --hbase-row-key id \ --hbase-create-table这里有几个坑要注意。rowkey 的选择--hbase-row-key指定的列会成为 rowkey如果这列是自增 ID导入后会有热点问题建议在 Sqoop 里做转换或者导入后再处理。列族必须提前存在虽然--hbase-create-table能自动建表但自动建的列族属性都是默认值生产环境建议手动建好表再导入。并发度Sqoop 默认用 4 个 map 任务可以通过-m调整但要注意 MySQL 端的压力。5.3 Java API 的核心用法生产环境用 Java API 操作 HBase 是最常见的。核心对象是 Connection、Table、Put、Get、Scan。这里给一个写入的骨架Configuration conf HBaseConfiguration.create(); conf.set(hbase.zookeeper.quorum, zk1,zk2,zk3); Connection conn ConnectionFactory.createConnection(conf); Table table conn.getTable(TableName.valueOf(test_table)); Put put new Put(Bytes.toBytes(row1)); put.addColumn(Bytes.toBytes(cf1), Bytes.toBytes(name), Bytes.toBytes(zhangsan)); table.put(put); table.close(); conn.close();Connection 是重量级对象要复用不要每次操作都创建。正确做法是在应用启动时创建一个全局 Connection所有线程共享。Table 对象是轻量的可以每次操作创建但也可以缓存。批量写入时用BufferedMutator比逐条 put 性能好很多它会自动攒批发送。记得在应用关闭时调flush()和close()。5.4 常见面试考点梳理既然聊到实战顺便把面试里高频的几个问题点一下这些也是理解 HBase 的关键为什么 HBase 写入比读取快因为写入是先写 WAL 再写 MemStore都是顺序操作读取要查 MemStore、BlockCache、HFile 多层还可能触发磁盘 IO。MemStore 刷写时机单个 MemStore 达到hbase.hregion.memstore.flush.size默认 128M、或者 Region 所有 MemStore 总和达到hbase.regionserver.global.memstore.size默认堆的 40%、或者 WAL 数量达到上限。Compaction 的作用把多个小 HFile 合并成大 HFile减少读取时的文件查找开销同时清理过期和删除的数据。分 Minor 和 Major 两种Major 会合并所有文件开销大一般手动或定期触发。Region 切分后原 Region 怎么处理切分后原 Region 下线两个子 Region 上线元数据更新到 hbase:meta 表由 HMaster 负责分配。6. 集群运维中的典型故障与处理6.1 HMaster 一直 initializing 的排查这个现象太常见了表现是 HMaster 进程在但 Web UI 打不开或者显示初始化中。根因通常有三个方向ZK 连接问题HMaster 启动时要连 ZK 注册自己如果 ZK 连不上或者之前的节点信息没清理就会卡住。处理办法是检查 ZK 状态必要时清理 ZK 里 /hbase 节点下的残留数据这个操作要谨慎确认集群确实没有在运行。HDFS 权限问题HMaster 要往 HDFS 写元数据如果 hbase.rootdir 目录权限不对写入失败就会卡住。用hdfs dfs -ls检查目录权限确保 HBase 启动用户有读写权限。端口冲突16000 或 16010 被占用HMaster 起不来。用netstat检查端口占用情况。排查顺序建议是先看 HMaster 日志的最后几行通常错误信息就在那里然后查 ZK最后查 HDFS。6.2 RegionServer 频繁挂掉的根因分析RegionServer 挂掉的原因比 HMaster 复杂我按出现频率排个序内存溢出OOM最常见。MemStore 和 BlockCache 加起来占了大部分堆内存如果写入量突增MemStore 涨太快触发 GC严重时 OOM。解决办法是调大堆内存、调小 memstore flush size、或者增加 RegionServer 数量分摊压力。GC 时间过长HBase 对 GC 停顿很敏感如果 Full GC 超过zookeeper.session.timeoutZK 会认为 RS 挂了。要用 G1 或者 CMS 收集器并且监控 GC 日志。HDFS 写入失败DataNode 故障或者磁盘满导致 WAL 写不进去RS 主动退出。这个要去 HDFS 层面解决。Region 过多单个 RS 管理的 Region 太多超过 200 个元数据开销和内存占用都会飙升。需要通过 balance 或者扩容来分摊。6.3 读写性能突然下降的定位思路性能问题最考验排查能力因为原因可能在任何一层。我的定位思路是从外到内先看客户端是不是请求量突增或者有慢查询。用 HBase 的 metrics 看 RPC 队列长度和延迟。再看 RegionServer看是否有 Region 热点某个 RS 请求量远高于其他、是否有频繁的 Compaction、GC 是否正常。然后看 HDFSDataNode 是否有慢节点、磁盘 IO 是否打满。最后看底层网络是否有丢包、磁盘是否有坏道。这个链路走一遍基本能定位到问题层。我遇到过一次性能下降最后发现是某台 DataNode 的磁盘快坏了读写特别慢拖累了整个 HDFS。6.4 数据一致性与恢复的注意事项HBase 保证的是单行事务的强一致性跨行跨表没有事务。这个要清楚设计业务时不能假设有跨行原子性。数据恢复主要靠 WAL 回放。RegionServer 宕机后HMaster 会把它负责的 Region 重新分配给其他 RS新 RS 会读取该 RS 的 WAL 目录回放未落盘的数据。这个过程是自动的但前提是 WAL 文件完整。如果 WAL 损坏无法回放数据就会丢失。所以生产环境要定期备份可以用 HBase 的 snapshot 功能也可以用 Export/Import 工具做全量备份。snapshot 是轻量的只记录元数据不复制数据文件恢复快。提示snapshot 虽然轻量但它依赖底层 HFile 不被删除。如果做了 snapshot 之后又跑了 Major Compaction旧 HFile 被清理snapshot 就可能失效。所以 snapshot 要配合定期验证确保能真正恢复。7. 我踩过的几个印象深刻的坑7.1 时间不同步导致的数据版本混乱有一次集群扩容新加的机器忘了配 NTP时间比老机器快了十几分钟。结果写入的数据时间戳比已有的还早读取时按时间戳排序就乱了出现了新写入的数据查不到的诡异现象。排查了很久才想到查时间同步。这个教训是集群所有节点的时间同步是硬性要求扩容时第一件事就是配 NTP。7.2 oldWALs 目录撑爆 HDFS前面提过 oldWALs 需要清理我自己就踩过这个坑。一个测试集群跑了几个月没管oldWALs 目录涨到了几个 T把 HDFS 空间占满了然后所有写入都失败。清理的时候要注意不能直接hdfs dfs -rm -r因为可能有正在回放的 WAL。正确做法是通过 HMaster 的清理机制或者确认没有回放任务后再删。7.3 rowkey 设计不当引发的热点早期做一个订单查询系统rowkey 直接用订单 ID自增结果所有写入都打到一个 Region 上监控显示单个 RS 的 CPU 跑满其他 RS 闲着。后来改成订单 ID 哈希前缀 订单 ID写入立刻分散了。这个坑让我彻底记住了 rowkey 设计的重要性也让我养成了建表前先想清楚访问模式的习惯。7.4 客户端 Connection 泄漏有个应用每次请求都创建 Connection用完不关跑了一段时间后 RegionServer 报连接数过多拒绝新连接。原因是 Connection 是重量级对象底层维护着到 ZK 和 RS 的连接池频繁创建销毁会耗尽资源。改成全局单例后问题消失。这个坑提醒我HBase 客户端的资源管理要像管理数据库连接池一样认真。8. 给不同阶段使用者的实用建议8.1 刚入门的人怎么快速上手如果你刚开始学 HBase我的建议是先在一台机器上用伪分布式模式搭起来跑通 shell 的基本命令理解 rowkey、列族、Region 这些概念。然后写一个简单的 Java 程序做增删改查体会一下 API 的用法。这个阶段不要纠结性能调优先把能用这一步走通。学习资料方面官方文档是最权威的虽然有些地方写得简略但概念定义准确。遇到具体问题再去搜社区帖子注意看发帖时间HBase 版本迭代快老版本的解决方案可能不适用。8.2 已经在用的人怎么避免常见问题如果你已经在生产环境用 HBase重点抓三件事监控、容量规划、定期演练。监控要覆盖集群级别Region 分布、请求量、延迟、节点级别CPU、内存、GC、磁盘、表级别读写量、Region 大小。用 HBase 自带的 metrics 配合 Prometheus 和 Grafana 就能搭一套。容量规划要提前做根据数据增长速度和写入量预估 RegionServer 数量别等到集群扛不住了才扩容。定期演练指的是模拟 RegionServer 宕机、HMaster 切换这些场景验证故障转移是否正常、数据是否完整。这个平时不做真出事时就会手忙脚乱。8.3 面试准备的重点方向面试 HBase 相关岗位除了前面提到的原理问题还要准备几个实战场景题怎么设计一个高并发的写入方案、怎么排查 RegionServer 挂掉、怎么优化一个慢查询。回答这类问题要体现排查思路而不是直接给答案面试官更看重你的分析能力。另外HBase 和 Hive、Spark、Flink 的集成也是常考点比如用 Hive 做 HBase 的 SQL 查询、用 Spark 读写 HBase 做分析。这些生态工具的用法要了解因为实际工作中很少单独用 HBase。8.4 后续可以深入的方向HBase 玩到一定程度可以往几个方向深入一是底层原理比如 HFile 的存储格式、LSM 树的合并机制、布隆过滤器的实现二是运维自动化比如用 Ansible 做集群部署、用 Operator 在容器平台管理 HBase三是性能调优针对特定业务场景做参数定制。我个人觉得把 HBase 和上层计算引擎结合起来用价值更大。比如用 HBase 做实时查询的存储层用 Flink 做实时写入用 Spark 做离线分析这套组合在很多场景下都能打。