欢迎光临
我们一直在努力

05-04-A-HBase与时序库详解

05-04-A-HBase与时序库详解

️ 关键词:HBase · LSM-Tree · RowKey 设计 · 列族 · Region · 时序数据库 · InfluxDB · TDengine · 降采样

📌 导读:MySQL 存"现在的状态",ClickHouse 存"历史的聚合",那海量明细的随机读写(用户画像、消息记录、监控指标原始值)谁存?HBase 就是为"海量 KV 随机读写"而生的分布式列存——万亿行、毫秒级点查、水平扩展。而带时间戳的指标数据(监控、IoT、行情)有时序库(InfluxDB/TDengine)这个更专的选手。这篇用大白话讲透:LSM-Tree 的实战形态(MemStore+HFile+Compaction,和 ClickHouse MergeTree 同源)、RowKey 设计三原则(散列/长度/反转)、列族与 Region 的切分、时序库的降采样与保留策略、HBase vs 时序库 vs ClickHouse 的选型。看完你能做到:被问"LSM-Tree 原理"能画出写读流程,被问"RowKey 怎么设计"能讲出三原则+热点规避,被问"监控数据存哪"能给出时序库方案。

前置知识:LSM-Tree 思想(19-A 篇 MergeTree)、B+ 树对比(12-A 篇)、分片思想(14-A 篇)。


📑 目录

  • 05-04-A-HBase与时序库详解
    • 📖 术语速查表(每个词都用人话解释)
    • 一、为什么需要 HBase:海量 KV 随机读写
      • 1.1 场景定位
      • 1.2 HBase 的四个核心能力
      • 1.3 HBase 不擅长什么(克制清单)
    • 二、LSM-Tree 实战形态:HBase 的存储引擎
      • 2.1 写入流程
      • 2.2 读取流程
      • 2.3 LSM-Tree vs B+ 树
    • 三、数据模型:RowKey、列族、时间戳
      • 3.1 四维数据模型
      • 3.2 列族设计原则
    • 四、RowKey 设计:HBase 第一设计决策
      • 4.1 三原则
      • 4.2 热点问题与规避
      • 4.3 经典设计案例
    • 五、Region 与水平扩展
      • 5.1 Region 切分
      • 5.2 预分区(Pre-Splitting)
      • 5.3 跑一遍:从建表到出结果
    • 六、时序数据库:InfluxDB 与 TDengine
      • 6.1 时序数据的特点
      • 6.2 时序数据模型(InfluxDB)
      • 6.3 降采样与保留策略
      • 6.4 跑一遍:从写入到降采样出结果
      • 6.5 InfluxDB vs TDengine vs Prometheus
    • 七、选型对比:HBase vs 时序库 vs ClickHouse
      • 7.1 分工表
      • 7.2 选型决策树
    • 八、总结
      • 8.1 一张图回顾全文
      • 8.2 核心要点浓缩(十二条)

📖 术语速查表(每个词都用人话解释)

️ HBase 核心类

术语一句话白话解释
HBase 建立在 HDFS 上的分布式列存 KV 数据库——万亿行、毫秒级随机读写、水平扩展、强一致
LSM-Tree(Log-Structured Merge Tree) HBase 的存储引擎思想:写入先进内存(MemStore),后台刷盘成有序文件(HFile),多层合并(Compaction)——写快读稍慢
MemStore 内存中的写缓冲区——写入先写 MemStore(有序),满了刷盘成 HFile
HFile(StoreFile) 磁盘上的有序数据文件(SSTable)——MemStore 刷盘的产物,不可变
Compaction 后台合并多个 HFile 成大 HFile——Minor Compaction 合并小文件,Major Compaction 合并全部+清理删除标记
WAL(Write-Ahead Log,HLog) 预写日志——写入 MemStore 前先写 WAL,crash 时靠 WAL 恢复未刷盘数据
RowKey 行键——HBase 的唯一索引,数据按 RowKey 字典序排序存储——设计决定一切
Column Family(列族) 列的分组——同一列族的数据物理存在一起,建表时指定,列族内列可动态增加
Cell 一个数据单元 = RowKey + 列族:列 + 时间戳 + 值——HBase 的最小存储单位
时间戳(Timestamp) 每个 Cell 的版本号——默认保留多版本,查询可指定版本/时间范围
Region HBase 的水平分片——表按 RowKey 范围切成多个 Region,分布在不同节点
RegionServer 管理 Region 的节点——负责读写请求、MemStore 刷盘、Compaction
HMaster 集群管理节点——负责 Region 分配、负载均衡、DDL(不处理读写)
ZooKeeper 协调服务——存 HMaster 地址、Region 元数据入口、集群状态

⏱️ 时序库类

术语一句话白话解释
时序数据库(TSDB) 专为带时间戳的指标数据优化的数据库——InfluxDB/TDengine/Prometheus
指标(Metric) 一条时间序列的名字(如 cpu_usage、order_qps)
标签(Tag) 指标的维度(如 host=web1、region=cn)——标签组合唯一确定一条时间序列
数据点(Point) 一个时间戳 + 一个值——时序数据的最小单位
降采样(Downsampling) 把高精度数据聚合为低精度(如 1s 原始值 → 1min 平均值)——老数据降精度省空间
保留策略(Retention Policy) 数据保留时长——超期自动删除(如原始数据留 7 天,1min 聚合留 1 年)
连续查询(Continuous Query) 定时自动执行的聚合查询——实现降采样的机制

一、为什么需要 HBase:海量 KV 随机读写

1.1 场景定位

#mermaid-svg-5F4pIcR1pxgKNF6T{font-family:Microsoft YaHei;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5F4pIcR1pxgKNF6T .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5F4pIcR1pxgKNF6T .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5F4pIcR1pxgKNF6T .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-5F4pIcR1pxgKNF6T .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-5F4pIcR1pxgKNF6T .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5F4pIcR1pxgKNF6T .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5F4pIcR1pxgKNF6T .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5F4pIcR1pxgKNF6T .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5F4pIcR1pxgKNF6T .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5F4pIcR1pxgKNF6T .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5F4pIcR1pxgKNF6T .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-5F4pIcR1pxgKNF6T .marker.cross{stroke:#0b0b0b;}#mermaid-svg-5F4pIcR1pxgKNF6T svg{font-family:Microsoft YaHei;font-size:16px;}#mermaid-svg-5F4pIcR1pxgKNF6T p{margin:0;}#mermaid-svg-5F4pIcR1pxgKNF6T .label{font-family:Microsoft YaHei;color:#333;}#mermaid-svg-5F4pIcR1pxgKNF6T .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-5F4pIcR1pxgKNF6T .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-5F4pIcR1pxgKNF6T .cluster-label span p{background-color:transparent;}#mermaid-svg-5F4pIcR1pxgKNF6T .label text,#mermaid-svg-5F4pIcR1pxgKNF6T span{fill:#333;color:#333;}#mermaid-svg-5F4pIcR1pxgKNF6T .node rect,#mermaid-svg-5F4pIcR1pxgKNF6T .node circle,#mermaid-svg-5F4pIcR1pxgKNF6T .node ellipse,#mermaid-svg-5F4pIcR1pxgKNF6T .node polygon,#mermaid-svg-5F4pIcR1pxgKNF6T .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-5F4pIcR1pxgKNF6T .rough-node .label text,#mermaid-svg-5F4pIcR1pxgKNF6T .node .label text,#mermaid-svg-5F4pIcR1pxgKNF6T .image-shape .label,#mermaid-svg-5F4pIcR1pxgKNF6T .icon-shape .label{text-anchor:middle;}#mermaid-svg-5F4pIcR1pxgKNF6T .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5F4pIcR1pxgKNF6T .rough-node .label,#mermaid-svg-5F4pIcR1pxgKNF6T .node .label,#mermaid-svg-5F4pIcR1pxgKNF6T .image-shape .label,#mermaid-svg-5F4pIcR1pxgKNF6T .icon-shape .label{text-align:center;}#mermaid-svg-5F4pIcR1pxgKNF6T .node.clickable{cursor:pointer;}#mermaid-svg-5F4pIcR1pxgKNF6T .root .anchor path{fill:#0b0b0b!important;stroke-width:0;stroke:#0b0b0b;}#mermaid-svg-5F4pIcR1pxgKNF6T .arrowheadPath{fill:#0b0b0b;}#mermaid-svg-5F4pIcR1pxgKNF6T .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#mermaid-svg-5F4pIcR1pxgKNF6T .flowchart-link{stroke:#0b0b0b;fill:none;}#mermaid-svg-5F4pIcR1pxgKNF6T .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-5F4pIcR1pxgKNF6T .edgeLabel p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-5F4pIcR1pxgKNF6T .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-5F4pIcR1pxgKNF6T .labelBkg{background-color:rgba(243.9999999999, 220.9999999998, 255, 0.5);}#mermaid-svg-5F4pIcR1pxgKNF6T .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#mermaid-svg-5F4pIcR1pxgKNF6T .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-5F4pIcR1pxgKNF6T .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-5F4pIcR1pxgKNF6T div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:Microsoft YaHei;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid hsl(220.5882352941, 60%, 88.3333333333%);border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5F4pIcR1pxgKNF6T .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5F4pIcR1pxgKNF6T rect.text{fill:none;stroke-width:0;}#mermaid-svg-5F4pIcR1pxgKNF6T .icon-shape,#mermaid-svg-5F4pIcR1pxgKNF6T .image-shape{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-5F4pIcR1pxgKNF6T .icon-shape p,#mermaid-svg-5F4pIcR1pxgKNF6T .image-shape p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);padding:2px;}#mermaid-svg-5F4pIcR1pxgKNF6T .icon-shape .label rect,#mermaid-svg-5F4pIcR1pxgKNF6T .image-shape .label rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-5F4pIcR1pxgKNF6T .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5F4pIcR1pxgKNF6T .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5F4pIcR1pxgKNF6T :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

