Apache Doris HTAP 实战教程:PostgreSQL 实时分析从零搭建

PostgreSQL + Apache Doris 构建 HTAP 架构,让事务和分析各自发挥所长。本教程从零开始,带你搭建一套完整的实时分析链路:PostgreSQL 负责事务写入,Apache Doris 负责分析查询,全程含可跑通的代码。

关键词:Apache Doris · PostgreSQL · HTAP · 实时分析 · Flink CDC · MOW 引擎 · 数据同步 · 存算分离


前言:为什么 PostgreSQL 的分析查询越来越慢?

很多团队的工作流是这样的:业务数据写进 PostgreSQL,BI 报表直接查 PostgreSQL。一开始还行,但随着数据量上来,慢查询让 DBA 头疼不已。PostgreSQL 本身的 MVCC 机制会积累大量 Dead Tuples,即使是简单的 COUNT 查询也要扫描大量冗余数据。

那能不能把分析任务从 PostgreSQL 剥离出来?答案就是 HTAP 架构:PostgreSQL 专管事务,Apache Doris 专管分析,两者通过实时同步打通。

这套教程会带你从零搭建整个链路。


第 1 步:环境准备

你至少需要以下组件:

组件 版本要求 用途
PostgreSQL 12+ 事务数据库(写入端)
Apache Doris 2.1+ 分析数据库(读取端)
Flink 1.18+ CDC 数据同步
Flink CDC Connector 3.0+ PostgreSQL → Doris 实时同步

以下假设 PostgreSQL 和 Doris 均已启动并能正常连接。


第 2 步:PostgreSQL 开启 WAL 日志

Flink CDC 通过读取 PostgreSQL 的 WAL(Write-Ahead Log)来捕获增量变更,所以需要先开启逻辑复制:

sql 复制代码
-- 1. 修改 postgresql.conf,重启生效
-- wal_level = logical
-- max_wal_senders = 4
-- max_replication_slots = 4
​
-- 2. 创建复制用户
CREATE ROLE flink_cdc WITH LOGIN PASSWORD 'your_password' REPLICATION;
GRANT CONNECT ON DATABASE mydb TO flink_cdc;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO flink_cdc;
​
-- 3. 创建发布(Publication),选择需要同步的表
CREATE PUBLICATION doris_pub FOR TABLE orders, users, products;

关键点wal_level = logical 是必须的,否则 Flink CDC 无法读取变更数据。


第 3 步:在 Apache Doris 中创建目标表

在 Doris 中创建与 PostgreSQL 对应的分析表。这里以订单表为例:

