深入 HBase 09 - Client 路由与重试
前置问题与边界 本篇回答一个核心问题:Client 如何缓存 hbase:meta 路由,Region 移动后怎样重新定位。 HBase Client 不是把请求发给 Master 再由 Master 转发。普通 Get、Put 和 Scan 会通过客户端定位找到 RegionServer,然后直接访问对应 Region。hbase:meta 是路由目录,ZooKeeper 或 registry 是引导与协调入口,HDFS 是底层文件系统;三者不能混成一个“元数据中心”。 HBase 2.6.6 中,Connection 是重对象,承载 RPC、线程、缓存和定位相关状态;Table、Admin、RegionLocator 是从 Connection 派生出来的轻量使用入口,使用后应该关闭。频繁创建 Connection 会增加资源和定位成本。 路由路径图 sequenceDiagram participant App as Application participant Conn as HBase Connection participant Meta a...
深入 HBase 08 - Region 生命周期:split、merge 与 assignment
前置问题与边界 本篇回答一个核心问题:表如何扩展,Region 如何迁移,状态由谁推进。 Region 是 HBase 表按 row-key range 切分后的服务单位。它决定数据由哪个 RegionServer 接收,也决定客户端定位和负载均衡的粒度。split、merge 和 assignment 都是在改变 Region 与 RegionServer 的映射,不能把这些动作写成简单的 HDFS 文件移动。 HBase 2.6.6 使用 Procedure v2 和 AssignmentManager 推进 Region assignment。Region 持久状态与位置信息写入 hbase:meta;hbase:meta 自身的位置信息和可用性还涉及 ZooKeeper 或 registry 相关路径。ZooKeeper 不保存所有 HBase 元数据。 生命周期图 stateDiagram-v2 [*] --> CLOSED CLOSED --> OPENING: assign OPENING --> OPEN: RegionS...
深入 HBase 07 - Compaction、TTL、版本与 Delete
前置问题与边界 本篇回答一个核心问题:不可变 HFile 如何合并,旧值和 tombstone 何时真正消失。 HBase 的写入路径把 mutation 写入 WAL 和 MemStore,flush 后形成新的 HFile。HFile 不原地修改,因此旧版本、Delete 标记和过期数据会散落在多个 StoreFile 中。Compaction 通过重写新文件来减少 StoreFile 数量,并在可见性规则允许时丢弃不再需要的 Cell。 本篇不讨论跨行事务,也不把 Delete 写成“立即删除磁盘数据”。HBase 的 Delete 是写入一个或多个 tombstone;旧数据是否在物理文件里消失,取决于 compaction 类型、版本策略、TTL、快照引用、最小保留时间和扫描可见性。 对象路径图 flowchart TD P[Put/Delete] --> WAL[WAL] P --> MS[MemStore] MS --> FL[Flush] FL --> H1[HFile A] FL --> H2...
深入 HBase 06 - HFile 内部结构
前置问题与边界 本篇回答一个核心问题:data block、index、file info、Bloom metadata 如何支持 HBase 在不可变文件里做有序查找。 HFile 是 HBase flush 和 compaction 之后写到 HDFS 的 StoreFile 格式。它不是关系数据库页文件,也不是面向分析扫描的列存文件。它保存按 Cell key 排序的记录,并携带索引、元信息、Bloom 相关数据和 trailer,供 RegionServer 在读路径中缩小访问范围。 基线仍是 HBase 2.6.6。HBase 2.6.6 的代码支持 HFile format version 3,不能把当前实现误写成“只支持 HFile v2”。HFile v2 的文档解释了多级索引、Bloom 和 trailer 等关键结构;写作时要把格式演进和当前版本能力分开。 文件结构图 flowchart TD H[HFile StoreFile] --> DB[Data Blocks: sorted Cells] H --> LB[Leaf Ind...
深入 HBase 05 - 读取路径:BlockCache、Bloom Filter 与 HFile block
前置问题与边界 本篇回答一个核心问题:Get 如何减少磁盘读取,并把 MemStore、BlockCache 与多个 HFile 的结果合成同一行的可见 Cell。 HBase 读路径不是 HDFS 随机读能力的直接暴露。客户端先定位 row key 所属 Region,再把请求发到对应 RegionServer;RegionServer 在 Store 内部合并内存数据和不可变 StoreFile。HDFS 提供文件读取和副本,HBase 提供 row-key 定位、HFile 索引、Bloom Filter、BlockCache 和版本可见性。 本篇基线是 HBase 2.6.6、Hadoop 3.4.3、JDK 17。HBase 3.0.0 的集中变化只放在第 19 篇。 读取路径图 flowchart TD C[Client Get row key] --> M[Region location from cache or hbase:meta] M --> RS[RegionServer] RS --> R[Region] ...
深入 HBase 04 - 写入路径:WAL、MVCC、MemStore 与 flush
前置问题与边界 一次 Put 从客户端发出后,不会直接变成 HFile。HBase 写路径先把 mutation 交给目标 RegionServer,在 Region 内完成行锁、WAL、MVCC、MemStore 更新和返回协议;随后由 flush 把 MemStore snapshot 写成 HDFS 上的 HFile。HFile 之后还会被 compaction 合并。 本篇回答一个核心问题:Put 从客户端到 HFile 经历哪些状态,何时对读取可见。BlockCache 和 HFile 读路径放到第 05、06 篇;compaction 清理旧版本和 Delete 放到第 07 篇;RegionServer 崩溃恢复放到第 11 篇。 HBase 2.6 的实现细节需要谨慎表述。WAL 是否同步、何时返回,受 mutation durability 和表配置影响。flush policy 可以选择哪些 Store 需要 flush,不能笼统写成任何 flush 都必然把 Region 内所有 column family 同时刷盘。 写入路径图 sequenceDiagr...
深入 HBase 03 - Schema 与 row key 设计
前置问题与边界 HBase schema 设计首先是 row key 设计,其次才是 column family 和 qualifier 的组织。row key 决定排序、Region 分布、范围 scan 和热点形态。column family 决定物理 Store、缓存、压缩、版本和 TTL 边界。qualifier 提供稀疏属性表达能力,但不替代 row key 的排序能力。 本篇回答一个核心问题:排序、前缀、salt、反转和时间桶如何影响热点与扫描。写入路径的 WAL/MemStore 状态放到第 04 篇;读取路径的 BlockCache、Bloom Filter 和 HFile block 放到第 05、06 篇;Region split 和 assignment 放到第 08 篇。 schema-less 不是没有 schema。HBase 不强制预定义 qualifier,但 row key 编码、family 数量、版本数、TTL、压缩、Bloom Filter 和访问模式都属于 schema 决策。 RowKey 决策图 flowchart TD Q[主要...
深入 HBase 02 - 集群架构:HMaster、RegionServer、ZooKeeper 与 hbase:meta
前置问题与边界 HBase 集群架构最容易被写成一张“Master 管所有、ZooKeeper 存所有、RegionServer 干活”的粗图。这个粗图会误导读写路径。普通数据读写的主路径是 Client 定位 Region 后直连 RegionServer;HMaster 负责表和 Region 的控制面操作;ZooKeeper 保存协调和服务发现所需的短状态;hbase:meta 是 HBase 系统表,保存 Region 路由元数据。 本篇回答一个核心问题:控制面、数据面、协调状态和路由元数据如何分工。Region split、merge 和 assignment 的状态推进放到第 08 篇;客户端缓存、重试和重新定位放到第 09 篇;ServerCrashProcedure 和 WAL 恢复放到第 11 篇。 基础版本仍是 HBase 2.6.6。HBase 2.x 客户端实现存在 ConnectionRegistry 等路径,不能把“客户端总是直接从 ZooKeeper 找全部 Region”写成唯一机制。更稳妥的表述是:客户端通过 registry/元数据定位 hba...
深入 HBase 01 - 数据模型:Cell、Column Family 与版本
前置问题与边界 HBase 的一个值不是由“第几行第几列”定位,而是由 (row, family, qualifier, timestamp) 这组坐标定位。row 是 uninterpreted bytes,按字典序排序;family 在建表时定义,是存储、压缩、缓存、版本数和 TTL 等配置的边界;qualifier 是 family 之内的列限定符,可以动态出现;timestamp 是版本维度。 本篇回答一个核心问题:(row, family, qualifier, timestamp) 如何唯一定位一个值。写入路径、MVCC、WAL 和 flush 放到第 04 篇;Delete tombstone 在 compaction 中真正清理的条件放到第 07 篇;行级原子性放到第 10 篇。 HBase 的“宽列”容易被误写成两种东西。它不是关系数据库里的稀疏宽表,因为 qualifier 不需要全表预定义,也不存在空列占位。它也不是分析型列存,因为物理按 column family 组织 Store,目标是按 row key 的在线读写和范围 scan。 Cell 坐标图 ...
深入 HBase 00 - 导读:row key 决定数据位置
前置问题与边界 HBase 能在 HDFS 上提供随机读写,不是因为 HDFS 获得了原地随机修改能力。HBase 把随机写接在 RegionServer 服务层:mutation 先经过 WAL 和 MemStore,随后 flush 成 HDFS 上不可变的 HFile。随机读也不是对 HDFS 文件做逐字节定位;客户端先定位 row key 所属 Region,再直连负责该 Region 的 RegionServer,由 RegionServer 合并 MemStore、BlockCache 和 HFile 中的结果。 本篇回答一个核心问题:HBase 为什么能在面向大文件的 HDFS 之上提供在线随机读写,代价落在哪里。row key 的 salt、反转和时间桶放到第 03 篇;WAL、MVCC、MemStore 与 flush 的时序放到第 04 篇;BlockCache、Bloom Filter 和 HFile 放到第 05、06 篇;Compaction、恢复、复制和运维会在后续篇目展开。 基础机制以 HBase 2.6.6、Hadoop 3.4.3、JDK 17 ...