存储家族的分工。

MySQL,行存。
强一致交易,单表千万级。
点查 / 事务 / JOIN。

ClickHouse,列存。
海量聚合,OLAP。
扫多行少列,出指标。

HBase,LSM 列存。
海量 KV 随机读写,万亿行。
毫秒级点查,水平扩展。

HBase 典型场景。
用户画像,消息记录,
订单历史,风控特征,
Feed 流,物联网设备状态。

时序库,时序优化。
带时间戳指标,监控 / IoT。
降采样 + 保留策略。

1.2 HBase 的四个核心能力

能力说明
海量存储 万亿行、PB 级——HDFS 底层,水平扩展
毫秒级随机读写 按 RowKey 点查/点写毫秒级——LSM-Tree + 布隆过滤器
强一致 单行读写强一致(Region 级)——比 Cassandra 的最终一致强
稀疏列 列可动态增加、稀疏存储——空列不占空间

1.3 HBase 不擅长什么(克制清单)

不擅长原因替代
复杂查询/JOIN 只有 RowKey 索引,无二级索引(原生) Phoenix(SQL 层)/ ES
全表扫描聚合 列存但非向量化,聚合慢 ClickHouse
事务 只支持单行事务 MySQL
低延迟批量分析 为点查优化 ClickHouse

二、LSM-Tree 实战形态:HBase 的存储引擎

2.1 写入流程

#mermaid-svg-HAEoORSycA5wqlLd{font-family:Microsoft YaHei;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HAEoORSycA5wqlLd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HAEoORSycA5wqlLd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HAEoORSycA5wqlLd .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-HAEoORSycA5wqlLd .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-HAEoORSycA5wqlLd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HAEoORSycA5wqlLd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HAEoORSycA5wqlLd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HAEoORSycA5wqlLd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HAEoORSycA5wqlLd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HAEoORSycA5wqlLd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HAEoORSycA5wqlLd .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-HAEoORSycA5wqlLd .marker.cross{stroke:#0b0b0b;}#mermaid-svg-HAEoORSycA5wqlLd svg{font-family:Microsoft YaHei;font-size:16px;}#mermaid-svg-HAEoORSycA5wqlLd p{margin:0;}#mermaid-svg-HAEoORSycA5wqlLd .label{font-family:Microsoft YaHei;color:#333;}#mermaid-svg-HAEoORSycA5wqlLd .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-HAEoORSycA5wqlLd .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-HAEoORSycA5wqlLd .cluster-label span p{background-color:transparent;}#mermaid-svg-HAEoORSycA5wqlLd .label text,#mermaid-svg-HAEoORSycA5wqlLd span{fill:#333;color:#333;}#mermaid-svg-HAEoORSycA5wqlLd .node rect,#mermaid-svg-HAEoORSycA5wqlLd .node circle,#mermaid-svg-HAEoORSycA5wqlLd .node ellipse,#mermaid-svg-HAEoORSycA5wqlLd .node polygon,#mermaid-svg-HAEoORSycA5wqlLd .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-HAEoORSycA5wqlLd .rough-node .label text,#mermaid-svg-HAEoORSycA5wqlLd .node .label text,#mermaid-svg-HAEoORSycA5wqlLd .image-shape .label,#mermaid-svg-HAEoORSycA5wqlLd .icon-shape .label{text-anchor:middle;}#mermaid-svg-HAEoORSycA5wqlLd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HAEoORSycA5wqlLd .rough-node .label,#mermaid-svg-HAEoORSycA5wqlLd .node .label,#mermaid-svg-HAEoORSycA5wqlLd .image-shape .label,#mermaid-svg-HAEoORSycA5wqlLd .icon-shape .label{text-align:center;}#mermaid-svg-HAEoORSycA5wqlLd .node.clickable{cursor:pointer;}#mermaid-svg-HAEoORSycA5wqlLd .root .anchor path{fill:#0b0b0b!important;stroke-width:0;stroke:#0b0b0b;}#mermaid-svg-HAEoORSycA5wqlLd .arrowheadPath{fill:#0b0b0b;}#mermaid-svg-HAEoORSycA5wqlLd .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#mermaid-svg-HAEoORSycA5wqlLd .flowchart-link{stroke:#0b0b0b;fill:none;}#mermaid-svg-HAEoORSycA5wqlLd .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-HAEoORSycA5wqlLd .edgeLabel p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-HAEoORSycA5wqlLd .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-HAEoORSycA5wqlLd .labelBkg{background-color:rgba(243.9999999999, 220.9999999998, 255, 0.5);}#mermaid-svg-HAEoORSycA5wqlLd .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#mermaid-svg-HAEoORSycA5wqlLd .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-HAEoORSycA5wqlLd .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-HAEoORSycA5wqlLd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:Microsoft YaHei;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid hsl(220.5882352941, 60%, 88.3333333333%);border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HAEoORSycA5wqlLd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HAEoORSycA5wqlLd rect.text{fill:none;stroke-width:0;}#mermaid-svg-HAEoORSycA5wqlLd .icon-shape,#mermaid-svg-HAEoORSycA5wqlLd .image-shape{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-HAEoORSycA5wqlLd .icon-shape p,#mermaid-svg-HAEoORSycA5wqlLd .image-shape p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);padding:2px;}#mermaid-svg-HAEoORSycA5wqlLd .icon-shape .label rect,#mermaid-svg-HAEoORSycA5wqlLd .image-shape .label rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-HAEoORSycA5wqlLd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HAEoORSycA5wqlLd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HAEoORSycA5wqlLd :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

是

否

是

写入请求。

① 写 WAL,HLog。
预写日志,持久化保证。
crash 时靠 WAL 恢复。

② 写 MemStore。
内存有序写缓冲,
按 RowKey 排序。
写入毫秒级,无磁盘 IO。

MemStore 满了?默认 128MB。

③ Flush 刷盘。
MemStore → HFile,
有序数据文件。
HFile 不可变。

写入完成,返回客户端。

HFile 太多?触发 Compaction。

④ Compaction 合并。
Minor:合并小 HFile。
Major:合并全部 + 清理删除标记。
后台异步,不阻塞写入。

白话:写入 = 写 WAL(保命)+ 写 MemStore(快)→ 满了刷盘成 HFile → HFile 多了后台合并——写路径全程顺序 IO,所以写入极快。

2.2 读取流程

