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+ 树
| 写入 | 顺序写(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)
四个维度:
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
| 定位 | 通用时序库 | 物联网/工业时序 | 监控告警 |
| 存储 | TSM 引擎(LSM 变体) | 列存+超级表模型 | TSDB(本地存储) |
| 查询语言 | InfluxQL/Flux | SQL(兼容) | PromQL |
| 集群 | 企业版收费 | 开源集群 | 联邦/远程存储 |
| 压缩 | 高 | 极高(针对时序优化) | 中 |
| 适用 | 通用监控/指标 | IoT/车联网/工业 | K8s/微服务监控 |
七、选型对比:HBase vs 时序库 vs ClickHouse
7.1 分工表
| 数据模型 | 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 的本质是用 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》
如果这篇文章对你有帮助,欢迎点赞、收藏、关注!🚀