sql 复制代码
-- 创建 Doris 数据库
CREATE DATABASE IF NOT EXISTS htap_demo;
​
-- 订单明细表,使用 MOW(Merge-On-Write)引擎
CREATE TABLE IF NOT EXISTS htap_demo.orders (
  order_id        BIGINT,              -- 订单 ID
  user_id         BIGINT,              -- 用户 ID
  product_id      BIGINT,              -- 商品 ID
  order_amount    DECIMAL(18, 2),      -- 订单金额
  order_status    VARCHAR(32),         -- 订单状态:pending/shipped/completed
  create_time     DATETIME,            -- 创建时间
  update_time     DATETIME             -- 更新时间
) ENGINE = OLAP
UNIQUE KEY(order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 10
PROPERTIES (
   "replication_allocation" = "tag.location.default: 1",
   "enable_unique_key_merge_on_write" = "true"  -- MOW 引擎,支持实时更新
);
​
-- 用户表
CREATE TABLE IF NOT EXISTS htap_demo.users (
  user_id     BIGINT,
  user_name   VARCHAR(64),
  city        VARCHAR(64),
  create_time DATETIME
) ENGINE = OLAP
UNIQUE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 8
PROPERTIES (
   "replication_allocation" = "tag.location.default: 1",
   "enable_unique_key_merge_on_write" = "true"
);

为什么用 MOW(Merge-On-Write)引擎?

  • 更新数据秒级可见,无需等后台 Compaction
  • 写入时即完成合并和排序,查询时无需临时计算
  • 支持完整的 DML 操作:INSERT / DELETE / UPDATE / UPSERT

这是整条链路的核心。Flink CDC 监听 PostgreSQL 的 WAL 变更,实时写入 Doris。

sql 复制代码
-- Flink SQL 任务:PostgreSQL → Doris 实时同步
-- 提交到 Flink 集群运行
​
-- (1) 注册 PostgreSQL CDC 源表
CREATE TABLE pg_orders_source (
  order_id        BIGINT,
  user_id         BIGINT,
  product_id      BIGINT,
  order_amount    DECIMAL(18, 2),
  order_status    VARCHAR(32),
  create_time     TIMESTAMP,
  update_time     TIMESTAMP,
   PRIMARY KEY(order_id) NOT ENFORCED
) WITH (
   'connector' = 'postgres-cdc',
   'hostname' = 'your-pg-host',
   'port' = '5432',
   'username' = 'flink_cdc',
   'password' = 'your_password',
   'database-name' = 'mydb',
   'schema-name' = 'public',
   'table-name' = 'orders',
   'slot.name' = 'doris_orders_slot',
   'decoding.plugin.name' = 'pgoutput'
);
​
-- (2) 注册 Doris Sink 表
CREATE TABLE doris_orders_sink (
  order_id        BIGINT,
  user_id         BIGINT,
  product_id      BIGINT,
  order_amount    DECIMAL(18, 2),
  order_status    VARCHAR(32),
  create_time     TIMESTAMP,
  update_time     TIMESTAMP
) WITH (
   'connector' = 'doris',
   'fenodes' = 'your-doris-fe:8030',
   'table.identifier' = 'htap_demo.orders',
   'username' = 'root',
   'password' = '',
   'sink.properties.format' = 'json',
   'sink.properties.read_json_by_line' = 'true',
   'sink.enable-delete' = 'true'   -- 开启 DELETE 同步
);
​
-- (3) 执行同步
INSERT INTO doris_orders_sink SELECT * FROM pg_orders_source;

增量同步策略建议

数据类型 同步策略 延迟
交易订单、状态变更 实时 CDC ≤ 10 秒
用户基础信息 定时增量(5 分钟) ≤ 5 分钟
全量初始化 DataX / 一次性同步 一次性

第 5 步:验证同步效果

同步启动后,在 PostgreSQL 写入一条数据,几秒钟后在 Doris 中查询验证:

sql 复制代码
-- PostgreSQL 写入
INSERT INTO orders VALUES (1001, 2023, 5001, 199.00, 'pending', NOW(), NOW());
​
-- Doris 中查询(延迟 ≤ 10 秒即可查到)
SELECT * FROM htap_demo.orders WHERE order_id = 1001;

再试一条 UPDATE:

sql 复制代码
-- PostgreSQL 更新状态
UPDATE orders SET order_status = 'shipped', update_time = NOW() WHERE order_id = 1001;
​
-- Doris 中验证(MOW 引擎秒级可见)
SELECT order_id, order_status, update_time 
FROM htap_demo.orders WHERE order_id = 1001;
-- 预期:order_status 变为 'shipped'

第 6 步:在 Doris 中执行分析查询

数据同步就绪后,分析查询全部交给 Doris:

sql 复制代码
-- 1. 实时运营看板:各城市近 1 小时订单量
SELECT
  u.city,
   COUNT(o.order_id)   AS order_count,
   SUM(o.order_amount) AS total_amount
FROM htap_demo.orders o
JOIN htap_demo.users u ON o.user_id = u.user_id
WHERE o.create_time > NOW() - INTERVAL 1 HOUR
GROUP BY u.city
ORDER BY total_amount DESC;
​
-- 2. 多维分析:各商品近 7 天每日销量趋势
SELECT
  o.product_id,
  DATE_TRUNC('day', o.create_time) AS dt,
   COUNT(*) AS order_cnt,
   AVG(o.order_amount) AS avg_amount
FROM htap_demo.orders o
WHERE o.create_time > NOW() - INTERVAL 7 DAY
GROUP BY o.product_id, dt
ORDER BY dt, order_cnt DESC;

这些查询原本在 PostgreSQL 中可能会消耗大量 CPU 并影响事务性能,现在完全由 Doris 承接。


第 7 步:存储优化 ------ 让热数据快、冷数据省

Doris 支持分层存储策略:

sql 复制代码
-- 存算分离模式:冷数据自动沉降到对象存储
ALTER TABLE htap_demo.orders
SET (
   "storage_policy" = "hot_cold_policy",
   "storage_cooldown_time" = "2026-01-01 00:00:00"  -- 该时间之前的数据沉降
);
​
-- 存算一体模式:冷数据迁移到 HDD
ALTER TABLE htap_demo.orders
MODIFY PARTITION p202501 SET ("storage_medium" = "HDD");

核心思路:热数据吃 SSD,冷数据吃廉价存储。在 TB 级日志或历史订单场景中,存储成本可以显著降低。


架构总结

lua 复制代码
PostgreSQL(TP 事务)       Apache Doris(AP 分析)
      |                             |
  写入 & 更新                     只读分析
      |                             |
      +--- Flink CDC ---> 实时同步 ---+
            延迟 ≤ 10s
  • PostgreSQL:只干事务的活,CPU 和内存不再被分析查询挤占
  • Apache Doris:向量化引擎 + MOW 更新 + 分层存储,查询快到亚秒级
  • Flink CDC:无侵入式监听 WAL,不增加 PG 的写入负担

常见问题

Q:同步延迟能控制在多少? A:交易类数据通常 ≤ 10 秒;低频数据(如用户资料)可配置 5 分钟定时增量。

Q:MOW 引擎和普通 Unique Key 有什么区别? A:MOW 在写入时即完成合并,更新秒级可见;普通 Unique Key 依赖后台 Compaction,查询时需要合并增量数据,延迟更高。

Q:生产环境推荐怎么规划资源? A:PostgreSQL 保持原有规格不变;Doris 3 节点起(FE x1 + BE x3),根据分析查询量线性扩容 BE 节点。


扩展阅读


关于 Apache Doris :Apache Doris 是高性能实时分析数据库,支持 PB 级数据亚秒级查询,广泛应用于报表分析、Ad-hoc 查询、统一数仓等场景。SelectDB 是 Apache Doris 的商业化公司,提供企业级支持和云服务。欢迎加入 Doris 社区 交流更多实践。

相关推荐
番茄炒鸡蛋加糖21 小时前
Spring 事务传播机制 & 事务失效场景
java·后端·spring
SelectDB21 小时前
SelectDB search() 实战教程:从 Elasticsearch 迁移到一条 SQL 搞定搜索与分析
后端
SelectDB21 小时前
Apache Doris / SelectDB 全栈实战教程:从 ClickBench 全球登顶到 AI Native 部署落地
后端
SelectDB21 小时前
SelectDB 实战教程:从部署到 AI 混合检索的完整实践
后端
qq_171538851 天前
Spring TransactionSynchronizationManager:事务同步的幕后指挥官
java·后端·spring
Oneslide1 天前
ES 7.17 APM 致命坑:@timestamp 被识别为 text,彻底解释为什么必须升级 8.x
后端
SimonKing1 天前
Spring Boot 集成 OnlyOffice,5 分钟搞定 Word/Excel 在线编辑
java·后端·程序员
明月_清风1 天前
🌐 多链生态对比:EVM vs Solana vs Sui,开发者怎么选?
后端·web3
swipe1 天前
14|(前端转全栈)商品详情高频访问怎么扛?Redis Cache Aside 实战
前端·后端·面试