ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Apache Doris是什么?从架构到选型,一文讲透实时OLAP数据库

Apache Doris是什么?从架构到选型,一文讲透实时OLAP数据库 先想一个特别真实的问题你手里的表已经不只是几千行数据了。每天有上亿条访问日志往里面灌老板随时要按渠道、按商品、按省份拉多维汇总还要能钻取到底层明细。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的集群由两类节点组成FEFrontend和BEBackend。FE是“大脑”负责接收客户端请求、解析SQL、生成执行计划、调度查询同时管理整个集群的元数据比如表结构、分区信息、副本状态。你可以把它理解成公司里的项目经理客户提需求他来拆解任务、分派给不同团队最后汇总结果。FE之间可以组成高可用组一台挂了另一台顶上。BE是“手脚”负责真正存储数据、执行计算。数据按分区和分桶打散到不同BE节点上每个BE节点并行处理自己负责的那部分数据最后把结果返回给FE聚合。BE也负责副本冗余——同一份数据默认存多个副本某个节点挂了数据不丢查询也能自动切到其他副本。这套“FE管元数据、BE管数据计算”的架构是Doris能同时做到高并发、高吞吐和线性扩展的核心。你加机器就是加BE节点数据自动重新分布查询性能跟着涨这也是Doris集群部署的价值所在。2. 核心特性拆解为什么那么多公司最后选了Doris2.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有什么区别用哪个好我直接上一张对比表把差异说清楚。维度DorisClickHouseStarRocksTrino/Presto架构MPP分布式FEBEMPP分布式多节点MPP分布式FEBE无存算一体查询引擎是否自带存储自带多副本自带多副本自带多副本不存数据查询外部存储实时数据接入强支持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 什么场景要谨慎选DorisClickHouse在单表超大规模数据集上的极速扫描和复杂聚合查询上依旧能打如果你的场景是“只查一张超大宽表不太需要多表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. 典型落地场景这些业务真的可以上Doris5.1 实时报表与分析驾驶舱最常见的场景就是“老板要看大屏”。数据从业务库经过Canal或者DataX实时同步到DorisDoris进行流式写入和预聚合大屏查询直接走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和物化视图是加速器。把这张图放在脑子里后面所有的问题都有了定位依据。希望你读完这篇也能先把这个轮廓画出来再跟我一起进入下一步实操。
返回列表