80TB电商数据迁移实录:从PostgreSQL分析困境到Apache Doris架构突围

发布时间:2026/8/4 1:50:28
80TB电商数据迁移实录:从PostgreSQL分析困境到Apache Doris架构突围 去年我们帮助一个电商团队完成了从 PostgreSQL 到 Apache Doris 的迁移。他们的业务数据规模达到 80TB已经为此搭建了三套独立的系统来分别支撑仪表盘、商品搜索和推荐向量服务。三个月后团队发现自己在调试各系统之间的数据同步问题上花费的时间比开发新功能还多。最终我们将所有业务收敛到 Apache Doris 一套系统上。做这个决定的核心理由很简单维护一套经过验证的系统比维护三套勉强拼凑的系统要省心得多。这不是一个关于技术选型优劣的泛泛讨论而是一个关于在数据规模增长到某个临界点后如何正确识别架构瓶颈并做出有效应对的真实复盘。你的技术栈永远不应该比业务实际能够运维的复杂度更高。每增加一个系统就意味着多出一份部署、监控、调试、值班和招聘专业人员的成本。目标是找到适合当前规模的最小可用基础设施。但首先你需要确认自己是否真的遇到了一个值得解决的问题。一、如何判断 PostgreSQL 是否真的遇到了瓶颈1.1 缓慢逼近的性能天花板PostgreSQL 的性能问题从来不会突然爆发它们总是以不易察觉的方式缓慢积累。团队通常会在每个阶段尝试最直接的解决方案添加索引、做分区、建反范式表、用物化视图、增加只读副本或者引入 Citus 这样的分片工具。每一步都带来了暂时的缓解但系统也变得越来越复杂、越来越难以扩展。最终团队会意识到一个根本问题PostgreSQL 是为单机设计的而不是为大规模分布式分析设计的。以下是一些需要警惕的信号信号典型表现介入阈值仪表盘延迟原本 2 秒返回的查询现在需要 20 秒相同查询出现超过 10 倍的性能退化查询超时日志中出现 statement timeout分析类查询每小时超时超过 5 次只读副本膨胀为分析负载不断添加只读副本超过 3 个只读副本专门用于分析大表顺序扫描EXPLAIN ANALYZE 显示 Seq Scan在超过百万行的表上出现全表扫描复制延迟分析负载高峰时期只读副本落后于主库仪表盘刷新期间延迟超过 5 秒磁盘持续紧张存储扩容成为常规应急操作频繁进行存储容量紧急扩容以下查询可以帮助你快速检查业务库中的全表扫描情况SELECT schemaname, relname, seq_scan, seq_tup_read, idx_scan, idx_tup_fetch, CASE WHEN seq_scan 0 THEN seq_tup_read / seq_scan ELSE 0 END as avg_rows_per_seq_scan FROM pg_stat_user_tables WHERE seq_scan 100 AND seq_tup_read / GREATEST(seq_scan, 1) 100000 ORDER BY seq_tup_read DESC LIMIT 10;如果这个查询返回了平均每次顺序扫描超过 10 万行的表说明你的分析查询正在进行大量全表扫描而列式存储处理这类查询的效率通常是行式存储的 10 倍以上。1.2 为什么只读副本解决不了根本问题出现这些警告信号后很多团队的第一反应是增加只读副本。但这样做并不能解决问题。只读副本解决的是并发问题而不是查询性能问题。根本原因在于 OLTP 数据库与 OLAP 数据库在架构上存在本质差异而这种差异是任何数量的只读副本都无法弥补的。行存储与列存储的根本差异。PostgreSQL 按行存储数据这在检索完整记录时非常高效。但当仪表盘查询从一张 50 列表格中只选择 2 列时数据库仍然需要从磁盘读取完整的行然后丢弃未使用的列。这意味着实际扫描的数据量远远超过了查询真正需要的数据量。列式数据库按列分别存储数据查询时只读取需要的列这对于分析型负载来说效率高得多。列式布局还能实现更高的压缩比通常在 5 到 10 倍之间而行式存储的压缩比大约只有 2 到 3 倍因为相邻的值共享相同的数据类型。逐行处理与向量化执行的差异。PostgreSQL 通过执行器逐行处理数据每一行都要经过表达式求值、谓词检查和聚合计算。分析型数据库使用向量化执行一次处理 1000 到 4000 个值的批次利用 CPU 的 SIMD 指令在单次操作中完成对整个列的计算。扫描一千万行数据的查询向量化执行比逐行处理快 10 到 50 倍。单节点规划与分布式规划的差异。PostgreSQL 的查询优化器针对单机进行优化一个查询只能在一台机器上运行。你不能把一个分析查询并行分发到多个只读副本上执行。只读副本能让你同时运行更多的查询但每个单独的查询并不会变得更快。分析型数据库使用分布式查询规划器将工作负载拆分到多个节点上。扫描 1TB 数据的查询会在 10 个节点上同时执行每个节点处理 100GB然后在协调节点合并结果。对比维度PostgreSQL (OLTP)分析型数据库 (OLAP)存储布局行式存储列式存储列选择性读取所有列只读取查询涉及的列执行模型逐行处理向量化批处理查询规划单节点优化器分布式查询规划器并行能力受限单查询单节点完整单查询跨多节点压缩比2-3 倍5-10 倍无论增加多少只读副本都无法弥合这个架构层面的鸿沟。你需要的是一个真正的分析型数据库。但在选择替代方案之前你需要先理解一件事你从 PostgreSQL 获得的能力可能比你意识到的要多得多。二、你可能不知道自己正在使用 PostgreSQL 的哪些实时分析能力2.1 PostgreSQL 不只是 OLTP 数据库很多团队始终将 PostgreSQL 视为 OLTP 数据库但实际上已经在不知不觉中把它用作了实时分析引擎。在数据库世界中有两个众所周知的极端OLTP 以高并发事务、行级操作和亚毫秒级延迟为特征批处理分析以大规模数据转换、分钟到小时级的延迟和高吞吐量为特征。两者之间是实时分析要求数据的新鲜度达到亚秒级且数据立即可用。PostgreSQL 恰好位于 OLTP 和实时分析之间的位置。因为你把它归为 OLTP所以很容易忽略那些实际上非常关键的实时分析能力。亚秒级数据新鲜度。你的只读副本通常落后于主库不到 1 秒。仪表盘显示的是当前数据而不是 10 分钟之前的数据。对于业务决策来说这种实时性具有不可替代的价值。实时更新。订单状态从待支付变更为已发货时执行一条 UPDATE 语句变更立即反映在分析结果中。无需批处理任务无需等待下一个 ETL 窗口。如果新的分析系统不支持更新整个数据管道就需要重构。轻量级事务性 ETL。执行 INSERT INTO summary_table SELECT ... FROM orders GROUP BY ... 这个操作要么完全成功要么完全失败。部分写入永远不会破坏你的聚合数据。这种事务性保证使数据管道维护变得可预期。多表关联查询。BI 查询在一个 SQL 中关联订单表、用户表、商品表和物流表。查询优化器自动处理无需考虑是否支持多表 JOIN。如果新的分析系统在 JOIN 能力上存在短板大量现有的 BI 报表将无法迁移。全文搜索。使用 tsvector 和 tsquery 搜索日志消息、商品描述和用户评论不需要额外部署一套独立的搜索集群。这省去了跨系统数据同步的麻烦。向量搜索。通过 pgvector运行语义搜索和 AI 驱动的功能。嵌入向量与关系型数据存储在一起不需要额外引入独立的向量数据库。数据的自然关联关系得以保留。这六项能力你很可能已经习以为常了直到迁移之后才发现它们的可贵。国内某零售团队就经历过这样的教训他们的库存仪表盘在新分析系统上出了问题因为新系统不支持 UPDATE 操作。他们不得不重建整个数据管道用删除加重新插入的方式替代更新操作。原计划两周的迁移拖成了两个月。大多数分析型数据库至少会牺牲上述能力中的一项。如果你知道哪些能力对自己是必需的这可以接受如果你是在迁移之后才发现那就会很痛苦。2.2 其他系统的取舍在评估替代方案时了解市场上其他系统能提供什么、不能提供什么是至关重要的。以 Snowflake、Databricks、BigQuery 为代表的批处理数仓擅长大规模历史分析和复杂数据转换生态完善。但在实时数据新鲜度方面存在明显短板数据延迟通常在分钟到小时级别。它们通常不内置文本搜索和向量搜索能力需要额外集成独立的搜索系统。以 ClickHouse、Druid、Pinot 为代表的实时分析数据库在仅追加工作负载上查询速度极快已经在 Uber 和 Cloudflare 等公司验证了处理数十亿事件的能力。但它们的事务支持有限更新和删除操作受限或效率低下。多表关联 JOIN 是它们的弱项更倾向于使用反范式化的单表查询。大多不内置全文搜索和向量搜索。如果你的业务需要亚秒级数据新鲜度和实时更新能力批处理数仓方案就会被排除。如果你需要事务支持和强关联查询能力大部分实时分析数据库也无法单独胜任。剩下的选择只有两条路要么组合使用实时分析数据库和批处理数仓要么选择一个同时支持以上全部六项能力的全功能实时分析数据库。三、为什么最终选择了 Apache Doris3.1 PostgreSQL 原生能力在 Doris 中的对应实现Doris 的设计目标之一就是保留那些 PostgreSQL 用户真正依赖的能力。以下是六项核心能力的对应实现亚秒级数据新鲜度。数据写入后数秒内即可查询不需要等待批处理 ETL 窗口。对于物流补货场景延迟要求通常在 1 到 2 秒内数据必须可见。在大多数场景下Doris 能在 10 秒内完成数据可见。实时更新。Unique Key 模型使 UPDATE 和 DELETE 按预期方式工作变更在数秒内可见。Doris 的 Merge-on-Write 模式结合 Delete Bitmap 和 Primary Index 技术在写入阶段为旧数据打上删除标记查询时直接跳过已删除行无需实时计算。补货业务、库存管理、订单处理和物流轨迹追踪都需要这种实时更新能力。轻量级事务性 ETL。ACID 支持保证了 INSERT INTO SELECT 要么完全成功要么完全失败。在菜鸟的实践中Doris 的实时更新能力确保了物流全流程状态变更数据的准确性和及时性补货业务决策基于最新的库存状态避免了缺货或过量采购。多表关联查询。基于成本的优化器确保了复杂关联查询的稳定性能。菜鸟仓内数据产品的包裹生产进度监控场景涉及多张亿级别大表的 JOIN 和大量 AD-HOC 查询迁移后平均查询响应时间降低了 72%。复杂场景下的多表关联聚合查询通常在 1 秒内返回极复杂场景也能在 4 到 5 秒内完成。全文搜索。内置倒排索引和 BM25 排序不需要额外维护一套独立的搜索集群。菜鸟的物流轨迹查询和包裹状态追踪场景受益于此。向量搜索。内置向量索引语义搜索不需要额外的向量数据库。商品推荐和嵌入向量分析可以在同一个系统中完成。Doris 从 0 开始在菜鸟落地逐步验证和推广到如今已经部署了 25 个以上集群、上万核的规模覆盖 3 个地域整个迁移过程未发生一起线上故障。菜鸟的实时数据架构已经逐步收敛Doris 成为 OLAP 分析的最优选型。3.2 架构之外的额外收益Doris 除了提供能力对等的功能之外还解决了几个随着 PostgreSQL 分析负载增长而逐渐暴露的运维难题。存储成本优化。Doris 的列式存储和 5 到 10 倍的压缩比显著降低了存储成本。在菜鸟的包裹生产进度场景中迁移到 Doris 后存储成本直接降低了 90%。对于电商业务历史数据清理后可以释放出可观的存储空间尤其是对于云上资源来说云资源成本较为昂贵这样做可以极大降低存储成本将预算投入到更重要的业务中。高并发点查能力。Doris 的单表主键查询 QPS 可达 1000 到 2000查询响应时间在几十毫秒到 100 到 200 毫秒之间。这得益于主键索引技术和 LSM tree 存储结构的协同作用能够快速定位和检索数据。在菜鸟的快递包裹生产进度场景中点查能力直接支撑了仓库生产监控的实时性需求。运维效率提升。将一个三系统拼凑的架构收敛为单一 Doris 集群后每减少一个系统就少了一套需要监控的组件、少了一条凌晨需要调试的集成链路、少了一家需要谈判的供应商。运维复杂度从三套独立系统的管理收敛为统一平台的管理这是架构收敛带来的长期红利。四、迁移方案与实施路径4.1 迁移方式的选型矩阵Doris 提供了多种从 PostgreSQL 迁移数据的方案可以根据数据量、同步时效性和是否需要 CDC 进行选择。方案适用场景同步模式是否支持整库是否支持增量Multi-Catalog一次性迁移、即席查询离线按需通过 SQL 实现否Flink Doris Connector (CDC)实时全量 增量同步实时支持支持Streaming JobDoris 内置持续同步流式持续支持支持第三方工具已有同步平台、可视化运维离线/实时支持视工具而定如果需要在不引入外部计算引擎的情况下完成迁移推荐使用 Multi-Catalog 或 Streaming Job。如果需要实时增量同步推荐使用 Flink Doris Connector 配合 CDC或直接使用 Doris 内置的 Streaming Job。4.2 数据同步策略与细节数据同步是保障分析数据准确性与实时性的核心环节。全量同步阶段用于初始化场景通过 Multi-Catalog 将 PostgreSQL 表映射为外表后使用 CTAS 一步建表并导入。这种方式适合一次性大规模迁移不需要手动在 Doris 端创建和源端一致的表结构避免了繁琐的 DDL 转换工作。增量同步阶段针对业务数据的实时变动。可以通过 Flink CDC 捕获 PostgreSQL 中的 INSERT、UPDATE、DELETE 操作日志实时传输至 Doris。Flink CDC 支持断点续传和数据去重保证增量数据的完整性与一致性。一个容易忽略的细节是 DDL 变更的同步。源端 PostgreSQL 的表结构发生变化时需要同步更新 Doris 端的表定义否则同步链路会中断。通过成熟的 CDC 工具可以自动捕获 DDL 变更并在 Doris 端执行保证业务变更能够稳定进行。4.3 核心验证与灰度迁移策略菜鸟在 Doris 推广过程中积累了一套可复用的验证方法。他们选择了一个核心场景——仓内数据产品使用频率最高的包裹生产进度监控而不是选择边缘场景做验证。理由是如果在最重要的核心场景都无法验证通过基本不可能推动业务侧做后续的迁移。这个场景是多表级联的 AD-HOC 场景涉及众多维度指标组合和多张亿级大表 JOIN且稳定性要求极高不能容忍数据延迟和查询超时。在验证过程中菜鸟团队选择了新老集群双跑方案并没有急于做灰度切流。他们利用流计算能力1:1 回放线上 SQL验证查询 RT 是否达到预期以及语法兼容性。持续跑了一段时间后才开始进行仓库粒度的灰度切流。整个灰度过程中逐步对 Doris 集群扩容直至 100% 流量全部切到 Doris。2023 年的双 11第一个小集群完成大促验证集群规模约 300 个 CU。核心场景验证通过后2024 年新财年确定大规模推广计划。9 月首批核心集群全部完成迁移11 月第一次大规模部署征战双 11在成本和稳定性上均表现出色。整个迁移过程未发生一起线上故障。4.4 表结构设计的要点为适配分库分表数据和实时分析需求Doris 表结构设计需要遵循以下原则。分区设计按时间维度或业务维度进行减少查询时的数据扫描范围。对于电商订单数据按月分区或按日分区是常见做法。分桶设计针对大表按高频查询字段进行使数据均匀分布在 Doris 各个节点充分发挥 MPP 并行计算能力。表引擎选择方面核心业务表采用 Merge-on-Write 表引擎支持行级近实时更新离线分析表采用 Aggregate 表引擎通过预聚合提升聚合查询效率。Unique Key 模型用于处理 UPSERT 场景适合订单状态持续更新的业务。五、关键收益与量化结果5.1 成本层面的收获在菜鸟的包裹生产进度场景中迁移到 Doris 后存储成本降低了 90%。在森马服饰的案例中将 Elasticsearch 加分布式 MySQL 架构统一为 SelectDB 版后复杂查询的 QPS 提升了 400%达到 200 以上的 QPS。天眼查将 Hive、MySQL、PostgreSQL 和 Elasticsearch 的混合架构替换为 Apache Doris 后数据写入效率提升了 75%用户分群延迟降低了 70%。5.2 稳定性层面的收获在菜鸟的实践中25 个以上集群遍布 3 个地域日常上万核规模整个迁移过程未发生一起线上故障。双 11 大促期间的成本和稳定性均表现出色Doris 的高并发写入能力和强一致性保证了库存数据的准确性和实时性。补货业务的延迟要求基本在 1 到 2 秒内数据需要可见Doris 能够在大多数场景下达到这一标准。5.3 运维效率层面的收获当将原先维持三套独立系统的架构收敛为 Doris 单一集群后每减少一个系统就少了一套监控配置、少了一条需要调试的数据管道、少了一家需要保持技术对齐的供应商。菜鸟的实时数据架构经过最近 3 年的优化和迭代已经逐步收敛在 OLAP 方向上 Doris 已经成为最优选型运维团队不需要再为多个系统的版本兼容、数据一致性和故障隔离耗费精力。六、这不是技术选型的终点PostgreSQL 是一个优秀的事务处理数据库它理应在电商业务中继续担任在线事务处理的核心角色。当数据分析负载增长到 80TB 这个量级时更好的选择不是在 PostgreSQL 这条路上继续加码而是把分析查询迁移到专门为此设计的 Apache Doris 上让 PostgreSQL 专注于自己最擅长的事务处理。许多团队在只有 80GB 数据时就开始焦虑未来的扩展问题另一些团队在 80TB 时还在尝试用更多只读副本救急。真实的分界线其实很清楚当你的分析查询开始出现 10 倍以上的性能退化当你需要 3 个以上的只读副本专门支撑分析负载当存储扩容成为常规操作就该正视这个问题了。Doris 不一定适合所有的场景但它解决了我们在 PostgreSQL 分析路径上遇到的几乎所有问题。选择 Doris 不是因为它是完美的而是因为维护一套能运转的系统比维护三套勉强度日的系统要好得多。