#mermaid-svg-1D0meyCipSyxTa5d{font-family:Microsoft YaHei;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1D0meyCipSyxTa5d .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1D0meyCipSyxTa5d .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1D0meyCipSyxTa5d .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-1D0meyCipSyxTa5d .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-1D0meyCipSyxTa5d .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1D0meyCipSyxTa5d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1D0meyCipSyxTa5d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1D0meyCipSyxTa5d .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1D0meyCipSyxTa5d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1D0meyCipSyxTa5d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1D0meyCipSyxTa5d .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-1D0meyCipSyxTa5d .marker.cross{stroke:#0b0b0b;}#mermaid-svg-1D0meyCipSyxTa5d svg{font-family:Microsoft YaHei;font-size:16px;}#mermaid-svg-1D0meyCipSyxTa5d p{margin:0;}#mermaid-svg-1D0meyCipSyxTa5d .label{font-family:Microsoft YaHei;color:#333;}#mermaid-svg-1D0meyCipSyxTa5d .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-1D0meyCipSyxTa5d .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-1D0meyCipSyxTa5d .cluster-label span p{background-color:transparent;}#mermaid-svg-1D0meyCipSyxTa5d .label text,#mermaid-svg-1D0meyCipSyxTa5d span{fill:#333;color:#333;}#mermaid-svg-1D0meyCipSyxTa5d .node rect,#mermaid-svg-1D0meyCipSyxTa5d .node circle,#mermaid-svg-1D0meyCipSyxTa5d .node ellipse,#mermaid-svg-1D0meyCipSyxTa5d .node polygon,#mermaid-svg-1D0meyCipSyxTa5d .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-1D0meyCipSyxTa5d .rough-node .label text,#mermaid-svg-1D0meyCipSyxTa5d .node .label text,#mermaid-svg-1D0meyCipSyxTa5d .image-shape .label,#mermaid-svg-1D0meyCipSyxTa5d .icon-shape .label{text-anchor:middle;}#mermaid-svg-1D0meyCipSyxTa5d .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1D0meyCipSyxTa5d .rough-node .label,#mermaid-svg-1D0meyCipSyxTa5d .node .label,#mermaid-svg-1D0meyCipSyxTa5d .image-shape .label,#mermaid-svg-1D0meyCipSyxTa5d .icon-shape .label{text-align:center;}#mermaid-svg-1D0meyCipSyxTa5d .node.clickable{cursor:pointer;}#mermaid-svg-1D0meyCipSyxTa5d .root .anchor path{fill:#0b0b0b!important;stroke-width:0;stroke:#0b0b0b;}#mermaid-svg-1D0meyCipSyxTa5d .arrowheadPath{fill:#0b0b0b;}#mermaid-svg-1D0meyCipSyxTa5d .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#mermaid-svg-1D0meyCipSyxTa5d .flowchart-link{stroke:#0b0b0b;fill:none;}#mermaid-svg-1D0meyCipSyxTa5d .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-1D0meyCipSyxTa5d .edgeLabel p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-1D0meyCipSyxTa5d .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-1D0meyCipSyxTa5d .labelBkg{background-color:rgba(243.9999999999, 220.9999999998, 255, 0.5);}#mermaid-svg-1D0meyCipSyxTa5d .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#mermaid-svg-1D0meyCipSyxTa5d .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-1D0meyCipSyxTa5d .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-1D0meyCipSyxTa5d div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:Microsoft YaHei;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid hsl(220.5882352941, 60%, 88.3333333333%);border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1D0meyCipSyxTa5d .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1D0meyCipSyxTa5d rect.text{fill:none;stroke-width:0;}#mermaid-svg-1D0meyCipSyxTa5d .icon-shape,#mermaid-svg-1D0meyCipSyxTa5d .image-shape{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-1D0meyCipSyxTa5d .icon-shape p,#mermaid-svg-1D0meyCipSyxTa5d .image-shape p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);padding:2px;}#mermaid-svg-1D0meyCipSyxTa5d .icon-shape .label rect,#mermaid-svg-1D0meyCipSyxTa5d .image-shape .label rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-1D0meyCipSyxTa5d .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1D0meyCipSyxTa5d .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1D0meyCipSyxTa5d :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

读取请求,按 RowKey。

① 查 MemStore。内存中最新数据。

② 查 BlockCache。内存读缓存,热数据。

③ 查 HFile。
磁盘有序文件,从新到旧。
布隆过滤器快速排除
不含目标 RowKey 的 HFile。

④ 合并多版本。
MemStore + 多个 HFile 的结果,
按时间戳取最新 / 指定版本。

返回结果。

读比写慢的原因:读可能要查 MemStore + 多个 HFile(合并多版本)——Compaction 减少 HFile 数量 = 减少读放大。布隆过滤器加速:快速判断某个 HFile 是否可能包含目标 RowKey,不含则跳过。

2.3 LSM-Tree vs B+ 树

维度LSM-Tree(HBase)B+ 树(MySQL)
写入 顺序写(MemStore→HFile),快 随机写(维护树结构),慢
读取 可能查多层(读放大),稍慢 一次树查找,快
空间放大 Compaction 期间有空间放大 无
写放大 Compaction 重写数据 无
适用 写多读少、海量数据 读写均衡、单表千万级

一句话:LSM-Tree 用"读放大+空间放大"换"写极快"——写多读少的海量场景选 LSM,读写均衡选 B+ 树。


三、数据模型:RowKey、列族、时间戳

3.1 四维数据模型

RowKey: user_001
├── Column Family: info
│ ├── name: 张三 (timestamp: t1)
│ ├── age: 25 (timestamp: t1)
│ └── city: 北京 (timestamp: t2)
├── Column Family: order
│ ├── order_001: {…} (timestamp: t3)
│ └── order_002: {…} (timestamp: t4)

