ARTICLE DETAIL

资讯详情

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

MPP架构深度解析:从单机瓶颈到大规模并行处理的工程实践

MPP架构深度解析:从单机瓶颈到大规模并行处理的工程实践 1. 从一次数据爆炸的深夜告警说起凌晨两点手机屏幕亮起一条告警信息弹了出来某张核心报表的查询耗时从平均3秒飙升到了47秒下游依赖它的三个看板全部超时。我爬起来连上服务器打开执行计划一看问题很典型——单机数据库的CPU被打满了而那条SQL本身写得并不差只是它要扫描的事实表已经悄悄涨到了八亿行。那一刻我很清楚这不是加个索引或者调个参数能解决的事这是单机架构撞到了物理天花板。这个场景就是MPPMassively Parallel Processing大规模并行处理要登场的时刻。如果你正在处理TB甚至PB级别的数据分析任务如果你发现单机数据库再怎么优化都追不上数据增长的速度如果你听说过Greenplum、Doris、StarRocks、ClickHouse这些名字但还没搞明白它们到底共享着什么底层逻辑那这篇内容就是写给你的。我会从MPP到底是什么讲起把它的架构拆开揉碎再聊聊不同平台对它的支持情况中间穿插我自己踩过的坑和总结出来的判断方法。先说结论MPP不是某一个具体产品而是一类架构思想。它的核心就一句话——把一个大任务拆成很多小任务让很多台机器同时干最后把结果汇总起来。听起来简单但真正落地时数据怎么分、任务怎么调度、节点之间怎么通信、失败了怎么恢复每一个环节都藏着大量的设计取舍。这些取舍决定了你选的MPP系统到底适不适合你的业务场景。2. MPP到底是什么把人多力量大翻译成工程语言2.1 一个生活化的类比从一个人搬砖到一支施工队想象你要搬一万块砖从A地到B地。一个人搬哪怕他是大力士也得搬一万趟这就是单机数据库的处境——CPU、内存、磁盘IO都是有限的数据量涨到一定程度再强的单机也扛不住。MPP的做法是找一百个人每人搬一百块同时开工。但这里立刻出现几个新问题。第一砖怎么分是每人随机拿一百块还是按某种规则分配第二如果有人搬得慢其他人要不要等他第三搬完之后怎么确认一万块一块不少第四如果中途有人请假了怎么办这四个问题对应到MPP系统里就是数据分布策略、任务调度与负载均衡、结果汇总与一致性保证、故障恢复机制。任何一个MPP产品的架构设计本质上都是在回答这四个问题。你评价一个MPP系统好不好也是看它在这四个维度上做得怎么样。2.2 MPP的精确定义与三个核心特征从工程角度给MPP下个定义MPP是一种由多个独立节点组成的分布式计算架构每个节点拥有自己的CPU、内存和存储资源节点之间通过高速网络互联协同完成同一个查询或计算任务。注意这里的独立很关键——每个节点不共享内存也不共享磁盘这叫Share-Nothing架构是MPP最本质的特征。它有三个绕不开的核心特征。第一个是并行执行一个查询会被拆分成多个子任务分散到不同节点上同时运行。第二个是数据分片数据不是存在一个地方而是按照某种规则分散在各个节点上。第三个是分布式协调必须有一个机制来统筹所有节点的行为保证大家朝着同一个目标努力。这三个特征听起来是优点但每一个都带来了相应的代价。并行执行意味着要处理节点间的同步问题数据分片意味着某些查询需要跨节点搬运数据分布式协调意味着引入了单点故障的风险。理解MPP本质上就是理解这些优点的代价以及不同产品是如何在这些代价之间做取舍的。2.3 MPP与相关概念的边界划分很多人容易把MPP和几个相邻概念搞混我在这里做个清晰的切分。MPP vs 分布式数据库分布式数据库是一个更大的范畴它包含MPP但也包含那种每个节点都能独立处理事务的架构比如分库分表中间件。MPP更强调并行协作完成单个大任务而广义分布式数据库还包括多个独立任务分散处理的模式。MPP vs Hadoop/SparkHadoop的MapReduce也是并行处理但它采用的是移动计算到数据的模式中间结果大量落盘适合批处理但对交互式查询不友好。MPP系统通常把中间结果尽量放在内存里追求更低的查询延迟。不过现在两者在融合Spark SQL、Presto这些引擎也在借鉴MPP的执行模型。MPP vs 列式存储这是两个不同维度的概念。列式存储说的是数据在磁盘上怎么组织MPP说的是计算怎么并行。你可以有行存的MPP也可以有列存的单机数据库。但实践中MPP系统往往搭配列式存储因为分析型查询通常只涉及少数几列列存能大幅减少IO。3. MPP架构拆解从SQL到结果的完整旅程3.1 整体架构分层理解MPP的骨架一个典型的MPP系统在逻辑上分为三层。最上层是接入层负责接收客户端连接、解析SQL、做权限校验。中间是协调层也叫Master节点或Coordinator负责生成执行计划、调度任务、汇总结果。最下层是计算层由多个Worker节点组成每个节点负责处理分配给自己那部分数据和计算。这个三层结构是逻辑上的物理部署时可以灵活调整。小规模场景下协调层和计算层可以混布在同一批机器上大规模场景下协调层通常独立部署甚至做高可用主备。我见过一些团队为了省钱把协调节点和计算节点混在一起结果一个复杂查询的协调开销把计算节点的资源也吃掉了查询性能反而下降。这个坑后面会详细说。数据在这三层之间流动的过程就是一次查询的完整生命周期。客户端发来SQL接入层解析后交给协调层协调层生成分布式执行计划把计划拆成多个片段下发到各个WorkerWorker并行执行后把结果返回给协调层协调层汇总后再返回给客户端。整个过程听起来线性但实际执行时Worker之间可能还需要互相交换数据这就引出了下一个关键话题。3.2 数据分布策略决定性能的第一道关卡数据怎么分布到各个节点上是MPP架构里最重要的设计决策之一因为它直接决定了查询时需不需要跨节点搬数据。常见的分布策略有三种。哈希分布是最常用的。选一个或多个列作为分布键对键值做哈希运算根据哈希值决定数据落到哪个节点。好处是数据分布均匀等值查询能精确定位到单个节点。坏处是如果查询条件不包含分布键就需要把数据广播到所有节点网络开销巨大。范围分布是按照某个列的取值范围切分数据。比如按日期分一月的数据在节点A二月的数据在节点B。好处是范围查询效率高坏处是容易数据倾斜——如果某个月的数据量特别大那个节点就会成为瓶颈。随机分布也叫轮询分布数据随机打散到各节点。好处是绝对均匀坏处是任何查询都需要扫描所有节点因为无法预判数据在哪。实操心得分布键的选择是MPP调优的第一优先级。我的一般原则是选那些在JOIN条件和WHERE条件中高频出现的列作为分布键。如果一张表经常按用户ID查询和关联那就用用户ID做分布键。如果找不到这样的列说明这张表可能不适合用MPP来存或者需要重新审视数据模型。3.3 执行计划与任务调度协调节点的核心职责协调节点收到SQL后要做的事情远比单机数据库复杂。它需要生成一个分布式执行计划这个计划不仅要说明做什么还要说明在哪里做和怎么汇总。生成计划的过程大致分几步。首先是解析与绑定把SQL文本变成抽象语法树再绑定到具体的表和列上。然后是逻辑优化做谓词下推、列裁剪、常量折叠这些通用优化。接着是物理计划生成决定每个操作在哪几个节点上执行需不需要数据重分布。最后是计划切分把物理计划切成多个片段每个片段对应一个或多个Worker上的任务。这里最复杂的是数据重分布决策。当两个表做JOIN但分布键不一致时协调节点必须决定是把小表广播到大表所在的每个节点还是把两个表都按照JOIN键重新哈希分布。这个决策直接影响查询性能好的MPP系统会根据表的统计信息自动选择但统计信息不准时也会选错。3.4 节点间通信与数据交换看不见的性能杀手MPP系统里节点间的数据交换是性能损耗的主要来源之一。这种交换有两种典型模式广播和重分布。广播是把一个小表的数据复制到所有节点。适合小表JOIN大表的场景但如果小表其实不小广播就会变成网络风暴。我曾经遇到过一个案例一张号称小表的维表实际有800万行被广播到200个节点每次查询光是网络传输就花了十几秒。后来改成重分布性能立刻恢复到秒级。重分布是把两个表都按照JOIN键重新哈希让相同键值的数据落到同一个节点。好处是网络传输量可控坏处是需要额外的计算和IO来重新分布数据。选择广播还是重分布核心判断依据是广播的数据量乘以节点数是否小于重分布的数据量。这个计算不复杂但很多人在写SQL时根本不会去想。节点间通信通常走两种通道一种是控制通道传输任务状态、心跳、元数据数据量小但要求低延迟另一种是数据通道传输实际的数据块数据量大但可以容忍一定延迟。好的MPP系统会把这两个通道分开避免控制消息被大数据块阻塞。4. 主流MPP平台支持与选型对比4.1 传统企业级MPPTeradata与GreenplumTeradata是MPP领域的鼻祖级产品它的架构非常经典完全无共享每个节点独立处理自己的数据和计算通过BYNET网络互联。Teradata的优势在于成熟稳定优化器非常强大在金融、电信这些对数据一致性要求极高的行业有大量部署。但它的缺点也很明显封闭生态、价格昂贵、扩展性受限于专有硬件。Greenplum是基于PostgreSQL的开源MPP数据库架构上借鉴了Teradata的思路。它的优势是开源、生态好、和PostgreSQL兼容度高很多PostgreSQL的运维经验可以直接复用。Greenplum的Master节点负责协调Segment节点负责计算通过Interconnect网络通信。我实际用下来Greenplum在几百TB级别的场景下表现稳定但到了PB级别Master节点容易成为瓶颈需要做额外的优化。4.2 新一代云原生MPPDoris、StarRocks与ClickHouseDoris和StarRocks都是国内团队主导的开源MPP数据库架构上做了很多现代化改进。它们采用FEFrontend和BEBackend分离的架构FE负责元数据管理和查询规划BE负责数据存储和计算。相比Greenplum它们的优势在于更好的实时写入能力、更灵活的扩缩容、以及更现代的向量化执行引擎。ClickHouse比较特殊它严格来说不完全是MPP因为它的分布式表需要依赖ZooKeeper或ClickHouse Keeper来协调而且JOIN能力相对弱。但它在单表聚合查询上的性能非常惊人适合日志分析、监控指标这类场景。如果你的业务以宽表聚合为主ClickHouse是很好的选择如果涉及复杂的多表JOINDoris或StarRocks可能更合适。4.3 平台支持对比与选型决策表维度TeradataGreenplumDorisStarRocksClickHouse开源否是是是是部署复杂度高中低低中实时写入弱中强强强多表JOIN强强强强弱扩缩容难中易易中生态兼容封闭PostgreSQLMySQL协议MySQL协议自有协议适用规模PB级百TB级百TB级百TB级十TB级选型时我的建议是先看数据规模和查询模式再看团队技术栈最后看运维成本。如果团队已经有PostgreSQL背景Greenplum上手最快如果追求实时性和易运维Doris或StarRocks更合适如果只是做日志聚合ClickHouse性价比最高。5. 实操中常见的坑与排查思路5.1 数据倾斜最隐蔽的性能杀手数据倾斜是MPP系统最常见也最头疼的问题。表现是同一个查询有时快有时慢或者某些节点CPU打满而其他节点很闲。根因通常是分布键选择不当导致大量数据集中在少数节点。排查方法很直接查每个节点的数据量和CPU使用率。如果发现某个节点的数据量是其他节点的几倍基本可以确认是倾斜。解决方法有几种换分布键、对倾斜键加盐、或者改用随机分布。加盐的做法是在分布键后面拼接一个随机数把热点数据打散但代价是查询时需要额外处理。注意事项加盐不是万能药。它会让等值查询变成范围查询可能反而降低性能。我一般优先考虑换分布键实在找不到合适的才用加盐。5.2 统计信息过期优化器瞎指挥的根源MPP的优化器依赖统计信息来做决策比如判断一个表是大表还是小表、选择广播还是重分布。如果统计信息过期优化器就可能做出错误决策。我遇到过最离谱的一次一张实际有5亿行的表统计信息还停留在500万行优化器把它当成小表广播结果查询直接跑挂。解决办法是定期收集统计信息尤其是在大批量数据导入后。大多数MPP系统都提供了ANALYZE命令可以手动触发也可以配置自动收集。但自动收集有延迟关键表建议在ETL流程里显式调用。5.3 常见问题速查表现象可能原因排查方向解决思路查询突然变慢统计信息过期检查统计信息更新时间手动ANALYZE部分节点CPU高数据倾斜查各节点数据量分布换分布键或加盐网络流量异常广播了大表看执行计划中的广播操作改用重分布协调节点瓶颈并发查询过多看协调节点资源使用限流或增加协调节点写入性能差小批量频繁写入看写入批次大小攒批写入5.4 一个真实的排查案例有一次业务方反馈某个报表每天早上9点准时变慢其他时间正常。我一开始怀疑是并发问题但查了监控发现9点的并发并不比其他时间高。后来仔细看执行计划发现这个报表的SQL里有一个JOINJOIN的右表是一张按日期分区的表而9点正好是前一天数据导入完成的时间点。数据导入后统计信息没更新优化器还以为右表很小选择了广播策略结果广播了一张实际很大的表。解决方式很简单在ETL流程的最后加一步ANALYZE。但排查过程花了两个小时因为一开始没往统计信息的方向想。这个案例告诉我MPP的问题排查一定要先看执行计划执行计划里藏着大部分答案。6. 我对MPP架构的一些个人理解MPP不是银弹它解决的是数据量大到单机处理不了的问题但代价是引入了分布式系统的复杂性。我在实际工作中最大的体会是MPP的性能上限取决于最慢的那个节点。这就像一支队伍行军速度取决于最慢的那个人。所以数据分布的均匀性、节点配置的一致性、网络带宽的充足性这些木桶短板比单个节点的性能更重要。另一个体会是MPP的调优是一个持续的过程不是一次性的配置。数据在变、查询模式在变、业务需求在变今天的最优分布键明天可能就不适用了。所以建立一套监控和定期review机制比一次性调优更有价值。最后分享一个小技巧如果你不确定一个查询会不会触发数据重分布可以在执行计划里搜索exchange或redistribute关键字。如果出现了说明有节点间数据搬运这时候就要评估这个搬运是否必要、是否可以用其他方式避免。这个习惯帮我省下了很多次性能排查的时间。
返回列表