HTAP 与 OLTP/OLAP 融合

从行存储与列存储原理出发,深入讲解 HTAP(混合事务/分析处理)架构设计、OLTP 与 OLAP 融合方案,以及 ClickHouse、TiFlash 等实时分析引擎的工程实践。

传统数据库架构将在线事务处理(OLTP)和分析处理(OLAP)分离:核心业务数据存储于 MySQL/PostgreSQL 等行存数据库,批量导入数据仓库进行报表分析。这种架构存在数据延迟、架构复杂等问题。HTAP(Hybrid Transactional/Analytical Processing)旨在用一套系统同时高效处理两种负载。本文从存储引擎原理到工程实践全面解析 HTAP。


1. OLTP vs OLAP 的本质差异

维度OLTPOLAP
数据操作单行/小范围增删改查大批量聚合分析
查询特征点查、短事务全表扫描、复杂 JOIN
数据状态当前最新数据历史快照
响应时间< 100ms秒级 ~ 分钟级
并发量数千 ~ 数万 QPS数十并发
存储模型行存储列存储
典型系统MySQL、PostgreSQLClickHouse、Snowflake

2. 行存储 vs 列存储

2.1 行存储(Row-Oriented)

磁盘布局(按行组织):
Page 0: [id=1, name=Alice, age=30, city=BJ] [id=2, name=Bob, age=25, city=SH] ...
Page 1: [id=1001, name=...] ...

适合:SELECT * FROM users WHERE id = 1    (一行全部列在一起)
不适:SELECT AVG(age) FROM users          (需要跳过 name/city,读放大)

2.2 列存储(Column-Oriented)

磁盘布局(按列组织):
id 文件:    [1, 2, 3, 4, 5, ...]
name 文件:  [Alice, Bob, Carol, ...]
age 文件:   [30, 25, 35, 28, ...]
city 文件:  [BJ, SH, GZ, SZ, ...]

适合:SELECT AVG(age) FROM users          (只读 age 列,顺序 IO)
不适:SELECT * FROM users WHERE id = 1   (需读取多个列文件合并)

2.3 列存储的优化技术

技术原理收益
数据压缩同类型数据连续,压缩比高存储量减少 70%~90%
向量化执行SIMD 指令一次处理一批数据CPU 利用率提升
** Zone Maps**每列块记录 min/max快速跳过不满足条件的块
延迟物化先过滤再组装完整行减少不必要的数据读取

3. 传统分离架构

3.1 ETL 数据管道

┌──────────┐    ETL(定时)    ┌──────────┐    SQL    ┌─────────┐
│ 业务库    │ ──► 抽取/转换/加载 ──► │ 数据仓库  │ ──►│ BI报表  │
│ MySQL/   │    (T+1 延迟)    │ Hive/    │    │ Grafana │
│ PostgreSQL│                 │ ClickHouse│    │ Tableau │
└──────────┘                 └──────────┘    └─────────┘

痛点:

  • 数据延迟 T+1,无法实时分析
  • ETL 管道复杂,维护成本高
  • 两套存储,数据冗余
  • MySQL 大查询拖垮 OLTP

3.2 实时同步方案

-- Canal/Debezium 实时 CDC 同步
MySQL Binlog ──► Kafka ──► Flink/Spark ──► ClickHouse

延迟降低至秒级,但架构更复杂。

4. HTAP 架构方案

4.1 方案一:单系统行/列双存储(TiDB TiFlash)

TiDB Server ──► TiKV (行存, OLTP)     ◄── 实时复制 ──► TiFlash (列存, OLAP)
                (Raft 协议)                          (Raft Learner)
                                                     
查询路由器根据 SQL 特征自动选择存储:
  - SELECT id, name WHERE id = 100 → TiKV(行存)
  - SELECT COUNT(*), AVG(price) GROUP BY category → TiFlash(列存)

4.2 方案二:内存列存加速(Oracle In-Memory)

磁盘:行存储(Buffer Cache)
内存:列存储(In-Memory Column Store)

事务先写入行存储,后台将变更同步到内存列存。
分析查询走内存列存,实现近实时分析。

4.3 方案三:计算存储分离(Snowflake、Databricks)

存储层:S3 对象存储(列存文件)
计算层:弹性 warehouses(按需启动)

数据以列存格式持久化在 S3,查询时拉取所需列到本地缓存。
完全分离 OLTP(外部 CDC 导入)和 OLAP。

4.4 方案对比

方案代表产品OLTP 延迟OLAP 延迟架构复杂度
行+列双引擎TiDB + TiFlash< 10ms< 100ms
内存列存Oracle IM< 10ms< 50ms
计算存储分离SnowflakeN/A(外部导入)< 1s
ETL 管道Hive/传统数仓N/AT+1 ~ 小时

5. ClickHouse 实时分析实战

5.1 核心特性

-- 建表(MergeTree 引擎,列存储)
CREATE TABLE events (
    event_date Date,
    user_id UInt64,
    event_type LowCardinality(String),
    properties String CODEC(ZSTD(1))
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_type, event_date, user_id);