四个维度:

  • RowKey:行键,唯一标识一行,数据按 RowKey 字典序排序;
  • Column Family(列族):列的分组,同一列族物理存在一起(HFile 按列族分),建表时指定;
  • Column(列):列族内的列,可动态增加(schema-free);
  • Timestamp:每个 Cell 的版本号,默认保留 3 个版本,可配置。
  • 3.2 列族设计原则

    原则说明
    列族要少 一般 1~3 个——列族多 = MemStore 多 = Flush 频繁 = 小 HFile 多
    列族内列可动态 不用预先定义所有列——稀疏列不占空间
    访问模式相近的列放一族 一起读写的列放同一列族——减少 IO

    四、RowKey 设计:HBase 第一设计决策

    4.1 三原则

    #mermaid-svg-DNR3Uq2uGueSJl5s{font-family:Microsoft YaHei;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DNR3Uq2uGueSJl5s .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DNR3Uq2uGueSJl5s .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DNR3Uq2uGueSJl5s .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-DNR3Uq2uGueSJl5s .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-DNR3Uq2uGueSJl5s .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DNR3Uq2uGueSJl5s .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DNR3Uq2uGueSJl5s .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DNR3Uq2uGueSJl5s .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DNR3Uq2uGueSJl5s .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DNR3Uq2uGueSJl5s .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DNR3Uq2uGueSJl5s .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-DNR3Uq2uGueSJl5s .marker.cross{stroke:#0b0b0b;}#mermaid-svg-DNR3Uq2uGueSJl5s svg{font-family:Microsoft YaHei;font-size:16px;}#mermaid-svg-DNR3Uq2uGueSJl5s p{margin:0;}#mermaid-svg-DNR3Uq2uGueSJl5s .label{font-family:Microsoft YaHei;color:#333;}#mermaid-svg-DNR3Uq2uGueSJl5s .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-DNR3Uq2uGueSJl5s .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-DNR3Uq2uGueSJl5s .cluster-label span p{background-color:transparent;}#mermaid-svg-DNR3Uq2uGueSJl5s .label text,#mermaid-svg-DNR3Uq2uGueSJl5s span{fill:#333;color:#333;}#mermaid-svg-DNR3Uq2uGueSJl5s .node rect,#mermaid-svg-DNR3Uq2uGueSJl5s .node circle,#mermaid-svg-DNR3Uq2uGueSJl5s .node ellipse,#mermaid-svg-DNR3Uq2uGueSJl5s .node polygon,#mermaid-svg-DNR3Uq2uGueSJl5s .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-DNR3Uq2uGueSJl5s .rough-node .label text,#mermaid-svg-DNR3Uq2uGueSJl5s .node .label text,#mermaid-svg-DNR3Uq2uGueSJl5s .image-shape .label,#mermaid-svg-DNR3Uq2uGueSJl5s .icon-shape .label{text-anchor:middle;}#mermaid-svg-DNR3Uq2uGueSJl5s .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DNR3Uq2uGueSJl5s .rough-node .label,#mermaid-svg-DNR3Uq2uGueSJl5s .node .label,#mermaid-svg-DNR3Uq2uGueSJl5s .image-shape .label,#mermaid-svg-DNR3Uq2uGueSJl5s .icon-shape .label{text-align:center;}#mermaid-svg-DNR3Uq2uGueSJl5s .node.clickable{cursor:pointer;}#mermaid-svg-DNR3Uq2uGueSJl5s .root .anchor path{fill:#0b0b0b!important;stroke-width:0;stroke:#0b0b0b;}#mermaid-svg-DNR3Uq2uGueSJl5s .arrowheadPath{fill:#0b0b0b;}#mermaid-svg-DNR3Uq2uGueSJl5s .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#mermaid-svg-DNR3Uq2uGueSJl5s .flowchart-link{stroke:#0b0b0b;fill:none;}#mermaid-svg-DNR3Uq2uGueSJl5s .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-DNR3Uq2uGueSJl5s .edgeLabel p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-DNR3Uq2uGueSJl5s .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-DNR3Uq2uGueSJl5s .labelBkg{background-color:rgba(243.9999999999, 220.9999999998, 255, 0.5);}#mermaid-svg-DNR3Uq2uGueSJl5s .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#mermaid-svg-DNR3Uq2uGueSJl5s .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-DNR3Uq2uGueSJl5s .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-DNR3Uq2uGueSJl5s div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:Microsoft YaHei;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid hsl(220.5882352941, 60%, 88.3333333333%);border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DNR3Uq2uGueSJl5s .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DNR3Uq2uGueSJl5s rect.text{fill:none;stroke-width:0;}#mermaid-svg-DNR3Uq2uGueSJl5s .icon-shape,#mermaid-svg-DNR3Uq2uGueSJl5s .image-shape{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-DNR3Uq2uGueSJl5s .icon-shape p,#mermaid-svg-DNR3Uq2uGueSJl5s .image-shape p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);padding:2px;}#mermaid-svg-DNR3Uq2uGueSJl5s .icon-shape .label rect,#mermaid-svg-DNR3Uq2uGueSJl5s .image-shape .label rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-DNR3Uq2uGueSJl5s .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DNR3Uq2uGueSJl5s .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DNR3Uq2uGueSJl5s :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    RowKey 设计三原则。

    ① 唯一性 RowKey 是唯一索引
    必须能唯一标识一行。

    ② 散列性,防热点
    写入要均匀分布到各 Region
    避免 RowKey 有序导致写热点 →
    加盐 / 哈希 / 反转。

    ③ 长度短 RowKey 存在每个 C
    ell 里 太长=空间浪费+比较慢
    → 控制在 16~100 字节。

    4.2 热点问题与规避

    问题:RowKey 有序(如自增 ID、时间戳开头)→ 新数据全写到最后一个 Region → 写热点(和 ClickHouse 范围分片热点同款,19-B 篇事故二)。

    三种规避方案:

    方案做法适用
    加盐(Salting) RowKey 前加随机前缀(如 hash(user_id)%16) 写入均匀,但范围查询要扫所有前缀
    哈希 RowKey = MD5(user_id) 完全散列,牺牲范围查询
    反转(Reversing) RowKey = 反转(user_id) 或 反转(时间戳) 保留部分范围查询能力(如手机号反转后同尾号聚集)

    4.3 经典设计案例

    RowKey = userId_反转 + (Long.MAX_VALUE – timestamp)

    RowKey = hash(userId) + userId + timestamp

    设计口诀:点查为主用哈希/反转散列,范围查询为主用"散列前缀+有序后缀"组合。


    五、Region 与水平扩展

    5.1 Region 切分

    #mermaid-svg-0WkdUxxW6OkRwEhY{font-family:Microsoft YaHei;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0WkdUxxW6OkRwEhY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0WkdUxxW6OkRwEhY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0WkdUxxW6OkRwEhY .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-0WkdUxxW6OkRwEhY .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-0WkdUxxW6OkRwEhY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0WkdUxxW6OkRwEhY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0WkdUxxW6OkRwEhY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0WkdUxxW6OkRwEhY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0WkdUxxW6OkRwEhY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0WkdUxxW6OkRwEhY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0WkdUxxW6OkRwEhY .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-0WkdUxxW6OkRwEhY .marker.cross{stroke:#0b0b0b;}#mermaid-svg-0WkdUxxW6OkRwEhY svg{font-family:Microsoft YaHei;font-size:16px;}#mermaid-svg-0WkdUxxW6OkRwEhY p{margin:0;}#mermaid-svg-0WkdUxxW6OkRwEhY .label{font-family:Microsoft YaHei;color:#333;}#mermaid-svg-0WkdUxxW6OkRwEhY .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-0WkdUxxW6OkRwEhY .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-0WkdUxxW6OkRwEhY .cluster-label span p{background-color:transparent;}#mermaid-svg-0WkdUxxW6OkRwEhY .label text,#mermaid-svg-0WkdUxxW6OkRwEhY span{fill:#333;color:#333;}#mermaid-svg-0WkdUxxW6OkRwEhY .node rect,#mermaid-svg-0WkdUxxW6OkRwEhY .node circle,#mermaid-svg-0WkdUxxW6OkRwEhY .node ellipse,#mermaid-svg-0WkdUxxW6OkRwEhY .node polygon,#mermaid-svg-0WkdUxxW6OkRwEhY .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-0WkdUxxW6OkRwEhY .rough-node .label text,#mermaid-svg-0WkdUxxW6OkRwEhY .node .label text,#mermaid-svg-0WkdUxxW6OkRwEhY .image-shape .label,#mermaid-svg-0WkdUxxW6OkRwEhY .icon-shape .label{text-anchor:middle;}#mermaid-svg-0WkdUxxW6OkRwEhY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0WkdUxxW6OkRwEhY .rough-node .label,#mermaid-svg-0WkdUxxW6OkRwEhY .node .label,#mermaid-svg-0WkdUxxW6OkRwEhY .image-shape .label,#mermaid-svg-0WkdUxxW6OkRwEhY .icon-shape .label{text-align:center;}#mermaid-svg-0WkdUxxW6OkRwEhY .node.clickable{cursor:pointer;}#mermaid-svg-0WkdUxxW6OkRwEhY .root .anchor path{fill:#0b0b0b!important;stroke-width:0;stroke:#0b0b0b;}#mermaid-svg-0WkdUxxW6OkRwEhY .arrowheadPath{fill:#0b0b0b;}#mermaid-svg-0WkdUxxW6OkRwEhY .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#mermaid-svg-0WkdUxxW6OkRwEhY .flowchart-link{stroke:#0b0b0b;fill:none;}#mermaid-svg-0WkdUxxW6OkRwEhY .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-0WkdUxxW6OkRwEhY .edgeLabel p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-0WkdUxxW6OkRwEhY .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-0WkdUxxW6OkRwEhY .labelBkg{background-color:rgba(243.9999999999, 220.9999999998, 255, 0.5);}#mermaid-svg-0WkdUxxW6OkRwEhY .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#mermaid-svg-0WkdUxxW6OkRwEhY .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-0WkdUxxW6OkRwEhY .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-0WkdUxxW6OkRwEhY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:Microsoft YaHei;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid hsl(220.5882352941, 60%, 88.3333333333%);border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0WkdUxxW6OkRwEhY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0WkdUxxW6OkRwEhY rect.text{fill:none;stroke-width:0;}#mermaid-svg-0WkdUxxW6OkRwEhY .icon-shape,#mermaid-svg-0WkdUxxW6OkRwEhY .image-shape{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-0WkdUxxW6OkRwEhY .icon-shape p,#mermaid-svg-0WkdUxxW6OkRwEhY .image-shape p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);padding:2px;}#mermaid-svg-0WkdUxxW6OkRwEhY .icon-shape .label rect,#mermaid-svg-0WkdUxxW6OkRwEhY .image-shape .label rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-0WkdUxxW6OkRwEhY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0WkdUxxW6OkRwEhY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0WkdUxxW6OkRwEhY :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    表按 RowKey 范围切成 Region。
    Region1:a~f,
    Region2:f~m,
    Region3:m~z。

    Region 分布在不同 RegionServer,
    负载均衡。

    Region 过大自动 Split。
    一个 Region 拆成两个,
    默认 10GB 触发。

    HMaster 负责 Region 分配。
    RegionServer 宕机 →
    Region 重新分配。
    靠 WAL + HDFS 保证数据不丢。

    ZooKeeper 存元数据入口。
    客户端先查 ZK 找 Region 位置,
    缓存后直连 RegionServer。

    5.2 预分区(Pre-Splitting)

    问题:建表时只有 1 个 Region → 写入全打到 1 个 Region → 热点 → 自动 Split 追不上写入速度。

    解决:建表时预分区——预先指定 Split 点,创建多个 Region 均匀分布:

    create 'user_table', 'info', {SPLITS => ['1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']}

    一句话:预分区是 HBase 建表的必做项——不预分区 = 单 Region 热点 = 写入瓶颈。

    5.3 跑一遍:从建表到出结果

    纯文字不好理解?下面是一段可以直接复制到 HBase Shell 执行的完整示例(场景:用户消息记录,RowKey = 哈希前缀 + userId + 反转时间戳),每一步都给出真实结果。

    # ① 建表:info 列族保留 3 个版本 + 预分区 16 个 Region(按十六进制前缀 0~f 切分)
    create 'user_msg', {NAME => 'info', VERSIONS => 3}, {NAME => 'msg'}, \\
    {SPLITS => ['1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']}

    # ② 写入 3 条数据(RowKey 前缀 a3 = hash(userId)%16,后缀 = Long.MAX_VALUE – timestamp,保证同一用户最新消息排前面)
    put 'user_msg', 'a3_1001_9223370536854775000', 'info:name', '张三'
    put 'user_msg', 'a3_1001_9223370536854775000', 'msg:content', '你好,订单已发货'
    put 'user_msg', 'a3_1001_9223370536854774000', 'msg:content', '你好,请问何时付款?'

    # ③ 点查:按 RowKey 精确查一行(毫秒级)
    get 'user_msg', 'a3_1001_9223370536854775000'

    # ④ 前缀扫描:查用户 1001 的全部消息(反转时间戳 → 最新的排最前)
    scan 'user_msg', {ROWPREFIXFILTER => 'a3_1001_', LIMIT => 10}

    ③ 的查询结果(一次点查只命中一个 Region,毫秒级返回):

    COLUMN CELL
    info:name timestamp=1704067200000, value=张三
    msg:content timestamp=1704067200000, value=你好,订单已发货
    1 row(s)
    Took 0.0120 seconds

    ④ 的扫描结果(注意顺序:反转时间戳让最新消息排在最前,LIMIT 10 即"最近 10 条"):

    ROW COLUMN CELL
    a3_1001_…774000 msg:content value=你好,请问何时付款?
    a3_1001_…775000 info:name value=张三
    a3_1001_…775000 msg:content value=你好,订单已发货
    2 row(s)
    Took 0.0350 seconds

    Java 客户端(生产代码不用 Shell,用 hbase-client):

    // 点查:Get 按 RowKey 精确命中
    try (Connection conn = ConnectionFactory.createConnection(conf)) {
    Table table = conn.getTable(TableName.valueOf("user_msg"));
    Get get = new Get(Bytes.toBytes("a3_1001_9223370536854775000"));
    Result result = table.get(get);
    String name = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("name")));
    // name = "张三"

    // 前缀扫描:查某用户最近 N 条消息
    Scan scan = new Scan();
    scan.setRowPrefixFilter(Bytes.toBytes("a3_1001_"));
    scan.setLimit(10);
    ResultScanner scanner = table.getScanner(scan);
    for (Result r : scanner) {
    // 逐行处理,顺序即"最新在前"
    }
    }

    💡 对照理解:第 ③ 步点查走的是「RowKey → Region 定位 → MemStore/BlockCache/HFile」路径,只碰一个 Region;第 ④ 步前缀扫描能"只扫一个用户的数据",靠的是 RowKey 字典序存储 + 散列前缀把同一用户聚在相邻位置——这就是 4.3 节"散列前缀 + 有序后缀"设计的直观回报。


    六、时序数据库:InfluxDB 与 TDengine

    6.1 时序数据的特点

    #mermaid-svg-NJEwhjGXXDOYpZMd{font-family:Microsoft YaHei;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NJEwhjGXXDOYpZMd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NJEwhjGXXDOYpZMd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NJEwhjGXXDOYpZMd .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-NJEwhjGXXDOYpZMd .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-NJEwhjGXXDOYpZMd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NJEwhjGXXDOYpZMd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NJEwhjGXXDOYpZMd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NJEwhjGXXDOYpZMd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NJEwhjGXXDOYpZMd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NJEwhjGXXDOYpZMd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NJEwhjGXXDOYpZMd .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-NJEwhjGXXDOYpZMd .marker.cross{stroke:#0b0b0b;}#mermaid-svg-NJEwhjGXXDOYpZMd svg{font-family:Microsoft YaHei;font-size:16px;}#mermaid-svg-NJEwhjGXXDOYpZMd p{margin:0;}#mermaid-svg-NJEwhjGXXDOYpZMd .label{font-family:Microsoft YaHei;color:#333;}#mermaid-svg-NJEwhjGXXDOYpZMd .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-NJEwhjGXXDOYpZMd .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-NJEwhjGXXDOYpZMd .cluster-label span p{background-color:transparent;}#mermaid-svg-NJEwhjGXXDOYpZMd .label text,#mermaid-svg-NJEwhjGXXDOYpZMd span{fill:#333;color:#333;}#mermaid-svg-NJEwhjGXXDOYpZMd .node rect,#mermaid-svg-NJEwhjGXXDOYpZMd .node circle,#mermaid-svg-NJEwhjGXXDOYpZMd .node ellipse,#mermaid-svg-NJEwhjGXXDOYpZMd .node polygon,#mermaid-svg-NJEwhjGXXDOYpZMd .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-NJEwhjGXXDOYpZMd .rough-node .label text,#mermaid-svg-NJEwhjGXXDOYpZMd .node .label text,#mermaid-svg-NJEwhjGXXDOYpZMd .image-shape .label,#mermaid-svg-NJEwhjGXXDOYpZMd .icon-shape .label{text-anchor:middle;}#mermaid-svg-NJEwhjGXXDOYpZMd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NJEwhjGXXDOYpZMd .rough-node .label,#mermaid-svg-NJEwhjGXXDOYpZMd .node .label,#mermaid-svg-NJEwhjGXXDOYpZMd .image-shape .label,#mermaid-svg-NJEwhjGXXDOYpZMd .icon-shape .label{text-align:center;}#mermaid-svg-NJEwhjGXXDOYpZMd .node.clickable{cursor:pointer;}#mermaid-svg-NJEwhjGXXDOYpZMd .root .anchor path{fill:#0b0b0b!important;stroke-width:0;stroke:#0b0b0b;}#mermaid-svg-NJEwhjGXXDOYpZMd .arrowheadPath{fill:#0b0b0b;}#mermaid-svg-NJEwhjGXXDOYpZMd .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#mermaid-svg-NJEwhjGXXDOYpZMd .flowchart-link{stroke:#0b0b0b;fill:none;}#mermaid-svg-NJEwhjGXXDOYpZMd .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-NJEwhjGXXDOYpZMd .edgeLabel p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-NJEwhjGXXDOYpZMd .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-NJEwhjGXXDOYpZMd .labelBkg{background-color:rgba(243.9999999999, 220.9999999998, 255, 0.5);}#mermaid-svg-NJEwhjGXXDOYpZMd .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#mermaid-svg-NJEwhjGXXDOYpZMd .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-NJEwhjGXXDOYpZMd .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-NJEwhjGXXDOYpZMd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:Microsoft YaHei;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid hsl(220.5882352941, 60%, 88.3333333333%);border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-NJEwhjGXXDOYpZMd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NJEwhjGXXDOYpZMd rect.text{fill:none;stroke-width:0;}#mermaid-svg-NJEwhjGXXDOYpZMd .icon-shape,#mermaid-svg-NJEwhjGXXDOYpZMd .image-shape{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-NJEwhjGXXDOYpZMd .icon-shape p,#mermaid-svg-NJEwhjGXXDOYpZMd .image-shape p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);padding:2px;}#mermaid-svg-NJEwhjGXXDOYpZMd .icon-shape .label rect,#mermaid-svg-NJEwhjGXXDOYpZMd .image-shape .label rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-NJEwhjGXXDOYpZMd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NJEwhjGXXDOYpZMd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NJEwhjGXXDOYpZMd :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    时序数据特点。

    ① 带时间戳。
    每个数据点 = 时间戳 + 值,
    按时间顺序写入。

    ② 只追加不修改。
    历史数据不变,新数据追加。
    → LSM-Tree 天然适配。

    ③ 按时间范围查询。
    查最近 1 小时 / 最近 1 天。
    → 时间分区裁剪。

    ④ 聚合为主。
    平均值 / 最大值 / P99。
    → 降采样预聚合。

    ⑤ 数据量大,
    价值随时间衰减。
    老数据价值低。
    → 保留策略自动删除。

    6.2 时序数据模型(InfluxDB)

    Measurement: cpu_usage # 指标名(类似表名)
    Tags: host=web1, region=cn # 标签(维度,建索引)
    Fields: value=0.75 # 字段(值,不建索引)
    Timestamp: 2024-01-01T10:00:00 # 时间戳

    Tags vs Fields:Tags 建索引(查询过滤用),Fields 不建索引(存值)——高基数维度别放 Tag(如 user_id 放 Tag = 索引爆炸)。

    6.3 降采样与保留策略

    #mermaid-svg-W2H79hgEbxHURLiS{font-family:Microsoft YaHei;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-W2H79hgEbxHURLiS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-W2H79hgEbxHURLiS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-W2H79hgEbxHURLiS .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-W2H79hgEbxHURLiS .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-W2H79hgEbxHURLiS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-W2H79hgEbxHURLiS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-W2H79hgEbxHURLiS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-W2H79hgEbxHURLiS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-W2H79hgEbxHURLiS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-W2H79hgEbxHURLiS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-W2H79hgEbxHURLiS .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-W2H79hgEbxHURLiS .marker.cross{stroke:#0b0b0b;}#mermaid-svg-W2H79hgEbxHURLiS svg{font-family:Microsoft YaHei;font-size:16px;}#mermaid-svg-W2H79hgEbxHURLiS p{margin:0;}#mermaid-svg-W2H79hgEbxHURLiS .label{font-family:Microsoft YaHei;color:#333;}#mermaid-svg-W2H79hgEbxHURLiS .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-W2H79hgEbxHURLiS .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-W2H79hgEbxHURLiS .cluster-label span p{background-color:transparent;}#mermaid-svg-W2H79hgEbxHURLiS .label text,#mermaid-svg-W2H79hgEbxHURLiS span{fill:#333;color:#333;}#mermaid-svg-W2H79hgEbxHURLiS .node rect,#mermaid-svg-W2H79hgEbxHURLiS .node circle,#mermaid-svg-W2H79hgEbxHURLiS .node ellipse,#mermaid-svg-W2H79hgEbxHURLiS .node polygon,#mermaid-svg-W2H79hgEbxHURLiS .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-W2H79hgEbxHURLiS .rough-node .label text,#mermaid-svg-W2H79hgEbxHURLiS .node .label text,#mermaid-svg-W2H79hgEbxHURLiS .image-shape .label,#mermaid-svg-W2H79hgEbxHURLiS .icon-shape .label{text-anchor:middle;}#mermaid-svg-W2H79hgEbxHURLiS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-W2H79hgEbxHURLiS .rough-node .label,#mermaid-svg-W2H79hgEbxHURLiS .node .label,#mermaid-svg-W2H79hgEbxHURLiS .image-shape .label,#mermaid-svg-W2H79hgEbxHURLiS .icon-shape .label{text-align:center;}#mermaid-svg-W2H79hgEbxHURLiS .node.clickable{cursor:pointer;}#mermaid-svg-W2H79hgEbxHURLiS .root .anchor path{fill:#0b0b0b!important;stroke-width:0;stroke:#0b0b0b;}#mermaid-svg-W2H79hgEbxHURLiS .arrowheadPath{fill:#0b0b0b;}#mermaid-svg-W2H79hgEbxHURLiS .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#mermaid-svg-W2H79hgEbxHURLiS .flowchart-link{stroke:#0b0b0b;fill:none;}#mermaid-svg-W2H79hgEbxHURLiS .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-W2H79hgEbxHURLiS .edgeLabel p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-W2H79hgEbxHURLiS .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-W2H79hgEbxHURLiS .labelBkg{background-color:rgba(243.9999999999, 220.9999999998, 255, 0.5);}#mermaid-svg-W2H79hgEbxHURLiS .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#mermaid-svg-W2H79hgEbxHURLiS .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-W2H79hgEbxHURLiS .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-W2H79hgEbxHURLiS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:Microsoft YaHei;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid hsl(220.5882352941, 60%, 88.3333333333%);border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-W2H79hgEbxHURLiS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-W2H79hgEbxHURLiS rect.text{fill:none;stroke-width:0;}#mermaid-svg-W2H79hgEbxHURLiS .icon-shape,#mermaid-svg-W2H79hgEbxHURLiS .image-shape{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-W2H79hgEbxHURLiS .icon-shape p,#mermaid-svg-W2H79hgEbxHURLiS .image-shape p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);padding:2px;}#mermaid-svg-W2H79hgEbxHURLiS .icon-shape .label rect,#mermaid-svg-W2H79hgEbxHURLiS .image-shape .label rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-W2H79hgEbxHURLiS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-W2H79hgEbxHURLiS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-W2H79hgEbxHURLiS :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    原始数据。
    1s 精度,保留 7 天。

    连续查询,定时聚合。
    每 1min 算一次
    avg / max / p99。

    1min 聚合数据。
    保留 1 年。

    1h 聚合数据。
    保留 5 年。

    存储成本。
    原始 7 天 + 1min 1 年 + 1h 5 年。
    远小于全量原始数据留 5 年。

    查询路由。
    查最近 1 小时 → 原始数据。
    查最近 1 月 → 1min 聚合。
    查最近 1 年 → 1h 聚合。

    6.4 跑一遍:从写入到降采样出结果

    下面是一段可以直接复制到 InfluxDB CLI(influx)执行的完整示例(场景:web 服务器 CPU 监控),每一步都给出真实结果。

    — ① 建库 + 两级保留策略:原始数据留 7 天(默认),1min 聚合留 1 年
    CREATE DATABASE monitoring
    CREATE RETENTION POLICY "rp_7d" ON "monitoring" DURATION 7d REPLICATION 1 DEFAULT
    CREATE RETENTION POLICY "rp_1y" ON "monitoring" DURATION 365d REPLICATION 1

    — ② 写入 4 个数据点(行协议:measurement,tag=value field=value timestamp)
    INSERT cpu_usage,host=web1,region=cn value=0.72 1704067200000000000
    INSERT cpu_usage,host=web1,region=cn value=0.85 1704067230000000000
    INSERT cpu_usage,host=web1,region=cn value=0.66 1704067260000000000
    INSERT cpu_usage,host=web2,region=cn value=0.31 1704067200000000000

    — ③ 查原始数据:web1 最近 1 小时的 CPU
    SELECT * FROM "cpu_usage" WHERE "host" = 'web1' AND time > now() – 1h

    ③ 的查询结果(Tag 过滤走索引,只扫 web1 这条时间序列):

    name: cpu_usage
    time host region value
    —- —- —— —–
    1704067200000000000 web1 cn 0.72
    1704067230000000000 web1 cn 0.85
    1704067260000000000 web1 cn 0.66

    — ④ 建连续查询:每 1 分钟自动把原始数据聚合(均值/最大值)写入 rp_1y 的降采样表
    CREATE CONTINUOUS QUERY "cq_cpu_1m" ON "monitoring" BEGIN
    SELECT mean("value") AS "avg_value", max("value") AS "max_value"
    INTO "rp_1y"."cpu_usage_1m"
    FROM "cpu_usage"
    GROUP BY time(1m), "host"
    END

    — ⑤ 等 1 分钟后查降采样结果(数据由连续查询自动生成,不用手工算)
    SELECT * FROM "rp_1y"."cpu_usage_1m" WHERE "host" = 'web1'

    ⑤ 的查询结果(3 个 30s 精度的原始点被聚合成 1 个 1min 点):

    name: cpu_usage_1m
    time host avg_value max_value
    —- —- ——— ———
    1704067200000000000 web1 0.7433333333333334 0.85

    💡 对照理解:第 ③ 步查的是原始精度(每 30s 一个点,只留 7 天);第 ⑤ 步查的是降采样后(每 1min 一个点,留 1 年)——存储量缩到 1/2,且老数据自动过期不用手工清理。查最近 1 小时走原始表、查最近 1 年走聚合表,这就是 6.3 节"查询按时间范围路由到对应精度"的直观体现。

    6.5 InfluxDB vs TDengine vs Prometheus

    维度InfluxDBTDenginePrometheus
    定位 通用时序库 物联网/工业时序 监控告警
    存储 TSM 引擎(LSM 变体) 列存+超级表模型 TSDB(本地存储)
    查询语言 InfluxQL/Flux SQL(兼容) PromQL
    集群 企业版收费 开源集群 联邦/远程存储
    压缩 高 极高(针对时序优化) 中
    适用 通用监控/指标 IoT/车联网/工业 K8s/微服务监控

    七、选型对比:HBase vs 时序库 vs ClickHouse

    7.1 分工表

    维度HBase时序库ClickHouse
    数据模型 KV + 列族 时间序列(metric+tag+field) 列存表
    核心能力 海量 KV 随机读写 时序指标存储+降采样 海量聚合分析
    查询模式 RowKey 点查/scan 时间范围+聚合 任意列聚合
    写入 随机写(LSM) 顺序追加 批量顺序写
    数据量 万亿行 百亿~千亿点 百亿~万亿行
    典型场景 用户画像/消息记录 监控/IoT/行情 报表/日志分析

    7.2 选型决策树

    #mermaid-svg-fZrsJ3WzWgaKz40r{font-family:Microsoft YaHei;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fZrsJ3WzWgaKz40r .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fZrsJ3WzWgaKz40r .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fZrsJ3WzWgaKz40r .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-fZrsJ3WzWgaKz40r .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-fZrsJ3WzWgaKz40r .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fZrsJ3WzWgaKz40r .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fZrsJ3WzWgaKz40r .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fZrsJ3WzWgaKz40r .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fZrsJ3WzWgaKz40r .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fZrsJ3WzWgaKz40r .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fZrsJ3WzWgaKz40r .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-fZrsJ3WzWgaKz40r .marker.cross{stroke:#0b0b0b;}#mermaid-svg-fZrsJ3WzWgaKz40r svg{font-family:Microsoft YaHei;font-size:16px;}#mermaid-svg-fZrsJ3WzWgaKz40r p{margin:0;}#mermaid-svg-fZrsJ3WzWgaKz40r .label{font-family:Microsoft YaHei;color:#333;}#mermaid-svg-fZrsJ3WzWgaKz40r .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-fZrsJ3WzWgaKz40r .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-fZrsJ3WzWgaKz40r .cluster-label span p{background-color:transparent;}#mermaid-svg-fZrsJ3WzWgaKz40r .label text,#mermaid-svg-fZrsJ3WzWgaKz40r span{fill:#333;color:#333;}#mermaid-svg-fZrsJ3WzWgaKz40r .node rect,#mermaid-svg-fZrsJ3WzWgaKz40r .node circle,#mermaid-svg-fZrsJ3WzWgaKz40r .node ellipse,#mermaid-svg-fZrsJ3WzWgaKz40r .node polygon,#mermaid-svg-fZrsJ3WzWgaKz40r .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-fZrsJ3WzWgaKz40r .rough-node .label text,#mermaid-svg-fZrsJ3WzWgaKz40r .node .label text,#mermaid-svg-fZrsJ3WzWgaKz40r .image-shape .label,#mermaid-svg-fZrsJ3WzWgaKz40r .icon-shape .label{text-anchor:middle;}#mermaid-svg-fZrsJ3WzWgaKz40r .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fZrsJ3WzWgaKz40r .rough-node .label,#mermaid-svg-fZrsJ3WzWgaKz40r .node .label,#mermaid-svg-fZrsJ3WzWgaKz40r .image-shape .label,#mermaid-svg-fZrsJ3WzWgaKz40r .icon-shape .label{text-align:center;}#mermaid-svg-fZrsJ3WzWgaKz40r .node.clickable{cursor:pointer;}#mermaid-svg-fZrsJ3WzWgaKz40r .root .anchor path{fill:#0b0b0b!important;stroke-width:0;stroke:#0b0b0b;}#mermaid-svg-fZrsJ3WzWgaKz40r .arrowheadPath{fill:#0b0b0b;}#mermaid-svg-fZrsJ3WzWgaKz40r .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#mermaid-svg-fZrsJ3WzWgaKz40r .flowchart-link{stroke:#0b0b0b;fill:none;}#mermaid-svg-fZrsJ3WzWgaKz40r .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-fZrsJ3WzWgaKz40r .edgeLabel p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-fZrsJ3WzWgaKz40r .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-fZrsJ3WzWgaKz40r .labelBkg{background-color:rgba(243.9999999999, 220.9999999998, 255, 0.5);}#mermaid-svg-fZrsJ3WzWgaKz40r .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#mermaid-svg-fZrsJ3WzWgaKz40r .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-fZrsJ3WzWgaKz40r .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-fZrsJ3WzWgaKz40r div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:Microsoft YaHei;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid hsl(220.5882352941, 60%, 88.3333333333%);border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fZrsJ3WzWgaKz40r .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fZrsJ3WzWgaKz40r rect.text{fill:none;stroke-width:0;}#mermaid-svg-fZrsJ3WzWgaKz40r .icon-shape,#mermaid-svg-fZrsJ3WzWgaKz40r .image-shape{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-fZrsJ3WzWgaKz40r .icon-shape p,#mermaid-svg-fZrsJ3WzWgaKz40r .image-shape p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);padding:2px;}#mermaid-svg-fZrsJ3WzWgaKz40r .icon-shape .label rect,#mermaid-svg-fZrsJ3WzWgaKz40r .image-shape .label rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-fZrsJ3WzWgaKz40r .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fZrsJ3WzWgaKz40r .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fZrsJ3WzWgaKz40r :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    是

    是

    否

    否

    是

    否

    是

    否

    数据是什么?

    带时间戳的指标?
    监控 / IoT / 行情。

    需要降采样 +
    保留策略?

    时序库。
    InfluxDB / TDengine。

    ClickHouse。
    时序数据也能存,聚合强。

    海量 KV 随机读写?
    用户画像 / 消息记录。

    HBase。
    万亿行毫秒点查。

    海量聚合分析?

    ClickHouse。

    MySQL。
    关系型交易。

    一句话:监控指标用时序库(降采样+保留策略),海量 KV 点查用 HBase,海量聚合用 ClickHouse,交易用 MySQL——四者分工。


    八、总结

    8.1 一张图回顾全文

    #mermaid-svg-WBNcru5La4e9rvGx{font-family:Microsoft YaHei;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WBNcru5La4e9rvGx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WBNcru5La4e9rvGx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WBNcru5La4e9rvGx .error-icon{fill:hsl(220.5882352941, 100%, 98.3333333333%);}#mermaid-svg-WBNcru5La4e9rvGx .error-text{fill:rgb(8.5000000002, 5.7500000001, 0);stroke:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-WBNcru5La4e9rvGx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WBNcru5La4e9rvGx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WBNcru5La4e9rvGx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WBNcru5La4e9rvGx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WBNcru5La4e9rvGx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WBNcru5La4e9rvGx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WBNcru5La4e9rvGx .marker{fill:#0b0b0b;stroke:#0b0b0b;}#mermaid-svg-WBNcru5La4e9rvGx .marker.cross{stroke:#0b0b0b;}#mermaid-svg-WBNcru5La4e9rvGx svg{font-family:Microsoft YaHei;font-size:16px;}#mermaid-svg-WBNcru5La4e9rvGx p{margin:0;}#mermaid-svg-WBNcru5La4e9rvGx .label{font-family:Microsoft YaHei;color:#333;}#mermaid-svg-WBNcru5La4e9rvGx .cluster-label text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-WBNcru5La4e9rvGx .cluster-label span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-WBNcru5La4e9rvGx .cluster-label span p{background-color:transparent;}#mermaid-svg-WBNcru5La4e9rvGx .label text,#mermaid-svg-WBNcru5La4e9rvGx span{fill:#333;color:#333;}#mermaid-svg-WBNcru5La4e9rvGx .node rect,#mermaid-svg-WBNcru5La4e9rvGx .node circle,#mermaid-svg-WBNcru5La4e9rvGx .node ellipse,#mermaid-svg-WBNcru5La4e9rvGx .node polygon,#mermaid-svg-WBNcru5La4e9rvGx .node path{fill:#fff4dd;stroke:hsl(40.5882352941, 60%, 83.3333333333%);stroke-width:1px;}#mermaid-svg-WBNcru5La4e9rvGx .rough-node .label text,#mermaid-svg-WBNcru5La4e9rvGx .node .label text,#mermaid-svg-WBNcru5La4e9rvGx .image-shape .label,#mermaid-svg-WBNcru5La4e9rvGx .icon-shape .label{text-anchor:middle;}#mermaid-svg-WBNcru5La4e9rvGx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WBNcru5La4e9rvGx .rough-node .label,#mermaid-svg-WBNcru5La4e9rvGx .node .label,#mermaid-svg-WBNcru5La4e9rvGx .image-shape .label,#mermaid-svg-WBNcru5La4e9rvGx .icon-shape .label{text-align:center;}#mermaid-svg-WBNcru5La4e9rvGx .node.clickable{cursor:pointer;}#mermaid-svg-WBNcru5La4e9rvGx .root .anchor path{fill:#0b0b0b!important;stroke-width:0;stroke:#0b0b0b;}#mermaid-svg-WBNcru5La4e9rvGx .arrowheadPath{fill:#0b0b0b;}#mermaid-svg-WBNcru5La4e9rvGx .edgePath .path{stroke:#0b0b0b;stroke-width:2.0px;}#mermaid-svg-WBNcru5La4e9rvGx .flowchart-link{stroke:#0b0b0b;fill:none;}#mermaid-svg-WBNcru5La4e9rvGx .edgeLabel{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-WBNcru5La4e9rvGx .edgeLabel p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-WBNcru5La4e9rvGx .edgeLabel rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-WBNcru5La4e9rvGx .labelBkg{background-color:rgba(243.9999999999, 220.9999999998, 255, 0.5);}#mermaid-svg-WBNcru5La4e9rvGx .cluster rect{fill:hsl(220.5882352941, 100%, 98.3333333333%);stroke:hsl(220.5882352941, 60%, 88.3333333333%);stroke-width:1px;}#mermaid-svg-WBNcru5La4e9rvGx .cluster text{fill:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-WBNcru5La4e9rvGx .cluster span{color:rgb(8.5000000002, 5.7500000001, 0);}#mermaid-svg-WBNcru5La4e9rvGx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:Microsoft YaHei;font-size:12px;background:hsl(220.5882352941, 100%, 98.3333333333%);border:1px solid hsl(220.5882352941, 60%, 88.3333333333%);border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WBNcru5La4e9rvGx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WBNcru5La4e9rvGx rect.text{fill:none;stroke-width:0;}#mermaid-svg-WBNcru5La4e9rvGx .icon-shape,#mermaid-svg-WBNcru5La4e9rvGx .image-shape{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);text-align:center;}#mermaid-svg-WBNcru5La4e9rvGx .icon-shape p,#mermaid-svg-WBNcru5La4e9rvGx .image-shape p{background-color:hsl(-79.4117647059, 100%, 93.3333333333%);padding:2px;}#mermaid-svg-WBNcru5La4e9rvGx .icon-shape .label rect,#mermaid-svg-WBNcru5La4e9rvGx .image-shape .label rect{opacity:0.5;background-color:hsl(-79.4117647059, 100%, 93.3333333333%);fill:hsl(-79.4117647059, 100%, 93.3333333333%);}#mermaid-svg-WBNcru5La4e9rvGx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WBNcru5La4e9rvGx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WBNcru5La4e9rvGx :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    HBase 与时序库。

    LSM-Tree。

    写:WAL + MemStore
    → Flush → HFile。
    读:MemStore + BlockCache + HFile 合并。
    Compaction 减读放大。
    LSM 用读放大换写极快。

    RowKey 设计。

    三原则:唯一 / 散列 / 短。
    热点规避:加盐 / 哈希 / 反转。
    预分区必做。
    不预分区 = 单 Region 热点。

    时序库。

    metric + tag + field + timestamp。
    tag 建索引,
    高基数别放 tag。
    降采样:1s → 1min → 1h。
    保留策略:老数据自动删。

    选型分工。

    监控指标 → 时序库。
    海量 KV 点查 → HBase。
    海量聚合 → ClickHouse。
    交易 → MySQL。

    8.2 核心要点浓缩(十二条)

  • HBase 定位:海量 KV 随机读写(万亿行、毫秒点查、水平扩展、强一致)——MySQL 存状态、ClickHouse 存聚合、HBase 存海量明细 KV。
  • LSM-Tree 写流程:写 WAL(保命)→ 写 MemStore(快)→ 满刷盘成 HFile → 后台 Compaction 合并——写路径全程顺序 IO,写极快。
  • LSM-Tree 读流程:查 MemStore → BlockCache → 多个 HFile(布隆过滤器排除)→ 合并多版本——读放大是 LSM 的代价,Compaction 缓解。
  • LSM vs B+ 树:LSM 用"读放大+空间放大"换"写极快"——写多读少海量选 LSM,读写均衡选 B+ 树。
  • 数据模型四维:RowKey(唯一+排序)+ 列族(物理分组,1~3 个)+ 列(动态+稀疏)+ 时间戳(多版本)。
  • RowKey 三原则:唯一、散列(防热点)、短(16~100 字节)——RowKey 设计是 HBase 第一设计决策。
  • 热点规避三方案:加盐(写入均匀但范围查询贵)、哈希(完全散列牺牲范围查询)、反转(保留部分范围能力)——点查用哈希,范围用"散列前缀+有序后缀"。
  • 预分区必做:不预分区 = 单 Region 热点 = 写入瓶颈——建表时按 RowKey 分布预切 16~256 个 Region。
  • 时序数据五特点:带时间戳、只追加、按时间范围查、聚合为主、价值随时间衰减——LSM-Tree 天然适配时序写入。
  • 降采样+保留策略:1s 原始留 7 天 → 1min 聚合留 1 年 → 1h 聚合留 5 年——用精度换空间,查询按时间范围路由到对应精度。
  • Tag vs Field:Tag 建索引(查询维度),Field 不建索引(值)——高基数维度(user_id)别放 Tag,索引爆炸。
  • 四者分工:监控指标用时序库(InfluxDB/TDengine),海量 KV 点查用 HBase,海量聚合用 ClickHouse,交易用 MySQL——不是替代,是分工。
  • 📌 最后一句话:HBase 的本质是用 LSM-Tree 把"海量写入"做到极致——写路径全程顺序 IO,读路径用布隆过滤器+Compaction 缓解放大;时序库的本质是用降采样+保留策略把"时间衰减"变成存储红利。RowKey 设计是 HBase 的灵魂(设计错=热点+慢查询),降采样是时序库的灵魂(不降采样=存储爆炸)。选型的智慧在于"把对的数据交给对的引擎"——监控给时序库,明细 KV 给 HBase,聚合给 ClickHouse,交易给 MySQL。


    📌 配套阅读:

    上一篇:《05-03-A-ClickHouse与OLAP详解.md》

     B 篇:《05-04-B-HBase与时序库面试与生产事故实战.md》

    下一篇:《05-05-A-对象存储与文件服务详解.md》

    如果这篇文章对你有帮助,欢迎点赞、收藏、关注!🚀

    赞(0)
    未经允许不得转载:171主机测评 » 05-04-A-HBase与时序库详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址