1. Doris 2.1.x 到底改了些什么:先给你一张全景图
Apache Doris 2.1.x 这个版本系列,在 Doris 的整个发展脉络里处于一个非常特殊的位置。它不是一个简单的小步迭代,而是从"能用"到"好用"的一个明显分水岭。我印象最深的是,2.1.0 正式发版那会儿,社区里讨论最多的问题已经从"Doris 能不能支撑我的业务"变成了"Doris 2.1 和 2.0 比,迁移成本高不高""哪些特性是真正值得升级的"——这说明用户群体已经从尝鲜者过渡到了大规模生产使用者。
从我自己的使用体验来看,2.1.x 最大的价值可以浓缩成三句话:查询优化器 Nereids 正式在生产环境扛大旗,成为默认优化器;写路径上的 group commit 和批量提交能力补上了高并发写入的短板;半结构化数据分析和数据湖联邦查询开始真正具备实用价值。这三个方向,恰好对应了 Doris 官方在 2.1 版本发布会上反复强调的关键词:更智能、更快写入、更开放。
这篇总结我不会给你念版本发布日志,那是官网干的事。我想从一个实际跑过 2.1.0 到 2.1.5 生产环境的从业者视角,把那些文档里不会写清楚、或者要踩过坑才能理解的东西整理出来。适合谁看?两类人:一类是正在评估要不要把线上集群从 2.0 升到 2.1 的运维和 DBA,另一类是用 Doris 做数据分析平台开发、想知道 2.1 新特性到底能解决什么业务问题的工程师。
2. 从 2.0 升级到 2.1:升级路径、行为变化与一次真实迁移复盘
先说结论:2.0 到 2.1 的升级不是平滑的"滚动升级就行",它包含了一些fe 和 be 的配置语义变化、默认值调整以及优化器行为的切换。如果你不做任何参数调整直接升级,大概率不会起不来,但查询性能可能会出现意料之外的波动,因为 Nereids 在 2.1 里变成了默认优化器,而很多 2.0 时代针对旧优化器调优过的 SQL 执行计划会发生变化。
2.1 升级前必须确认的检查项清单
我把 2.1 升级前的检查项列一个清单,这是我经历过的、以及从社区里多位实践者那里交叉验证过的结果:
- 版本路径确认:2.1.x 支持从 2.0.x 直接升级,但从 1.2.x 跨版本升级会复杂很多,建议先升到 2.0 再升 2.1。我见过有人试图从 1.2 直接跳 2.1,结果 fe 元数据兼容性校验报错,最后只能重新初始化,非常折腾。
- fe.conf 参数清理:2.1 移除了部分旧优化器相关的参数,保留了参数名但在新优化器下不再生效,比如
max_old_optimizer_fallback之类的配置。升级前最好把 fe.conf 里那些为旧优化器设置的参数全部过一遍。 - be.conf 行为变更:2.1 对存储目录和 Tablet 元数据管理的默认方式做了调整,新部署的集群默认会开启更严格的 tablet 校验逻辑。升级前建议先读一次官方升级文档里关于
ignore_tablet_incompatible的说明。 - 审计日志和监控项:2.1 的审计日志插件接口有变化,如果你的监控系统依赖 audit log 做查询分析,需要在升级前先更新插件版本,不然后续的查询审计数据会断档。
2.2 一次真实迁移复盘:某业务集群从 2.0.13 到 2.1.4
我在某个模拟项目 X 里负责过一套 12 个 BE 节点、3 个 FE 节点的集群迁移,数据体量大概在 8TB 左右。我们当时的目标版本是 2.1.4,整个升级过程是:先在FE 侧开启 Nereids 灰度模式,通过set enable_nereids_planner=true强制一部分线上查询走新优化器,并在测试环境跑了整整一周的查询回归。回归重点有两个:一是核心报表 SQL 的执行时间是否在可接受范围内;二是有没有出现旧优化器能跑、新优化器却报错的 SQL。
一个典型的例子是那种带有大量子查询嵌套和复杂关联条件的报表,Nereids 在等价改写上的能力明显更强,回报表也比旧优化器更快,但偶尔会出现谓词下推行为不一致导致的扫描行数变化。所以升级期间务必保留一条快速回退通道,我们的做法是保留一个 FE 节点不升级,随时可以切回旧版本。
BE 节点我们采用的是逐台滚动替换:先下线一台 BE、更换二进制、重新上线、等副本恢复,再操作下一台。这里有个教训:下线一台 BE 前必须确认副本个数不小于 2,不然数据会处于单副本状态,一旦替换失败就是一场灾难。滚动替换 12 台 BE 花了大概一天半,整体体验比较顺利,没有发生数据损坏或查询长时间中断的情况。
2.3 从 1.x 直接跨到 2.1:哪些业务更容易掉坑
如果你的集群还停留在 1.2.x,想直接升到 2.1,我得先给你泼盆冷水。1.x 到 2.x 的元数据格式有变化,Doris 官方支持通过元数据回放加 transform的方式做迁移,但实际操作非常敏感。我见过某团队因为 1.2 时代遗留的动态分区表达式在 2.1 里语法解释不同,导致升级后自动创建分区失败,夜间调度任务直接报错。他们的做法是升级前把建表语句全部导出来,人工检查所有分区表达式和数据类型。
另外 1.x 时代的PROC系统表在 2.x 里被大量替换成了INFORMATION_SCHEMA视图,很多运维脚本基于旧表名写的查询会直接失效。建议提前在测试环境用你的运维脚本集跑一遍全量回归,不要等上了生产再对着报错信息一个个改。
从长远的可维护性来看,我的建议是:如果你的集群还在 1.x,不要因为怕麻烦而拖延升级,2.1 的安装部署和日常运维体验比 1.x 好了不止一个档次,这个升级成本是值得付的,跨多个大版本升级的风险始终更高。
3. 查询性能的核心引擎:Nereids 优化器在 2.1 的成熟度与调优实践
Nereids 在 2.1 里成为默认优化器,这件事的意义怎么强调都不过分。Doris 在 2.0 时代做了大量 Nereids 的 SQL 方言兼容和性能调优,但很多用户因为担心稳定性,仍然用参数把旧优化器锁死。2.1 是一个拐点,社区大量生产案例已经验证了 Nereids 的能力,我自己也从 2.1.2 开始彻底不再回退旧优化器了——前提是你要理解它个性和旧优化器完全不同。
3.1 为什么 Nereids 的执行计划更合理:关联顺序与代价模型
旧优化器在生成执行计划时,对多表关联顺序的处理相对机械,它更依赖经验规则而不是代价模型。Nereids 则是基于CBO(Cost-Based Optimization)的架构,它会根据表的行数估算、列的基数、过滤率等统计信息,枚举可能的关联顺序并计算代价,选择更优的执行计划。
用大白话解释就是:旧优化器像一个认路的老司机,只走自己熟悉的那几条路,哪怕堵车也硬着头皮走;Nereids 像一个打开实时路况的导航,会根据每条路的拥堵情况动态选择最快路线。前提是路况信息要准——也就是说,表的统计信息要足够准确,如果统计信息缺失或过期,Nereids 的估算就会失真,做出的计划未必比旧优化器好。
所以在 2.1 里,统计信息的收集成了影响查询性能的关键前置条件。很多从旧版本升级上来的用户发现某些查询反而变慢了,排查到最后往往是统计信息没有收集。2.1 提供了ANALYZE TABLE语句手动收集,也支持自动收集任务。对核心大表,我建议还是在业务低峰期手动做一次全量 ANALYZE,并给关键列建立统计信息,特别是关联列、过滤列。
3.2 统计信息收集:手动与自动的选择
Doris 的统计信息分为基础统计信息和直方图统计信息。基础统计信息默认在数据导入时自动更新,但对于查询性能影响最大的行数估算和基数估算来说,如果表数据量大且更新频繁,自动更新可能滞后。我在实践中发现,对持续高频导入的大表,手动 ANALYZE 的收益非常明显。
以一个模拟业务的订单表为例,单表 1.2 亿行,关联维度表时,未收集统计信息前 Nereids 估算驱动表行数偏差超过一个数量级(实际过滤后 80 万行,估算成了 1200 万行),执行计划选择了一个错误的关联顺序,查询耗时 8 秒。手动ANALYZE TABLE 订单表之后,同样的查询耗时降到了 1.5 秒。这个案例我自己复现过多次,所以强烈建议把核心表的 ANALYZE 调度纳入日常运维。
2.1 还提供了analyzestatsenabled这个全局开关,可以控制统计信息自动收集的粒度。如果你在意统计信息搜集带来的额外开销,可以针对核心表开启自动收集、其他表关闭,在开销和性能之间找平衡点。
3.3 利用 Profile 反推执行计划问题:短查询与长查询的不同观察维度
Nereids 的执行计划是一个树状结构,Doris 的 Query Profile 会详细记录每个执行节点的耗时、扫描行数、峰值内存等信息。调优的时候,我最常做的一件事是:对比 Profile 里各个执行节点的扫描行数和输出行数,找出「行数膨胀」的位置——通常是关联方式不对或者中间结果集过大导致的。
举个具体的排查路径:某查询在 2.1 上偶发耗时破秒,从 Profile 看 Join 节点左子树扫描 10 万行,右子树扫描 8000 万行,输出行数也是 8000 万级,显然优化器选择了大表做驱动表。这个问题的根源是统计信息不准导致估算偏差,重新 ANALYZE 后执行计划纠正,问题消失。
另外要注意一点:Nereids 对短查询(毫秒级)的优化收益往往不如长查询(秒级)明显。短查询的瓶颈经常在 FE 的 SQL 解析和计划生成阶段,这部分开销和优化器关系不大。如果一个耗时 5ms 的查询优化到了 4ms,这是正常的,别指望 Nereids 能把短查询缩短一个数量级;但一个耗时 10 秒的分析查询,Nereids 优化到 3 秒是常有的事。
4. work harder or smarter:2.1 的物化视图与异步构建能力
物化视图是 Doris 2.1 里另一项被大幅强化的能力。简单说,物化视图就是「预先算好的结果集」,查询时直接读结果而不是现场计算,这对多表关联、聚合汇总类报表尤其有效。2.1 把物化视图从只能基于单表做简单聚合,扩展到支持多表 Join、嵌套聚合、异步刷新,这就让它在实际生产里的可玩性高了很多。
4.1 异步物化视图解决了什么问题:现场计算 vs 提前计算
过去,如果业务有复杂的多表关联报表,Doris 的常规做法是:要么现场跑 Join,要么在业务侧单独建一张汇总表,通过调度任务写入。前者的问题是大查询容易拖垮集群资源,后者的问题是繁琐、实时性差、逻辑分散。
异步物化视图把「单独建汇总表 + 调度刷新」这套逻辑做进了数据库内部。你只要定义好物化视图的 SQL 和刷新策略,Doris 自己负责在后台构建和维护结果数据。对业务应用来说,物化视图就像一张「虚拟表」,查询走它就行,不需要管刷新逻辑,非常省心。我用它重构过一个多表关联的看板接口,原来查询端到端要 3 秒,命中物化视图后 60ms 内出结果。
4.2 物化视图的实际案例:刷新策略的选择与命中验证
在 2.1 里创建异步物化视图的语法大致是:
CREATE MATERIALIZED VIEW mv_order_daily BUILD IMMEDIATE REFRESH AUTO ON MANUAL DISTRIBUTED BY HASH(order_id) BUCKETS 16 AS SELECT order_date, user_id, SUM(amount) AS total_amount FROM orders GROUP BY order_date, user_id;刷新策略上,我强烈建议生产环境用ON MANUAL手动刷新,配合调度平台在业务低峰期执行REFRESH MATERIALIZED VIEW mv_order_daily。虽然 Doris 也支持 ON COMMIT 同步刷新,但对于大数据量场景,同步刷新成本很高,容易阻塞导入链路。
有一个大家比较容易忽略的点:物化视图是否被查询命中,需要主动验证。有时候你以为查询走了物化视图,其实走了原表,结果性能没有预期提升。你可以用EXPLAIN查看执行计划,确认查询计划里是否出现了物化视图名称;也可以在会话中开启相关变量观察查询命中的物化视图信息。不要想当然,验证了才有底。
4.3 什么场景不合适用物化视图
物化视图也不是银弹。维度表更新频繁、数据实时性要求极高的场景就不适合,因为物化视图本质是「T+1」或「T+N」数据,就算刷新间隔短也做不到完全实时。刷新时如果基表数据量大,构建和刷新过程会占不少资源,选刷新窗口时要避开业务高峰。
举个例子,有个团队把一张明细大表的物化视图刷新策略设成了每小时一次,结果每次刷新都要全量 Scan 大表,高峰期 CPU 直接被打满,线上的实时查询跟着抖动。后来改成分区级别增量刷新,只刷新当天分区,资源占用立刻降了下来。所以记住:能用分区粒度刷新,就不要整表刷新。
5. 写入链路的重构:Group Commit、丰富导入生态与大批量写入
如果说查询是 Doris 的面子,写入就是里子。2.1 在写入侧做了很多扎实工作,其中Group Commit(分组提交)是值得一提的新特性。它解决的问题非常具体:高并发小写入场景下,单个导入请求的固定开销(比如 FE 解析、BE 写入事务提交)会被放大,导致写入延迟高、吞吐上不去。Group Commit 的做法是把多个并发的小写入请求合并成一个大的写入任务批量执行,从而摊薄固定开销。
5.1 什么是 Group Commit:高频小写入场景的救星
用个通俗的类比:如果没有 Group Commit,每辆物流车只拉一件货就出发,高速费油费都是固定的,成本太高;开启 Group Commit 后,物流调度中心会等一批货满了再发车,整体运输效率大幅提升。Doris 2.1 的 Group Commit 支持三种模式:
- sync 模式:客户端发请求后同步等待写成功,延迟低,吞吐提升明显
- async 模式:客户端发请求立即返回,后台批量提交,吞吐更高但实时性稍差
- off 模式:关闭分组提交
我最常用的是 sync 模式,业务侧完全无感知,写入吞吐能提升数倍。实测过某日志类业务,关闭 Group Commit 时单并发写入延迟平均 20ms,开启 sync 模式后吞吐从每秒 5000 行提升到每秒 2 万行以上,而延迟依然可控。这里一个关键点是:Group Commit 适合导入间隔短、数据量小的场景,比如实时埋点、日志收集;它对大批量导入(比如一次导入上亿行)没什么意义,因为一次大导入本身就是「整车发货」。
5.2 Merge-on-Write 在 2.1 的完善:Update 场景的表现
2.1.x 在 Unique 模型的写入实现上做了大量优化,Merge-on-Write(MOR)已经可以在生产环境放心使用。相比旧的 Merge-on-Read(读时合并),MOR 在写入时就把主键冲突合并掉了,查询时不需要额外执行合并操作,对于大量 Update 的场景,查询性能稳定得多。我们在测试环境对比过:同样是千万级主键表的点查,MOR 比 MRO 平均快 2 到 4 倍。
2.1 里还给 Unique 模型加了自动分桶和更聪明的分桶数选择,减少了很多「分桶设置不合理导致写入和查询倾斜」的问题。如果你是从 1.x 升级过来的用户,建议把所有 Unique 表都迁移到 MOR,查询性能和稳定性收益都很可观。
5.3 导入生态与内存控制:从 Spark Load 到 Flink Connector 的配合
2.1 面向生态的导入能力也在持续补全。Spark Doris Connector 支持了更灵活的写法,比如通过 DataFrame 直接写 Doris,同时把事务、统计信息的衔接做得更顺滑。对于 Flink 用户,官方 Flink Connector 在 2.1 也做了明显改进,尤其是支持了Stream Load 的列裁剪和 WHERE 过滤下推,能减少导入前的数据量,对端到端链路的成本控制有帮助。
这里我想强调一个导入内存控制的经验。Doris BE 的导入内存会占用可查询内存的一部分,如果导入任务并发度过高,会导致 MemTable 累积,触发 GC 甚至 OOM。2.1 里通过调整max_memory_limited_ratio和load_process_max_memory_limit_percent的配合来控制导入总内存占比。我在生产上喜欢把导入内存占比控制在 BE 总内存的 30%-50% 之间,确保导入高峰不挤压查询侧的内存用量。这个比例要结合你的业务读写比例来调,不能照抄。
6. 半结构化数据与倒排索引:Doris 不只是个 OLAP
Doris 2.1 在「非结构化/半结构化数据」支持上的进步值得单独说。最直观的是Array、Map、Struct 等嵌套类型的可用性提升,以及JSON 类型从全文解析到索引加速的跨越。在 2.0 时代,Doris 对 JSON 基本是「存」和「取」的能力,查询时解析开销大;2.1 引入了更高效的变长类型支持,加上倒排索引的落地,让 JSON 字段上的全文检索和点查有了真正可用的性能。
6.1 倒排索引的逻辑:从扫描到快速定位
倒排索引的原理可以类比书的目录:你要找某一个关键词,不用从第一页翻到最后一页,直接通过目录定位到相关页码。Doris 2.1 的倒排索引就是为字符串、JSON 字段上的等值和全文检索场景设计的加速结构。它很适合日志分析里的「按关键字搜索报文内容」、订单表里「按用户 ID 在 JSON 里检索标签」这类业务。
创建倒排索引的语法示例:
CREATE TABLE log_table ( ts DATETIME, level VARCHAR(10), message TEXT, INDEX idx_message(message) USING INVERTED ) DUPLICATE KEY(ts) DISTRIBUTED BY HASH(ts) BUCKETS 16;这里要提醒的是,倒排索引的构建和存储都有额外开销,不是所有字段都适合加。只在那些确实需要加速检索的长文本、JSON 字段上加即可。字段区分度低、基数高的字段上,索引收益不大,还浪费存储。
6.2 JSONB 数据类型的实际收益:二进制 Json 的高效处理
2.1 的 JSON 类型底层格式升级为 JSONB(二进制 JSON),查询和解析的效率比旧版高了不少。JSONB 带来的最直观变化是同一张表里 JSON 字段的读取、过滤、提取子字段的性能大幅提升。如果你的业务大量使用GET_JSON_STRING、JSON_QUERY这类函数,升级到 2.1 后应该能感觉到明显加速。
一个常见的应用场景是「业务宽表 + JSON 补充字段」的模型。比如主表存结构化核心字段,JSON 字段存扩展信息、标签、变长属性。过去这个 JSON 字段如果要作为过滤条件,往往要全列解析,慢得离谱;2.1 下配合倒排索引或带类型的 JSONB 子列提取,把高频过滤的某个 JSON 子字段物化成生成列,过滤性能提升非常可观。
6.3 日志场景的混合负载:Doris 和 Elasticsearch 的边界在哪里
说到半结构化和倒排,自然绕不开 Elasticsearch 这个对手。我经常被问到「日志数据分析到底选 Doris 还是选 ES」。我的看法是:Doris 2.1 更适合「日志结构化分析 + 高并发聚合」,而 ES 更适合「交互式全文搜索 + 灵活性极强的检索」。两者不是完全替代关系,但 Doris 在产品易用性、SQL 兼容性、和周边 OLAP 生态的结合上,对很多日志分析场景已经构成了实质的替代选项。
举例来说,一个安全运营平台需要保存半年以上的访问日志,既要按时间范围聚合统计(按天、按客户端类型分组计数),又要支持对报文内容做关键词检索。这个场景用 Doris 2.1 的倒排索引加物化视图完全可以覆盖,还能和现有数据仓库用 SQL 做关联分析——这是 ES 很难做到的。反过来,复杂相关性排序、灵活的全文检索语法等,ES 依然优势明显。所以选型不是「谁替代谁」,而是根据查询模式和成本模型来判断。
7. 数据湖联邦查询:打通外部数据源的 2.1 实践
湖仓一体在 2.1 里不是概念,而是实打实可用的功能。Doris 的多 Catalog 功能在 2.1 中继续增强,尤其是对Hive Metastore、Iceberg、Hudi、Delta Lake 以及对象存储上的 Parquet/ORC 文件的联邦查询支持更成熟了。我实际用下来,2.1 的 Iceberg 集成体验比 2.0 稳定得多,元数据缓存、分区裁剪、谓词下推都有了实质改进。
7.1 多 Catalog 架构:一个查询入口的便利与限制
设置一个 Hive Catalog 的语法只需几行:
CREATE CATALOG hive_catalog PROPERTIES ( 'type' = 'hms', 'hive.metastore.uris' = 'thrift://hive-metastore:9083' );之后在 Doris 里就能直接查 Hive 表:
SELECT * FROM hive_catalog.db_name.table_name LIM 10;这种架构的价值在于:让 Doris 成为一个统一的数据分析入口,上层报表和应用只需要连接 Doris,后端的数据可以分布在 Hive、Iceberg、对象存储等多个系统里。对很多团队来说,数据分析链路的复杂度因此显著下降。
但要清醒地认识到联邦查询的代价:外部数据源的扫描速度大概率比 Doris 内表慢,因为 Doris 无法完全控制外部数据的存储布局和索引。所以联邦查询适合做「低频的探索式分析」或「冷热分层中的冷数据查询」,不适合对延迟极度敏感的线上主链路。
7.2 外部表查询的性能调优:缓存与执行引擎的配合
2.1 为外部数据源增加了缓存机制,有点像「给查询加了一层加速」。对于重复访问同一个 Parquet 文件的场景,Doris 会把文件元数据和部分数据块缓存到 BE 本地,后续查询直接读缓存,性能提升明显。开启方式大致是通过 Catalog 属性或会话语义控制缓存策略,比如把file_cache_ttl设置成一定时间,控制缓存的有效期。
我在模拟项目 X 里跑过一组对比:一条查询 Hive 外表聚合 1TB 数据的 SQL,第一次执行耗时 180 秒,连续第二次执行耗时约 45 秒——主要就是文件缓存生效了。当然,前提是查询热数据有复用性,纯随机扫描的数据,缓存效果有限。另外要留意文件缓存会占用 BE 磁盘,默认可能落在 BE 数据目录下,建议为缓存数据单独挂盘或明确大小限制,避免缓存把磁盘撑满。
7.3 安全和权限:外表数据源的集成注意点
联邦查询让你能查外部数据,同时也意味着安全问题变得更复杂。2.1 的多 Catalog 支持通过 Ranger 做外部数据源的鉴权,但这个集成需要额外配置,不是默认开启的。如果你们的 Hive 或 Iceberg 数据源本身有严格的权限模型,务必在引入 Doris 联邦查询时同步做好权限对接,别出现「Doris 成了绕过权限的后门」这种情况。
我踩过一个小坑:有段时间我们用 Hive Catalog 查询外部表,外层没做任何鉴权,结果任何一个能连 Doris 的用户都能查 Hive 里的全部数据。后来通过配置 Ranger 服务对接 Doris 的 Catalog 权限认证,才算把这道口子补上。安全这方面,宁可多花点时间配置,也不要留下隐患。
8. 可观测性与查询治理:从审计到 Workload Group 的资源隔离
2.1 在运维侧的可用性提升也是升级后感知最明显的一部分。审计日志插件升级、Workload Group 资源隔离、慢查询治理、查询队列,这些功能组合起来,让线上集群的「看得到、管得住」能力上了个台阶。
8.1 审计日志插件:查询历史的完整闭环
2.1 的审计日志功能可以记录到每个查询的完整信息,包括 SQL 文本、执行时长、返回行数、扫描行数、客户端 IP、用户等。这套数据是查询治理的基石:通过分析审计日志,可以快速定位慢查询、热查询、异常访问。
我在实际运维中,会把审计日志导入到 Doris 自己的一张表里(天然的吃自己的狗粮场景),然后定期跑分析:
- 哪些 SQL 是「高频 + 高耗时」组合,记录下来做针对性优化
- 哪些用户或业务的查询消耗了不成比例的扫描行数
- 哪些 SQL 出现失败或超时次数异常增长
有一个查询治理的典型案例:某业务上线后集群 CPU 突然飙升,通过审计日志筛出某个新上线的报表 SQL 每小时被调用上千次,而且每次都是全表扫描。跟业务沟通后发现这条 SQL 根本不需要全表扫描,只是开发没写过滤条件。优化后 CPU 直接降了一半。没有审计日志,这种问题排查基本靠猜。
8.2 Workload Group:隔离不等于浪费
2.1 的 Workload Group 可以做 CPU、内存、并发度的多维隔离。听起来这是个纯运维概念,但我建议每个 Doris 用户都认真设计一下分组策略,特别是多业务共用一个集群的场景。
举例来说,一个集群里既有核心在线报表(要求低延迟),又有离线分析任务(允许跑得久但吃资源多)。如果不做隔离,离线任务很可能把 CPU 和内存抢光,在线报表响应变慢。通过 Workload Group:
- 在线报表组设高优先级,限制并发数的同时保障 CPU 配额
- 离线分析组设低优先级,允许大查询跑,但不让它挤占在线组的资源
- 对突发事件再配合查询队列(Query Queue)进行排队,集群过载时拒绝新请求而非拖垮已有任务
这里有个容易被误解的点:资源隔离不是「把资源分出去就不能用了」。Doris 的 Workload Group 是软隔离和硬隔离的结合,CPU 配额是弹性的——如果离线组没用满 CPU,在线组可以借过来用;一旦在线组需要,资源又能归还。所以不用担心隔离策略导致资源利用率下降,反而应该担心「不隔离」导致大家互相干扰。
8.3 慢查询治理的实操流程:一个可以抄作业的闭环
结合审计日志 + Profile + Workload Group,慢查询治理在我这里形成了一套固定闭环:
- 每天定时从审计日志里捞「耗时 top 50」或「扫描行数 top 50」的 SQL
- 逐个分析 Profile,找出执行计划的瓶颈节点(通常是 Join 行数膨胀、或过滤条件下推失败)
- 能通过索引、物化视图、统计信息等手段优化的,优化后在生产验证
- 无法优化的长查询(比如真的需要扫全表做深分析),转移到专门的 Workload Group 里,加长超时时间,避免影响在线业务
- 定期复查,把优化掉的 SQL 从 top 榜单移除,保持治理有持续产出
这套流程不需要额外开发任何平台,纯靠 Doris 自身的功能和几个定时脚本就能跑起来。我建议每一条从 top 榜移除的 SQL 都记录一下原因,方便以后回顾和复盘——你会发现,大部分慢查询的根因集中在缺失统计信息、缺失索引、Join 顺序不合理这些共性问题上,果然是幸福的家庭总是相似的,不幸的查询各有各的不幸。
9. 升级到 2.1.6 以后:回看整个 2.1.x 系列的成熟轨迹
Doris 2.1.x 从 2.1.0 到 2.1.6,补丁版本迭代节奏快,每个小版本都有重点修复。如果你还在犹豫用哪个小版本,我直接给结论:生产环境用 2.1.4 之后的版本会省心很多。2.1.0 到 2.1.2 期间,部分场景下 BE 的内存统计和导入稳定性还有瑕疵,社区反馈比较集中的问题,在 2.1.3、2.1.4 里陆续得到了修复。
9.1 跨小版本升级的注意事项
2.1.x 内部的小版本升级通常是平滑的,只要你在升级前阅读对应 Release Note,关注是否有配置项废弃、默认值变更、或者 BE 元数据不兼容的提示即可。从 2.1.2 升到 2.1.6 这类同大版本内的升级,基本可以按「先升级 FE,再逐台替换 BE」的节奏操作,风险很可控。
但要注意:升级到 2.1.x 后,不要马上把一些实验性功能全打开。比如某些新加的参数默认是关闭的,需要明确了解其含义再决定是否开启。一个稳妥的策略是:升级后保持默认参数跑一段时间,观察查询耗时分布、导入延迟、GC 情况,确认稳定后再按需开新特性。
9.2 一个值得尝试的功能:更灵活的表分桶设置
2.1 改进了自动分桶的算法,让建表时可以不指定分桶数,由系统根据表大小和机器数量自动计算。这个特性对新手非常友好,因为「分桶数设多少」一直是个玄学问题——设少了数据倾斜,设多了小文件太多。自动分桶会根据数据导入情况动态调整分桶数,省去了很多手工调优的功夫。
我实际测试下来,自动分桶对百亿行以下的大表表现都不错,但对于超级大表(千亿行以上),还是建议根据集群规模手工精细化设置分桶。两种方式没有绝对优劣,核心是理解你的数据分布特征,再决定用哪种策略。另外,在 2.1 中修改分桶数已经不需要重建表了,可以通过ALTER TABLE操作完成动态调整,这在运维上是很大的解脱。
9.3 从 2.1 到 3.0 的展望:为下一个大版本做准备
写这篇文章时,Doris 3.0 体系也在快速发展了。如果你正准备新上线一套集群,我建议直接评估新版本——因为从 2.1 到 新大版本,核心 API 和 SQL 方言大体兼容,但性能和功能优势明显。从 2.1 升级到新版本的路径通常比从旧版本升级顺畅得多,所以现在基于新版本做新项目,未来会少折腾一次。
当然,已经跑在 2.1 生产环境的集群,也没有必要因为追新而急着迁移。2.1 的稳定性和功能完整度足够支撑绝大多数业务跑两三年,升级计划可以按你自己的节奏走。关键是:不要在 1.x 时代停太久,2.1 带来的操作体验和性能提升,值得你认真的花一个周末去升级。
10. 写在最后:2.1.x 让 Doris 从一个查询引擎变成了一个数据平台
如果要我用一句话概括对 Doris 2.1.x 的整体评价,我会说:它的确从「一个能跑 SQL 的 OLAP查询引擎」进化成了「一个有平台能力的数据基础设施」。查询优化器、物化视图、倒排索引、资源隔离、联邦查询、审计治理——这些能力组合在一起,意味着 Doris 已经可以成为企业数据分析架构的中枢,而不只是某个报表系统的后端存储。
我在实际项目中,已经不止一次把 Doris 2.1 用在了以前会选其他组件的场景:日志分析的全文检索、多源数据的联邦分析、甚至轻量级的用户画像标签查询,它都表现出了足够强的工程能力。当然,没有完美的工具,Doris 在超大集群规模、实时性要求极高的场景下仍有边界,但对于大多数业务来说,2.1 已经足够优秀。
最后分享一个小经验:版本升级和新技术引入,最忌讳「想全了再动」。你不会把所有坑都在文档里看到,最好的办法是搭一个测试环境,把你最核心的 20 条 SQL 和最关键的业务链路跑一遍,让数据说话。我在评估 2.1 的时候就是这么做的——两周的验证换来两年的稳定,很值。希望这篇基于实际经验写成的版本总结,能让你在 Doris 2.1.x 的路上少踩几个坑,多省几夜眠。