尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Share Nothing vs Share Disk:数仓架构选型核心原理与实战避坑

Share Nothing vs Share Disk:数仓架构选型核心原理与实战避坑 前两天跟朋友聊数仓选型对方问了个挺有代表性的问题“我到底该用share nothing还是share disk”我说你先别急着选这两个词是两种架构路线不是两个能直接买的产品。选错了后续扩容、事务处理、数据倾斜的坑一个接一个。这篇文章我打算把share nothing和share disk这两种架构的核心原理、代表产品、关键对比维度、以及我踩过的实战坑位一次性说透。不管你是做DBA、数据架构师还是正在给团队做技术选型的开发负责人看完应该能对这两个词有比较清晰的判断而不是停留在PPT上那些概念图里。1. 先搞清楚这两个架构到底在争论什么1.1 一句话理解一个共用资源一个各管各的我先把这两个词拆开。“Share”是共享后面跟的是共享的边界。Share Disk全称是Shared Disk指所有计算节点共享同一份磁盘数据。数据只有一份谁需要谁去读但由于多节点同时操作同一份数据必须用分布式锁、缓存协调机制来保证大家看到的内容一致。Share Nothing直译就是没有任何共享的东西每个计算节点拥有独立的CPU、内存和磁盘数据被分片放到不同节点上各自处理自己那部分数据节点之间通过网络交换中间结果。用开公司来类比。Share Disk就像一个大办公室工位随便坐但所有人都连同一个文件服务器。好处是谁坐哪个工位都一样坏处是所有人都去抢同一个服务器的吞吐协调成本高。Share Nothing就像每个员工自带一台电脑和一份业务数据各管各的片区效率高但跨片区合作时要把数据汇总总有额外的沟通成本。这两种模式没有绝对好坏只看你的团队协作方式更适合哪一种。1.2 架构分歧的本质数据与算力的边界在哪里这两个架构争论的根源是对同一个问题的不同答案数据到底放在哪里算力应该靠近数据还是共享数据从数据库史来看单机时代没有这个问题一块磁盘、一个CPU、一份数据自己玩。到了集群时代系统需要多台机器协同工作于是出现了分岔路。Share Disk选择保留“一份数据”的逻辑模型把所有复杂的一致性问题交给协调机制去解决换取应用层对数据分布的无感知。Share Nothing则选择把数据切开、分散到每台机器上让每台机器在本地处理自己的那部分数据查询天然是并行的但分布式事务、跨节点join就要额外设计。这个分歧本质上是在赌“瓶颈会出现在哪一端”如果瓶颈是存储容量和IO吞吐那Share Nothing的分布式存储天然能摊薄成本如果瓶颈是应用改造成本和事务一致性那Share Disk的透明模型更省心。我见过不少团队在选型时只盯着名字听没有想清楚自己真实的瓶颈在哪结果上线后要么性能卡在存储层要么数据倾斜把单节点拖爆。2. Share Disk架构存储集中需要“协调”来兜底2.1 核心原理与运行机制Share Disk架构的基本结构是一群计算节点也叫实例、无状态节点通过网络连接到同一个存储系统。计算节点有自己的CPU和内存本地可以缓存热点数据块但持久化数据在共享存储上。当某个节点需要的数据不在本地缓存就去共享存储读取同时通过集群范围内的锁机制或缓存协议确保数据在被修改后其他节点不能读到旧版本。这套机制的关键在于缓存一致性。多节点缓存同一份数据块后A节点改了数据B节点不知道就会读到脏块。以Oracle RAC为例它实现的是Cache Fusion机制数据块并不是直接落盘通知其他节点而是通过集群内的高速互联通常叫Interconnect直接把块传输给需要的节点。节点间通过分布式锁管理器DLM维护数据块的归属状态保证每个数据块在同一时刻只有持有对应锁的节点能修改。这样避免了频繁写盘但引入了节点间的网络传输开销所以RAC集群对网络延迟和带宽极其敏感InfiniBand或万兆网络几乎成了标配。除了缓存一致性还有锁的粒度问题。共享存储上的同一份数据如果多个节点同时想要执行事务就必须有一个全局的锁管理来协调。锁的粒度越细并发度越高但协调开销越大。这些细节是Share Disk最贵、最难调的部分也是它被诟病扩展性有限的主要原因。2.2 两个典型代表Oracle RAC 与 AWS AuroraOracle RAC是Share Disk最经典的商业实现。它允许多个数据库实例并发访问同一个数据库业务层无需感知具体实例任意实例故障后连接可以切换到存活实例实现了高可用。很多传统核心系统用RAC来做“双机热备”之外的扩展手段架构上不用改SQL也不用拆表对遗留系统非常友好但需要采购共享存储网络和排障门槛都不低。Aurora则代表了云上的另一种Share Disk思路计算节点本身不存数据只做SQL解析和执行持久化数据位于存储集群中存储层保留6个副本、分布在3个可用区写入时走Quorum机制4/6确认成功来保证不丢数据。Aurora还把redo日志下沉到存储层计算节点之间不需要共享缓存因为存储层自己会做日志应用这大大简化了计算节点间的协调。这两类实现代表了Share Disk内部的两种路线一种是“共享已落盘的数据块 缓存融合”对存储硬件要求高另一种是“共享日志 存储层自治”把一致性压力转移到存储层。后者在云上更吃香这也是很多新兴云数据库选择的路线。但本质没变——计算节点都面对同一份逻辑数据这也是它能透明扩展读能力、简化故障切换的原因。2.3 优点与坑位盘点Share Disk的优势主要集中在三点。第一对应用透明数据分片不需要业务层感知切换、扩容时不用重分布数据。第二数据只有一份事务实现相对简单不需要跨节点分布式事务所以在强一致性事务场景下体验接近单库。第三故障切换快存储是共享的计算节点无状态或低状态挂掉一个节点新节点拉起后能马上接着读同一份数据。坑位也很明显。首先是存储瓶颈所有节点都读写同一个存储系统存储的IOPS和带宽就是天花板更不要说双活存储的授权和维护费用。其次是缓存一致的协调开销Oracle RAC的网络报文极多要在高速网络环境才能压出性能。最后是水平扩展上限加计算节点能提升读但写路径和锁协调资源有限CPU堆到一定程度收益明显下降。我见过很多团队在硬件成本爆炸后才意识到与其继续堆RAC节点不如换个架构。3. Share Nothing架构各人自扫门前雪3.1 核心原理与数据分布策略Share Nothing架构的逻辑正好反过来每个节点都是完整的计算 存储单元数据按分布键被切分到不同节点上节点只处理和存储自己的那部分数据。典型的实现包括Greenplum、ClickHouse集群、Hadoop生态以及很多分布式数据库。数据分布是这类架构的核心。最常见的分布方式是Hash分布把某一列作为分布键计算hash值后按节点数取模保证数据尽量均匀地散到所有节点。还有Range范围分布按字段区间分片适合按时间分区的日志类数据。也有随机分布不保证有序但能尽量打散数据。除此之外还有复制表小维度表在每个节点复制一份专门用来避免join时的小表广播。查询执行时协调节点Coordinator / Master把SQL下推到各个数据节点各节点并行执行本地部分最后把结果汇聚到协调节点。这里最怕的是跨节点join和跨节点聚合因为输入数据不在同一个节点时必须将数据重新分发产生shuffle。这就像你把一个任务拆给10个人做大家各做各的没问题但如果中间需要互相交换材料沟通成本就上来了。3.2 多个典型实现Greenplum、ClickHouse、HadoopGreenplum是最典型的MPP数据库Master节点负责接收SQL和生成执行计划Segment节点保存数据并并行执行。建表时必须指定分布键DISTRIBUTED BY如果分布键选得不好很容易出现某几个segment数据量远大于其他节点的情况。查询时Master会把执行计划分发给所有Segment各Segment并行扫描本地数据。ClickHouse的分布式方案更轻量一点。数据本身存储在每台服务器的本地表里再在上层建一个Distributed逻辑表。查询时Distributed引擎把SQL拆成对本地表的查询下推到各个分片然后合并结果。这种模式非常灵活但需要使用者手动管理分片和副本分配不像Greenplum那样有完整的元数据管理。如果你团队里没人能玩明白ClickHouse的分片架构建议先小规模试点。Hadoop生态则贯彻“计算向数据移动”的理念。HDFS把文件切成块存在多台机器上MapReduce/Spark调度时尽量让计算任务在数据所在节点上运行减少网络传输。这里的数据本地性Data Locality是性能关键也决定了分布式文件系统更适合批处理、扫描型任务而不是高并发点查。3.3 优点与坑位盘点Share Nothing的最大优点是扩展性用普通服务器就能线性扩展存储容量和计算能力不需要昂贵的企业级存储设备。因为数据天然分散每个节点的负载是“自己的那部分”理论上节点越多总的吞吐越高。它也非常适合大数据的分析型场景全表扫描、聚合、ETL之类天然并行效率极高。坑位同样不少。第一是数据倾斜这是最经典的“理论很丰满实际很骨感”的地方。分布键选不好某个用户数据量特别大那个节点就会成为热点拖慢整个查询。第二是跨节点操作代价高join、排序、聚合如果涉及不同节点的数据都要shuffle网络带宽一吃紧性能就崩。第三是分布式事务复杂度上升多节点更新需要两阶段提交、分布式锁、全局时钟性能损失明显。第四是运维和扩容加节点后数据要重新平衡过程费时且可能影响线上服务。4. 关键维度逐项对比——一张表看清本质为了避免对话停留在概念层面我习惯用一个比较表把两个架构拉到同一频道。下面这张表基于我实际使用和测试的经验整理不能覆盖所有产品细节但方向性很强。对比维度Share DiskShare Nothing数据存储一份数据所有计算节点共享数据分片各节点独享扩展方式增加计算节点受存储和协调瓶颈限制增加数据节点存储与计算同步扩展硬件成本依赖共享存储成本高可用普通服务器成本低数据一致性单份数据锁与缓存协调保证分布式事务需要两阶段提交/全局时钟查询表现无需考虑数据分布优化简单并行能力强但受shuffle和倾斜影响故障影响存储故障影响全局计算节点故障恢复快节点故障只影响该节点数据有副本则可控典型代表Oracle RAC、AWS AuroraGreenplum、ClickHouse、Hadoop典型场景高可用OLTP、读写分离、单体数据库扩展海量数据OLAP、数仓、大数据处理这一节的后面几个小节我把表格里的结论展开讲也顺便讲讲为什么有些数据看起来不那么“一边倒”。4.1 一致性、事务与锁谁更接近“单库”体验从事务角度Share Disk天然更接近单库体验。因为数据只有一份事务涉及的数据基本都在共享存储上系统需要保证的是“多节点操作同一份数据时互不干扰”这个可以通过全局锁和缓存协议解决。Oracle RAC就是这么干的能用传统的事务语义应用几乎不需要改动。代价是锁协调的网络开销很大节点越多协调越重。Share Nothing在单节点内的事务没有问题但跨节点的事务就要两阶段提交先让所有参与节点prepare全部通过后再commit。两阶段提交的脆弱之处在于prepare之后的协调节点故障恢复以及在网络分区时会阻塞。所以很多分布式数据库都做了妥协要么限制跨节点事务比例要么用全局时钟加TCC之类的补偿方案要么像TiDB那样引入PD和TSO来维护全局一致快照但整体实现复杂度比Share Disk高一个量级。所以如果你的业务里大量操作必须强一致地跨节点更新那Share Nothing会让你付出很大代价。反过来如果你的业务主要是单点更新加上少数跨节点操作Share Nothing完全可以通过合理的分布键设计让大部分事务落在单节点把跨节点事务控制在极低比例。4.2 扩展性一个往“上加计算”一个往“外加节点”Share Disk扩展计算节点本质是增加算力但数据还在同一份存储上。所以它能提升读能力因为更多节点可以分担缓存和CPU却不容易提升写能力因为写要过共享存储和锁机制。存储IOPS就像水泵的功率加再多水龙头总流量还是被水泵限制。在存储层不升级的前提下Share Disk能支撑的节点数量是有限的Oracle RAC通常生产环境也就几个到十几个节点再往后收益锐减。Share Nothing每加一个节点等于同时增加CPU、内存和磁盘数据会重新平衡到新节点。理想情况下吞吐量和容量都能近线性增长这是它被大规模数据分析场景选中的核心原因。瓶颈主要在跨节点的通信网络上如果查询频繁shuffle网络会成为新的天花板但相比存储的硬上限网络扩容要灵活得多。4.3 查询优化与数据倾斜看起来很美分不好很痛这句话是对Share Nothing说的也是我在实际项目里最深的体会。选分布键是整个架构中最重要的决策之一。以订单表为例按用户ID做Hash分布是常规操作但如果某个大客户订单量占了全量的20%那这一个用户的数据几乎会让某个节点承担20%的负载其他节点都在等这个慢节点查询被拖垮。Share Disk没有这个问题一张表就是一份数据优化器不用考虑数据在哪个节点执行计划也不涉及跨节点搬运。但在Share Nothing下优化器需要判断join两侧数据的分布方式如果join键和分布键不一致就必须先shuffle再join。这个操作非常昂贵所以通常会把维度表做成复制表让每个节点本地都有完整的小表从而避免shuffle。这类优化技巧是真正的“架构差距之外的经验差距”。4.4 成本、运维与故障恢复账要算清楚成本不只是硬件采购。Share Disk的共享存储尤其是支持RAC的企业级SAN单TB成本远超普通服务器磁盘。加上双活、快照、高可靠性设计存储费用很容易成为项目最大的支出。Share Nothing用普通x86服务器加本地磁盘单位存储成本低很多但要付出更多的运维人力扩容重分布、数据备份、节点监控都得自己管理。故障恢复维度也要分场景。Share Disk的存储是单点一旦存储挂了整个业务断掉所以在存储层要做好高可用设计故障切换的RPO/RTO通常能做到很低。计算节点故障则非常友好任何计算节点都可以接管同一个存储。Share Nothing中单个节点挂了只影响它持有的那部分数据分片有副本的情况下可以自动切换副本但节点数据重新同步到新机器需要时间期间分片副本可能处于降级状态。5. 选型思路与实践经验分享5.1 事务型负载别为了“分布式”而分布式我在做技术咨询时最常劝退的一种情况就是核心交易系统单机数据库其实压力还没到极限但架构评审会上有人提出“别人都在分布式了我们也不能落后”于是开始选型Share Nothing分布式数据库。结果业务模型里大量关联更新上线后分布式事务性能不达标团队不得不改应用代码、拆分业务流程项目延期半年起步。事务型负载的正确姿势是优先把单机数据库的优化做透索引是否合理、读多写少要不要读写分离、是否能用缓存抵挡重复查询。如果单机确实扛不住再考虑能不能用Share Disk解决——因为它对事务语义破坏最小对应用最透明。只有在数据量和并发量都大到Share Disk撑不住的时候才应引入Share Nothing并且提前评估跨节点事务占比和分布键方案。这个顺序不该乱。5.2 分析型负载share nothing是正确的方向但要多花心思如果你的核心场景是几百GB到几十TB的报表、ETL、行为分析、数仓建模那Share Nothing MPP数据库几乎是当前主流答案。Greenplum、ClickHouse、以及云上的数仓服务本质上都是这个思路。数据量大时全量扫描和聚合天然适合分而治之这和Share Disk要处理锁协调和存储瓶颈的路子完全是两个方向。但在上线前一定要多花时间做三件事第一认真设计分布键可以先拿真实数据的分布跑一遍模拟避免倾斜第二把join的场景梳理一遍把小维度表做成复制表把常用join键和分布键对齐第三把网络规划做足跨节点shuffle是常态万兆网络是基本盘不要在这个地方省钱。我见过客户因为机柜内部是千兆网络跑一个多表join的ETL任务要六个小时换成万兆后直接掉到四十分钟。5.3 云原生数据库其实早就开始“融合”了现代云原生数据库出现后两边不再是二选一。以Snowflake和AWS Aurora为代表的产品采用存储计算分离架构计算节点层是Share Nothing的各自处理不同的查询任务互不干扰存储层则是共享的数据文件统一存放在对象存储或分布式存储上。它把两者的优点合了起来计算节点可以按查询需求独立伸缩存储按容量计费数据只有一份在存储层天然不需要做数据分片时给应用暴露复杂性。当然代价是计算节点访问“远程存储”的数据可能带来更多的网络时延和缓存命中的问题所以很多系统又做了数据缓存层、结果缓存、热数据本地化等优化。这是目前很多团队实际在用的架构形态也说明Share Nothing和Share Disk不是对立的敌人而是可以组合的方案组件。5.4 我踩过的几个真实的坑最后分享几个我在实际中遇到的坑不是为了劝退而是希望大家少交点学费。第一个坑是数据倾斜。当时做一个用户行为分析平台用户维度表按user_id hash做了三个月后一个头部渠道贡献了几亿条行为记录对应节点磁盘快满了查询性能雪崩。后来才重视分布键选择加了一个二级维度把热点用户拆分。第二个坑是跨节点join。系统里有几十个G的大表和几万行的小表做join最初没有把小表设成复制表每次查询都触发广播和shuffle慢到没法用。改成复制表之后流畅很多。这是Share Nothing下回报率最高的性能优化之一。第三个坑是在非必要场景上了分布式事务。有个内部系统事务涉及三个节点按两阶段提交实现后数据量一大prepare和commit之间等待时间变长客户体验明显下滑。后来重构成单节点事务加异步补偿反而简单可靠。不是分布式事务没有价值而是它只该用在真正需要的地方。架构选型这件事最终还是要回归到自己的业务负载、团队能力和运维投入来选。不要被概念带着走先把你当前最痛的瓶颈列出来再回头看看哪个架构能对症下药。希望这些经验能有点帮助。
返回列表