-- 向量化聚合查询
SELECT 
    event_type,
    count() AS total,
    uniqExact(user_id) AS unique_users,
    avg(length(properties)) AS avg_props_len
FROM events
WHERE event_date >= today() - 7
GROUP BY event_type
ORDER BY total DESC;

5.2 实时同步架构

MySQL ──► Canal/Debezium ──► Kafka ──► ClickHouse Kafka Engine

ClickHouse Kafka Engine 直接消费 Kafka:
CREATE TABLE events_queue (
    user_id UInt64,
    event_type String,
    ts DateTime
) ENGINE = Kafka()
SETTINGS kafka_broker_list = 'kafka:9092',
         kafka_topic_list = 'events',
         kafka_group_name = 'ch_consumer',
         kafka_format = 'JSONEachRow';

-- Materialized View 自动将 Kafka 数据写入 MergeTree
CREATE MATERIALIZED VIEW events_mv TO events AS
SELECT * FROM events_queue;

5.3 ClickHouse 性能优化

优化点说明
分区裁剪PARTITION BY 让查询只读目标分区
主键排序ORDER BY 列保证数据有序,快速过滤
列裁剪只读取所需列
向量化SIMD 加速批量数据处理
物化视图预聚合常用查询
数据类型使用 Int 替代 String、LowCardinality 压缩

6. TiDB HTAP 实战

6.1 TiFlash 架构

                                    SQL 解析 + 优化器
                                           │
                    ┌──────────────────────┼──────────────────────┐
                    │                      │                      │
                    ▼                      ▼                      ▼
              TiKV Region              TiKV Region            TiFlash Segment
              (行存 Leader)             (行存 Follower)        (列存 Learner)
                                                                 
Raft Log 复制:Leader(行存) ──► Follower(行存) ──► Learner(列存, TiFlash)
                                    
优化器根据代价模型选择:
  - 点查、短事务 → 行存 TiKV
  - 分析查询、聚合 → 列存 TiFlash

6.2 智能路由

-- TiDB 自动选择,无需关心底层
SELECT * FROM orders WHERE order_id = 100;  -- 路由到 TiKV

SELECT region, COUNT(*), AVG(amount) 
FROM orders 
GROUP BY region;  -- 优化器自动路由到 TiFlash

-- 强制指定(不推荐)
SELECT /*+ read_from_storage(tiflash[orders]) */ * FROM orders;

6.3 MPP 查询加速

TiFlash 支持 MPP(Massively Parallel Processing):

SELECT region, COUNT(*), SUM(amount)
FROM orders o JOIN customers c ON o.customer_id = c.id
GROUP BY region;

执行计划:
-  JOIN 和聚合下推到多个 TiFlash 节点并行执行
- 节点间 Shuffle 数据
- 局部聚合后汇总
- 比单节点分析快 10~100 

7. HTAP 设计要点

7.1 数据一致性

级别延迟实现方式
强一致0TiFlash Raft Learner 同步(等待 apply)
最终一致毫秒级Raft Learner 异步 apply
近实时秒级Canal + Kafka + ClickHouse
准实时分钟级定时 ETL Batch

7.2 资源隔离

单机部署 HTAP 的核心挑战:分析查询占用大量 CPU/IO,影响事务。

解决方案:
1. 物理隔离:OLTP 和 OLAP 跑在不同节点(TiKV/TiFlash 分离)
2. 资源组限制:CPU/内存配额(TiDB Resource Control)
3. 优先级调度:OLTP 查询优先级高于 OLAP
4. 读写分离:OLAP 路由到只读副本

8. 选型建议

场景推荐方案理由
MySQL 已有业务 + 实时报表TiDB + TiFlash无缝迁移,智能路由
纯分析、日志/事件分析ClickHouse极致列存性能
复杂数据仓库、多数据源Snowflake/Databricks弹性计算,生态成熟
Oracle 存量 + 分析加速Oracle In-Memory无需改架构
中小规模、预算有限PostgreSQL + 物化视图 + 读写分离够用就好

9. 总结

HTAP 代表了数据库架构的演进方向:

传统架构:                 HTAP 架构:
OLTP ──► ETL ──► OLAP     OLTP ═══ 实时复制 ═══ OLAP
  │        │       │        │                      │
  ▼        ▼       ▼        ▼                      ▼
MySQL   小时延迟  Hive     TiDB ─── TiFlash      ClickHouse
                     │      (统一系统)              (列存消费)      
                   T+1      毫秒延迟                秒级延迟

HTAP 的核心价值不是完全消除延迟,而是在可接受的架构复杂度下,让分析负载不再干扰事务处理,同时大幅降低数据管道的维护成本。随着 TiDB、ClickHouse 等系统的成熟,HTAP 正从概念走向大规模生产实践。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「数据库」更多文章

  1. 备份恢复与高可用方案
  2. 数据库性能监控与诊断
  3. NewSQL 选型对比