先想一个特别真实的问题:你手里的表,已经不只是几千行数据了。每天有上亿条访问日志往里面灌,老板随时要按渠道、按商品、按省份拉多维汇总,还要能钻取到底层明细。MySQL扛不住这种量级的聚合查询,跑一次全表扫描能卡几分钟;Hive又太重,每次跑批要等半天,根本没法做“即时分析”。这时候你就需要一种“又快、又稳、又能扛大数据量”的分析型数据库。Doris,就是为这种场景生的。
这篇是“Doris从入门到上天”系列的第一篇,也是整个系列的地基。这一篇不聊具体安装,不聊调优参数,只把一个事情讲透:Doris到底是什么,它解决了什么核心问题,以及为什么那么多公司在OLAP选型时最后选了它。适合谁看?刚接触Doris的工程师、在技术选型阶段纠结“要不要引入Doris”的团队负责人,以及那些已经被“Presto查Doris报missing”“几MB数据要不要分桶”这类问题困扰过的同学,这篇都值得先静下心读完。
1. Doris到底是什么:一个为分析查询而生的数据库
1.1 从OLTP和OLAP的“分裂”说起
常规的业务系统,比如订单、用户、库存,用的是MySQL或者PostgreSQL这类关系型数据库。这类数据库擅长的是“增删改查”,一个订单一条记录,按主键读写,非常快。这类场景统称OLTP,强调事务、一致性和低延迟写入。但一旦你把几亿行数据拉到一起做聚合,比如“统计每个省份每个商品最近30天的销售额”,OLTP数据库就抓瞎了——它不是为这种大范围扫描设计的,索引在聚合查询面前基本失灵,只能全表扫描,然后内存和CPU全部打满。
另外一个方向是Hadoop生态。数据大归大,能存,但查询要用Hive这种批处理框架,提交一个SQL任务,等MapReduce或Spark跑完,分钟级甚至小时级的延迟是家常便饭。你老板坐在旁边等一张报表,等到咖啡都凉了还没出来。这个场景就是OLAP,强调海量数据上秒级甚至毫秒级的分析响应。
Doris走的是第三条路:MPP架构的分布式OLAP数据库。它把表数据打散到多个节点上并行计算,查询过来时所有节点一起跑,结果汇总后返回,把“大查询”拆成很多“小查询”,再合起来,所以数据量越大、节点越多,优势越明显。它的定位非常清晰:分析型,不是事务型。你可以拿它做报表、大屏、用户行为分析,但不要试图拿它替代MySQL做订单交易系统。
1.2 Doris的成长路径:从百度内部到Apache顶级项目
了解一个技术的“身世”是有意义的,因为它的基因决定了它的适用范围。Doris最初叫Palo,是百度内部用来支撑广告报表分析的自研系统,2018年百度把核心代码捐赠给Apache基金会,项目更名为Doris,后来一步步成长为Apache顶级项目。这个出身有两个直接影响:
第一,它天生解决的是“真实业务里的大数据量聚合查询”问题,而不是实验室产品。百度广告系统每天产生海量日志,需要按广告主、用户、时间等维度做极快的多维度分析,这种极端压力下打磨出来的系统,稳定性和性能是经过验证的。
第二,它融合了MPP数据库和分布式系统的设计经验,同时保持了MySQL协议兼容。这意味着你不需要学习一套全新的查询语言——团队里会MySQL的人,基本可以直接上手写SQL查Doris,只是在建表和模型设计上有些新概念需要理解。
1.3 整体架构:FE管脑子,BE管干活
Doris的集群由两类节点组成:FE(Frontend)和BE(Backend)。
FE是“大脑”,负责接收客户端请求、解析SQL、生成执行计划、调度查询,同时管理整个集群的元数据,比如表结构、分区信息、副本状态。你可以把它理解成公司里的项目经理,客户提需求,他来拆解任务、分派给不同团队,最后汇总结果。FE之间可以组成高可用组,一台挂了另一台顶上。
BE是“手脚”,负责真正存储数据、执行计算。数据按分区和分桶打散到不同BE节点上,每个BE节点并行处理自己负责的那部分数据,最后把结果返回给FE聚合。BE也负责副本冗余——同一份数据默认存多个副本,某个节点挂了,数据不丢,查询也能自动切到其他副本。
这套“FE管元数据、BE管数据计算”的架构,是Doris能同时做到高并发、高吞吐和线性扩展的核心。你加机器,就是加BE节点,数据自动重新分布,查询性能跟着涨,这也是Doris集群部署的价值所在。
2. 核心特性拆解:为什么那么多公司最后选了Doris
2.1 列式存储:让“扫描”变便宜
Doris在数据存储层面采用列式存储。传统行式存储,比如MySQL的InnoDB,是把一行记录的所有字段放在一起物理连续存储,像一本流水账,每行都有完整字段。查询时哪怕只要一个列,也几乎要把整行数据读出来。
列式存储则相反,同一列的数据连续放在一起。做聚合时只读取需要的列,比如“SUM(amount)”只需要读amount列,其他字段完全不碰。这对数据分析场景是决定性的优势——I/O量可能缩小几倍甚至几十倍。同时,同一列的数据类型一致,压缩率远高于行式存储。Doris支持Snappy、LZ4等压缩算法,实际生产环境下,日志类大宽表压缩比经常能到5:1甚至更高。磁盘上的数据变小了,扫描速度自然更快,这也是Doris单表查几十亿行还能保持秒级响应的重要原因之一。
2.2 向量化执行引擎:把CPU用到极致
光有列式存储还不够,Doris在查询执行层面用了向量化执行引擎。传统数据库的查询执行,很多时候是一行一行地处理记录,每一行都要重复调用同一套逻辑,CPU的分支预测和缓存命中率都很不理想。
向量化执行改变的是处理粒度:按“列的一批数据”为单位批量计算,一个操作同时处理上万行数据,配合SIMD指令集,让CPU在一个时钟周期内完成更多计算。简单来说,如果一个传统引擎像一个工人搬砖一次搬一块,向量化引擎就是开了一台叉车一次叉一托盘。这块是Doris在1.0之后重点发力的方向,实测在聚合类SQL上,向量化执行比非向量化版本通常有几倍到十几倍的性能提升。
有一点要说明:Doris对复杂Join和子查询的支持也在持续完善,但它的核心优势是“大宽表聚合、过滤、排序、分页”这一类分析操作。你设计模型时,尽量让场景符合它的优势区,效率会最大化。
2.3 三种数据模型:学会区分,就学会了Doris的一半
Doris的建表思维和MySQL很不一样,核心区别就在数据模型。Doris提供了三种模型:
- Duplicate Key Model(明细模型):数据原样存储,不做任何合并,适用于日志、行为流水等需要保留全量明细的场景。建表时指定的Key列只用于排序,不参与聚合。
- Aggregate Key Model(聚合模型):按照维度列做预聚合,比如导入多条记录,系统按指定聚合函数自动合并。适合“按时间、按维度统计总量”的报表场景,比如PV/UV、销售汇总。
- Unique Key Model(主键模型):按主键去重,重复导入的数据以最新记录覆盖旧记录,适合订单、用户信息这类需要“更新”状态的场景。比如订单状态从“待支付”变成“已支付”,主键模型保证最终查询时只看到最新状态。
这三种模型本质上决定了数据怎么存储、怎么写。很多人第一次用Doris踩坑,往往就是模型选错了——该用Unique的用了Duplicate,结果数据重复;该用Aggregate的用了Unique,预聚合优势没发挥出来。这个点我会在系列的后面专门出一篇详细讲,这里先有个概念就行。
2.4 实时导入与高并发查询:两边都占
很多OLAP系统要么写入好查询差,比如Kafka和日志系统,要么查询快但写入通道弱。Doris是一个“写入和查询都比较强”的引擎。
写入方面,Doris支持多种导入方式:Stream Load适合程序实时推送;Broker Load适合从HDFS、S3等外部存储批量导入;Routine Load可以直接订阅Kafka流式数据,自动持续消费。生产环境里最常见的组合是:业务数据通过Canal同步到Kafka,再由Doris的Routine Load实时写入,做到分钟级甚至秒级的数据可见。不要小看这个能力,这直接决定了你能不能做“实时数仓”。
查询方面,Doris支持高并发点查。虽然它是分析型数据库,但MySQL协议加良好的索引设计,让它可以支撑几十到几百QPS的轻量查询,很多公司直接用它替代部分Redis或MySQL的读场景,减少技术栈复杂度。
2.5 物化视图与Rollup:以空间换时间的典型操作
Doris有一项“独门绝技”叫Rollup表,可以理解为“自动维护的预聚合表”。你原始明细表存着全量数据,再建几张Rollup表,按不同的维度组合预先聚合。查询时优化器如果发现某个Rollup表能更快地回答查询,会自动改写SQL去查预聚合表,不需要你改一行代码。
举个例子,原始表是“用户 PK访问日志”,每天几个亿行。你又建了一张Rollup:按“日期+省份+渠道”做PV/UV聚合。那么查询“昨天各省份渠道的PV”时,Doris会直接命中那张很小的预聚合表,性能可能差几个数量级。这个机制比传统数据库的物化视图更灵活,也是Doris在很多报表场景里能秒开的核心原因之一。
3. 和ClickHouse、StarRocks、Presto放一起,怎么选不后悔
3.1 先看一张横向差异表
刚接触Doris的人,几乎都会问同一个问题:它和ClickHouse、StarRocks、Presto/Trino有什么区别,用哪个好?我直接上一张对比表,把差异说清楚。
| 维度 | Doris | ClickHouse | StarRocks | Trino/Presto |
|---|---|---|---|---|
| 架构 | MPP分布式,FE+BE | MPP分布式,多节点 | MPP分布式,FE+BE | 无存算一体,查询引擎 |
| 是否自带存储 | 自带,多副本 | 自带,多副本 | 自带,多副本 | 不存数据,查询外部存储 |
| 实时数据接入 | 强,支持Stream/Broker/Routine Load | 强,Kafka/文件导入 | 强,与Doris类似 | 一般,靠连接器 |
| 多维分析性能 | 强,物化视图优化好 | 很强,单表查询极快 | 强,与Doris相似 | 中等,适合联邦查询 |
| 高并发查询 | 支持不错的点查能力 | 较弱,不太适合高并发 | 支持 | 一般 |
| 多表Join能力 | 较好,CBO优化器 | 弱,尤其复杂Join较差 | 较好,继承并优化Doris | 强,尤其跨数据源 |
| 更新数据能力 | 支持,Unique模型 | 较弱,靠变异操作,成本高 | 支持,Unique模型 | 不支持写 |
| 生态与易用性 | 社区活跃,Apache顶级项目,MySQL生态 | 社区庞大,SQL方言有些特殊 | 商业公司主导,兼容Doris生态 | 数据源丰富,Java/Python生态 |
3.2 什么场景直接选Doris
我会这么建议:如果你的核心诉求是“实时数仓”和“统一OLAP分析”——数据从业务库/Kafka实时进来,业务方要通过各种维度组合秒级查报表、做自助分析,同时希望一套系统既能处理明细又能做预聚合,Doris是当前最顺手的答案。因为它把实时导入、明细存储、预聚合、高并发查询全部集成在一起,不需要你像老数仓那样拼装多套组件。
另外,如果你团队的技术栈是MySQL生态,Doris的MySQL协议兼容会让学习成本低到惊人。DBA和业务分析师都能很快上手,这也是很多企业选型时给Doris加分的隐形原因。
3.3 什么场景要谨慎选Doris
ClickHouse在单表超大规模数据集上的极速扫描和复杂聚合查询上依旧能打,如果你的场景是“只查一张超大宽表,不太需要多表Join和事务性更新”,ClickHouse值得优先考虑。而且ClickHouse的SQL方言有一些独特语法,要留出学习成本。
Trino/Presto则更适合做“联邦查询”:数据分散在MySQL、PostgreSQL、Hive、对象存储等多个系统里,你希望用一套SQL串起来查。但这种架构先天不带存储,每次查询都直接读源头数据,性能依赖下游数据源的能力,不适合做高性能交互式分析。
3.4 关于“Presto查Doris报missing”的热门问题
这个热搜词我特别留意了。实际使用场景里,很多人会用Trino/Presto做跨源联邦查询,其中就去查询Doris的数据。抛出的错误里经常出现“missing”字样,比如找不到表、找不到列。遇到这类错误,先别怀疑Doris本身,多数原因是:你在Trino/Presto侧配置的Doris连接器元数据没有正确加载或同步,比如表名大小写不匹配、Doris中的分区字段没有被连接器正确映射。
排查思路是:先在Doris客户端里确认表名和列名的精准大小写,再看Trino/Presto的查询能不能直接走MySQL方言与Doris通信。如果配置没问题,大多数“missing”都能当场解决。这个问题的本质,是“两种查询引擎之间的元数据差异”,跟Doris集群状态是否正常没有关系。
4. 部署形态与那个经典问题:只有几MB数据,要不要分桶
4.1 从单机安装到集群部署,路径其实很清晰
网上搜“doris安装部署”和“doris集群部署”的人很多,这里先把部署形态讲清楚,具体步骤后续单独展开。
Doris的最小部署是一个FE节点加一个BE节点,官方提供了编译好的二进制包,解压后改几个配置,启动进程就能跑起来。单机模式适合学习、开发调试、功能验证。我建议新手第一次接触Doris时,别直接上手复杂集群,先装一个单机版,建几张表,用数据灌一灌,把模型、导入、查询这套流程跑通,比看十篇文档都管用。
生产集群部署则要考虑:FE至少要多节点部署,避免单点;BE根据数据量和查询并发来扩容。基本路径是:先规划好服务器资源,安装JDK、配置环境,下载二进制包,配置FE的listen端口和元数据目录,启动FE,再用MySQL客户端连接做初始化,然后启动BE,在MySQL客户端里把BE节点注册到集群,最后建库建表导入数据验证。整个流程熟了,半小时左右能完成一套小集群,这放到整个“入门到上天”系列里,属于前期的“新手村任务”。
4.2 分区和分桶,到底在解决什么问题
很多人在Doris里建表时,看到“PARTITION”和“DISTRIBUTED BY HASH”就懵了。我用一句话帮大家拆清楚:分区解决“按范围管理数据”,分桶解决“按哈希均匀散列”。
分区通常是按时间范围做的,比如按天、按月。好处是查询可以分区裁剪——你想查最近三天,系统只需要扫三个分区目录,不用扫全表;同时老数据可以直接落盘归档甚至删分区,非常方便。
分桶则是在每个分区内部,再按某个列的哈希值把数据散列成若干桶。比如按“订单ID”分10个桶,一条订单进来,系统计算它的哈希值,落到对应的桶里。这样做的好处是:数据分布均匀、并行查询粒度更细、还能拿来做分布式Join优化。分桶数选得好,查询时每个BE都能摊到均衡的工作量;选得不好,就容易出现数据倾斜,个别节点忙死,其他节点闲着。
4.3 数据只有几MB,真的不需要分桶吗
这应该是Doris新手最常搜的问题之一。答案是:不需要,或者说没有必要刻意追求“多分桶”。
设计分桶数的时候,核心逻辑是“让每个桶的数据量落在合理区间”,同时“分桶数不超过BE节点总数的合理倍数”。你只有几MB数据,如果按默认经验值分出几十个桶,每个桶里就几千行数据,查询时还要在多节点间做任务调度和结果汇总,收益非常低,甚至因为分布式通信开销反而更慢。合理做法是:把分桶数设为1,或者和你BE节点数量持平,先保证查询能跑、数据能正常导入,把注意力放在模型设计上。
等数据量真的增长到单桶几GB甚至几十GB时,你再来做分桶策略的调整。这里给一个简单经验:单个桶的数据量最好在100MB到几个GB之间;分桶数不要超过BE节点数乘以某个系数(比如10);如果你的集群可能从3台扩到10台,分桶数留一点余量。实际操作中,很多人为了“以后好扩展”,一上来就设128个桶,结果小数据量场景下白白增加调度开销,效果反而不如分桶数设小一点来得划算。这一点,等我后续写《Doris集群部署与容量规划》那篇时,会再展开细讲。
5. 典型落地场景:这些业务真的可以上Doris
5.1 实时报表与分析驾驶舱
最常见的场景就是“老板要看大屏”。数据从业务库经过Canal或者DataX实时同步到Doris,Doris进行流式写入和预聚合,大屏查询直接走Doris的高性能查询通道,刷新延迟控制在秒级以内。这个场景对系统的要求是:写入要稳定、查询要快、同时能支持多个图表并发刷新。Doris的Routine Load加物化视图,正好把这三个要求都吃下来。
5.2 用户画像与行为分析
用户行为数据通常是明细流水,量极大且字段多。Doris的明细模型可以存储全量行为日志,再通过Rollup表按“用户维度”做聚合。做用户画像标签时,标签计算任务扫描全量行为数据,Doris的列式存储和向量化执行能大幅缩短计算时间;标签结果写入主键模型表,后续通过用户ID进行点查,响应速度极快。一个平台同时承担了“全量加工”和“实时查询”两个角色,技术栈自然就精简了。
5.3 湖仓一体的加速层
现在很多公司有数据湖(HDFS、S3、Iceberg),但湖的查询延迟偏高,不可能直接服务所有报表。常见方案是:数据仍然放在数据湖做统一存储和批处理,但把高频查询的“热表”通过定时同步导入Doris,由Doris承担对外提供秒级服务的角色。Doris的Multi-Catalog功能可以直接连接Hive、Iceberg、Hudi等外部数据源,支持用一条SQL在Doris里查外部表数据,这让“湖仓一体”落地变得非常平滑——不需要所有数据都搬迁进来,先把查询加速做起来。
5.4 日志分析与监控告警
日志数据分析也是Doris的强项。服务日志写入Kafka后,Doris通过Routine Load持续消费,落地到明细模型。查询时按关键字过滤、按时间聚合、按服务维度排序,秒级返回。配合告警系统,分析师还能直接对Doris做“异常检测”类的结构化查询。这个场景替代了以前“日志进ES,再导数据进数仓”的双链路,省掉一套ES存储成本,同时查询分析的表达能力更强。
6. 新手从入门到“不踩坑”的学习路径
6.1 第一步:先装一个单机版跑通流程
学Doris最快的方式,永远是自己动手装一次。我建议的学习顺序是这样的:
第一步,去Doris官网下载最新的二进制包,这步很简单,解压后即可使用。第二步,启动FE进程,再到MySQL客户端里执行几条SQL完成初始化。第三步,启动BE进程,并注册到集群。第四步,用MySQL标准协议连接Doris,建库、建表、导入几条数据、跑一个查询。
跑通这套流程后,你至少会收获四个概念上的“实感”:FE和BE分别是什么、MySQL客户端怎么连Doris、建表时的分区和分桶是怎么配置的、数据导入之后报表查询是怎么一个响应速度。这些实感,是读任何文档都替代不了的。
6.2 学Doris的“二八法则”
如果你时间有限,我建议优先掌握以下三个板块,它们覆盖了日常使用Doris的80%工作:
第一个板块是建表和数据模型。搞清楚Aggregate、Unique、Duplicate三种模型的区别,能让你建表时不纠结。第二个板块是数据导入。至少掌握Stream Load和Routine Load两种方式,前者适合单次批量导数据,后者适合持续消费Kafka。第三个板块是查询与监控。会用EXPLAIN看执行计划,会用Doris自带的监控页面看BE节点状态、查询延迟、导入任务是否堆积。这三个板块吃透,你基本已经摆脱“新手”标签了。
6.3 关于官网、文档和后续系列
很多人在搜索时喜欢直接找“doris官网”,这里提醒一句:官网入口是Apache Doris的官网,文档非常完善,包含部署、建表、导入、查询、调优等全链路说明,遇到问题先查官方文档中的“FAQ”和“操作指南”,比散落在网上的零散帖子靠谱得多。GitHub上Apache Doris的仓库也非常活跃,issues里你能看到很多真实生产场景的问题和官方维护者的回复。
这个系列叫“从入门到上天”,我不会停在概念层面。后续的文章会涵盖:单机安装到集群部署的完整实操、三类数据模型的选型逻辑、Stream Load与Routine Load的配置细节、分区分桶的容量规划、Rollup与物化视图的设计技巧、以及常见报错和性能调优实录。每一篇都以实际操作和踩坑记录为主线,我会尽量把文档里不写清楚的那些经验判断都补出来。
最后再分享一个我自己的习惯:每次接触一个新组件,我都会先在一张纸上画出它的“输入—存储—计算—输出”链条,标出每个环节负责的模块。Doris这张图里,Kafka或者业务库是输入,FE是调度者,BE是存储与计算节点,MySQL协议是连接窗口,Rollup和物化视图是加速器。把这张图放在脑子里,后面所有的问题都有了定位依据。希望你读完这篇,也能先把这个轮廓画出来,再跟我一起进入下一步实操。