ARTICLE DETAIL

资讯详情

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

集群和分布式有何区别?架构形态、核心机制与实战选型解析

集群和分布式有何区别?架构形态、核心机制与实战选型解析 1. 先搞清楚的第一个问题它们到底是同一个东西吗我见过太多刚入行的同学一聊到分布式和集群就含糊其辞。有的说“集群不就是多台机器一起干活嘛分布式也差不多”有的干脆回答“分布式就是集群的升级版”。这两种说法都对一半但对的那一半恰恰是最容易误导人的地方。作为整天和服务器、服务进程打交道的从业者我可以明确告诉你分布式和集群描述的不是同一个维度的问题。分布式描述的是“系统的架构形态”即一个业务系统被拆成多个独立模块部署在不同机器上协同工作集群描述的是“系统的部署密度”即同样的服务或模块启动了多个实例来共同承担压力或提供冗余。用一个生活化类比一个餐饮连锁品牌总店负责菜品研发、中央厨房负责半成品加工、各门店负责出餐和外卖这叫分布式——整个生意被拆成不同职能的部门各干各的但又互相配合。而同一家店在写字楼A座和B座各开了一个窗口卖一样的饭、用一样的配方这叫集群——同一个业务能力多份部署。但要注意这两者往往同时出现。生产环境里几乎不存在“纯分布式”或“纯集群”新手的理解难点不在于背定义而在于看透它们之间的协作关系集群可以分布分布式通常也用集群来支撑。这本书我们拆开聊透。1.1 为什么总有新手搞混根源在于“分布式系统”这个词的使用混乱你去搜资料会发现中文互联网对这两个词的解释五花八门原因主要在“分布式”这个前缀到处乱贴。微服务架构叫分布式系统Hadoop叫分布式系统分布式缓存也带分布式三个字甚至多线程任务拆分也有人叫分布式计算。而集群这个词也很惨Redis集群、Kafka集群、MySQL集群、K8s集群凡是多个节点凑一起都叫集群。词义覆盖范围重叠是新手混淆的第一根源。但实际代码和运维层面两者的差异极其明显。分布式关注的是“拆分”和“协同”集群关注的是“复制”和“调度”。一个需要解决的是服务发现、远程调用、数据一致性、分布式事务另一个需要解决的是负载均衡、健康检查、故障转移、水平扩展。举个我在面试中常问的例子假设公司要做一个订单系统单体应用跑了三个月用户量上来了性能扛不住。方案一把同一份代码部署到5台服务器上前面加个Nginx做负载均衡——这是典型的集群扩容。方案二把订单系统拆成用户服务、商品服务、订单服务、支付服务四个进程分别部署在不同机器上通过网络通信协作——这是典型的分布式架构。一个是“一个服务多副本”一个是“一个系统多模块”差异一目了然。1.2 一句话版本先行集群是“多干”分布式是“分工”如果你只记一句话我建议记这个集群解决的是“一台机器不够用那就多来几台分担”分布式解决的是“一个系统太复杂那就拆成多个模块解耦”。集群里的每个节点都能独立完成全部工作互为备份挂了一个剩下的继续顶上分布式里的每个节点只负责自己的那部分职责挂了整个功能就可能不可用所以分布式环境下的每一个服务节点通常又需要再做一个集群来保障高可用。这两者是互补关系而不是同一概念的两个阶段。2. 集群多台机器干同一件事为了讲透区别我得先从“集群”开始细拆。集群这个概念比“分布式”更好理解也更贴近底层基础设施。说白了集群玩的就是“人多力量大”和“相互替班”。2.1 集群的分类高可用集群、负载均衡集群、高性能计算集群业内聊集群通常会分成三类高可用集群HA Cluster核心目的是避免单点故障。两台机器跑同一个服务一台挂了另一台接管业务用户无感知。典型代表是KeepalivedVIP、MySQL主从切换、Redis Sentinel哨兵模式。负载均衡集群LB Cluster核心目的是分担压力。多台机器同时对外提供服务入口由负载均衡器分发请求。典型代表是Nginx反向代理背后挂多个Tomcat或云上的SLB挂多台ECS。高性能计算集群HPC Cluster核心目的是把海量计算任务并行化。计算节点动辄成百上千台任务通过调度器分散到各节点上并行跑典型代表是科研计算用的Slurm集群、大数据分析用的Hadoop集群。高可用集群关注的是“别挂”负载均衡集群关注的是“分担”高性能计算集群关注的是“加速”。千万不要以为集群就是简单地把多台服务器堆在一起不同目标的集群架构设计和运维手段完全不一样。2.2 集群里最核心的机制调度、健康检查、故障转移一个集群能不能在工作判断标准只有一个当一个节点挂了系统的对外能力有没有受损。这套能力依赖三个核心机制的配合。调度机制决定请求发给谁。如果是L4/L7负载均衡调度算法有轮询、加权轮询、最小连接数、IP哈希等如果是自研集群可能要自己实现一致性哈希路由。我做过一个内部任务调度集群用的就是加权轮询加最小负载综合评分避免某些机器被流量热点打成热点机。健康检查机制决定节点是否还能接活。常见做法是TCP端口检测、HTTP接口探活、自定义Agent上报心跳三种。注意这里的坑TCP端口通不代表服务健康我曾经遇到过端口正常但线程池已满的情况直到把健康检查从“端口检测”升级成“接口探活线程池占用率上报”才彻底解决假死问题。故障转移机制决定挂掉之后谁来接盘。高可用集群通常靠VIP漂移或自动选主动比如ZK的Leader选举无状态集群直接由负载均衡器把流量摘掉其他节点自动多扛一些有状态集群则麻烦得多比如MySQL主从切换要处理数据补齐、Binlog回放、从库提升为主库等一系列动作一不留神就会丢数据。2.3 集群是分布式的基础但不是全部我见过不少创业公司一开始就堆集群数据库一主两从、应用5台起步、Redis搞个哨兵表面上看起来挺“高可用”。但等到业务模块越来越多、研发团队扩张之后问题就来了所有应用都复用同一个数据库一个慢SQL把整个系统拖垮订单逻辑和支付逻辑耦合在一个进程里支付一抖订单跟着挂代码越来越臃肿改一行代码要回归整个系统。这种单服务多副本的集群架构大家称为“单体集群”。它能扛住并发扛不住复杂度。真正的转折点是当系统需要由不同团队各自独立迭代时单体集群的耦合问题就会成为生产的最大阻力——这就是为什么要走向分布式架构。3. 分布式把一件事拆成很多件分给不同机器聊完集群再来看分布式理解起来会更清晰。分布式系统的定义可以概括为多个自治的计算节点通过网络通信与协调共同完成一个整体任务。重点在“自治”和“协调”这两个词——每个节点独立运行节点之间没有共享内存只有网络消息传递要通过协作来保证整体对外表现像一个系统。3.1 分布式系统的几个典型形态先看几个主流形态你不用背定义理解场景就能记住。分布式计算把一个巨型任务拆成很多小任务分发给多台机器并行计算再汇总结果。Spark的MapReduce、Ray的分布式训练都是这个思路。分布式存储把数据分片存储到多台机器上每台只存一部分通过一致性协议保证副本一致。HDFS、Ceph、Minio集群都属于这一类。分布式应用微服务按业务边界把系统拆成多个服务每个服务独立部署、独立迭代通过RPC或消息队列通信。这是目前互联网公司最普遍的形态。分布式协调为上述系统提供共识、锁、配置管理、命名服务等底层能力典型代表是ZooKeeper、etcd。注意分布式系统的“分布式”体现在“多个节点协作”而每个节点本身往往又需要以集群的方式做高可用和负载均衡。所以前面我说分布式和集群是互补关系而不是互斥概念。3.2 分布式架构带来的核心难点分布式不是免费午餐它解决了很多问题的同时也带来了单调架构不需要操心的麻烦。我列几个你迟早要面对的第一网络是不可靠的。两台机器之间的请求可能丢失、延迟、乱序也可能一台机器处理完但响应丢了调用方就以为失败了。这导致“是否真的执行成功”成了一个需要协商的问题。分布式系统所有复杂性的根源基本都在这里。第二数据一致性难以保证。多个副本之间如何同步主节点和从节点什么时候能看到相同的数据一台机器写成功了另一台还没来得及同步用户就可能读到旧数据。这个问题的通用解法牵扯到一致性协议比如Raft、Paxos以及工程上的妥协方案——最终一致性。第三分布式事务极其麻烦。一个请求跨多个服务每个服务有自己的数据库如何保证所有库要么一起成功、要么一起回滚分布式事务的解决方案2PC、TCC、Saga、本地消息表等各有适用场景没有银弹。第四排错难度大幅度上升。一个请求从网关进来调用A服务再调B服务再调C服务全程要串联日志、追踪调用链路没有全链路监控系统的话出了问题就像在迷宫里找一只蚂蚁。3.3 分布式场景下经常出现的名词分布式锁、分布式事务、分布式任务调度结合前面提到的热搜词这几个是面试和实战中都绕不开的我展开聊一下。分布式锁解决的是“多个进程/多台机器同时操作共享资源”的问题。单机时代用synchronized或ReentrantLock就够了但分布式环境下锁必须放在所有节点都能访问到的第三方组件上。主流实现有Redis分布式锁SETNX过期时间进阶用Redisson的红锁、ZooKeeper分布式锁临时顺序节点、数据库乐观锁。我在实践中更推荐优先考虑业务上能否规避冲突比如通过请求幂等键、唯一索引等方式从源头避免加锁。必须加锁的时候一定要设计好锁的自动释放机制防止持锁节点宕机导致死锁。分布式事务解决的是跨服务的数据一致性问题。场景最典型的就是订单和库存用户下单扣库存订单服务和库存服务是两个独立的系统怎么保证订单创建成功了库存一定扣减成功业界方案五花八门2PC的强一致方案只适用于对一致性要求极高的内部系统因为同步阻塞性能和可用性都不可接受实际业务里用得最多的是最终一致比如本地消息表、事务消息RocketMQ事务消息、Saga长事务补偿。核心思路是别强求一步到位只要最终数据一致期间允许短暂的中间状态。分布式任务调度解决的是多台机器上定时任务重复执行的问题。单体时代用Quartz就搞定但分布式环境下同一套代码部署了多份定时任务如果用原生的Quartz每个节点都会触发一次执行结果就乱套了。解决方案是XXL-JOB、ElasticJob这类框架通过数据库锁或ZooKeeper来实现“同一时间只有一个节点执行任务”的调度语义。4. 核心区别的5个维度一张表讲透到了这里我觉得最有用的就是把区别摆到同一个坐标里对比一遍。我做了这么多年架构最怕的就是用“概念”解释“概念”所以我更倾向用维度去对照。对比维度集群分布式关心的问题一台不够多台来凑容量/可用性一团乱麻拆分治理复杂度/扩展性节点关系每个节点职责相同互为备份每个节点职责不同分工协作数据存放每个节点通常持有全量数据副本数据按业务/分片逻辑拆分存储是否必须网络通讯节点间不一定要通信LB集群就很少节点间通信节点间必须频繁通信和协调典型失败模式某个节点宕机集群自动摘除整体不受影响单个节点故障可能影响整条链路需要强治理4.1 维度一从“服务或数据的形态”看差异集群里的每个节点拥有相同的服务代码和数据副本形象一点说就是“人人手里都有一本完整教材谁讲都一样”。分布式系统则把教材拆成不同章节不同节点各持一部分谁缺了别人手里的内容得通过网络去问。数据形态差异最明显的例子MySQL主从集群中从库是主库的完整拷贝而一个微服务系统中订单服务和用户服务各自拥有独立的数据库数据是彻底隔离的。这就是集群和分布式在架构层面最大的分水岭。4.2 维度二从“节点故障后的影响”看差异集群节点故障理论上被摘除即可因为还有别的节点能接活。有一种特殊情况是有状态集群比如Redis集群中某个主节点挂掉其负责的槽位slot需要自动迁移到其他主节点但即使如此整体能力在设计上不会缺失。分布式节点故障可怕的是链路断裂。比如一个请求必须经过A→B→C三个服务B挂了A和C再健康也没用。所以分布式系统必须额外做到服务降级、熔断、限流、超时控制、重试机制等等这些在集群场景里根本不是重点在分布式场景里就是生命线。4.3 维度三从“扩展方式”看差异扩展集群很简单把代码拷一份多部署一台配置好负载均衡即可。而且集群扩展大多是“无脑横向扩”只要服务是无状态的加机器就能顶流量。分布式扩展更复杂因为它牵扯到按业务模块拆的维度。某个模块流量高了可以给这个模块单独加机器做集群但模块之间的调用链、数据边界、事务边界一旦没设计好扩展一个模块就可能连带影响其他模块。很多公司从单体拆微服务之后发现性能反而下降了就是因为分布式带来的网络开销和协调开销没有控制好。4.4 维度四从“一致性问题”看差异集群因为有副本核心问题就是副本之间的数据一致性。主写从读、强一致还是弱一致、脑裂了怎么处理都是集群设计里绕不开的话题。分布式系统的一致性范围更大不止包括副本还包括不同服务各自持有的数据之间的业务一致性。简单来说集群的一致性解决的是“同一个数据的多个拷贝是否一致”分布式一致性解决的是“多个不同数据之间的业务逻辑是否满足预期”。后者复杂度高一个量级所以才会引出分布式事务这种专门领域。4.5 维度五从“监控与运维”看差异集群的监控相对简单看节点存活、看负载、看流量分配是否均匀。分布式系统的监控则要落到链路层面一个请求从网关到最终落库经过了哪几个服务、每个服务耗时多少、哪里出现慢调用这需要有完整的链路追踪体系和调用拓扑图否则生产出了问题只能靠人肉瞪眼。我强烈建议凡是搞分布式架构的团队第一优先级先把日志规范和监控体系做起来——这比任何业务功能都重要。等到线上真出事的时候再补监控成本高十倍不止。5. 真实世界里一个秒杀系统是怎么把两者揉在一起的概念讲多了容易空我拿一个完整的业务场景把集群和分布式串起来讲——秒杀系统。这个场景几乎涵盖了前面聊的所有要素。5.1 请求接入层的集群用户请求先到Nginx或SLB这一层这一层必须做集群多台入口机同时接流量。这个集群不关心业务逻辑只负责把请求转发到后面的应用服务。因为入口网关是无状态的所以扩容极其简单压力大就多加几台前面挂个负载均衡完事。5.2 业务服务的集群化真正的秒杀业务逻辑比如校验用户身份、读商品信息、校验库存、生成订单这些通过Spring Boot之类的框架写出来的服务也会部署多个实例组成集群。同一个商品详情请求可能落到任意一个实例上每个实例都能独立完成整个业务流程至少在不拆微服务的前提下。这个阶段如果系统架构本来就是微服务那每个微服务自身的部署形态仍然是“集群”而微服务之间的协作关系才是“分布式”。5.3 缓存与存储的分布式集群秒杀场景下数据库肯定扛不住得用Redis做前置缓存。生产环境的Redis几乎是标配集群三主三从数据按槽位分片存储主节点负责读写从节点负责备份和故障切换。你看这一层既是集群多节点、副本又是分布式槽位分片、数据不重复两个概念在这一层真正融为一体。数据库层面单库肯定扛不住秒杀常见做法是分库分表把订单表按用户ID哈希拆分到多个库这就是“数据拆分”属于分布式存储的范畴。但每一个分片背后又往往要做主从复制这是典型的集群高可用方案。5.4 底层协调依赖的分布式组件秒杀入口要防超卖用户点了立即购买多个请求可能同时落到不同的应用实例上如果都去数据库扣库存必须用分布式锁保证同一时刻只有一个请求成功扣减。再比如下单成功后要发消息给下游物流系统做异步处理消息队列Kafka/RocketMQ本身也是集群部署。这些底层组件服务于整个分布式架构让你真正体会到什么叫“基建先行”。所以我经常跟团队说不要争论“我们到底要上集群还是分布式”成熟的生产系统一定是两层叠加。集群解决容错和压力分布式解决拆分和解耦。6. 选型错误会怎样我见过的事故分享几个我实际见过或经历过的坑帮大家厘清思路。6.1 该做集群的做了分布式过度设计有一家公司的业务体量并不大单库单表也能跑主从复制加个读写分离就足够了。但技术团队非要搞微服务拆分把用户、订单、支付、库存拆成六个服务还各自建库。结果每次业务发布要协调六个团队的迭代节奏排查一个用户问题要翻六个服务日志线上的稳定性反而不如单体。这个案例的教训是分布式是手段不是目的。业务复杂度不够时单体加集群是最好的选择。只有单个模块逻辑已经足够复杂、团队规模已经能支撑独立运维再考虑拆分布式收益才能大于成本。6.2 该做分布式的硬堆集群治标不治本另一家公司的情况恰好相反。业务逻辑已经严重耦合订单模块、支付模块、库存模块全写在一个工程里一个进程运行数据库共用一张大表。并发上来了他们的应对策略永远是加服务器、加数据库从库但每次扩容都只能撑两到三个月然后继续扩容开发迭代越来越慢。这就像厨房很小菜式很多明明应该扩建厨房或分设几个操作间结果只靠增加厨师人数来硬顶。厨师多了不但没变快反而互相绊脚。这种系统的正确解法是把订单、支付、库存拆成独立服务做成分布式架构再配合消息队列削峰才能真正解决问题。6.3 集群切换没做演练主从切换直接丢数据这是我特别想强调的运维经验。有一家做电商的公司MySQL主从架构从库作为实时备份平时看起来一切正常。某天主库所在服务器硬件故障运维执行主从切换结果发现数据不一致主库还有最近两分钟的事务没同步到从库。切换之后这两分钟的数据就丢了。原因并不复杂半同步复制没开启默认的异步复制模式下主库提交事务成功就返回了从库回放有一定延迟。虽然概率很低但真碰上了就是生产事故。这个案例虽然不是纯分布式问题但它反映的是集群架构里最容易被忽视的一点高可用不等于数据零丢失任何集群方案都要搞清楚RPO和RTO能到多少。对于数据敏感的场景务必评估开启半同步复制、组复制或基于Paxos/Raft的强一致方案。6.4 分布式锁踩过的坑锁没失效 锁续期问题写分布式锁的时候容易踩两个坑。第一个是忘记设置过期时间一旦拿到锁的节点宕机锁永远释放不了所有请求全部阻塞。第二个是业务执行时间超过锁的过期时间锁自动释放了别的节点拿到锁进来了同一份数据就被两个节点同时操作很可能产生脏数据。正确做法是搞锁续期机制。Redisson的WatchDog自动续期就能解决锁超时问题它会在锁快到期时自动给锁续期直到业务执行完释放锁。如果不想引入Redisson依赖也可以用异步任务定期刷新过期时间但一定要把握“谁加的锁只有谁能释放”这个原则解锁的时候比较自己写入的唯一标识防止误删别人的锁。7. 面试常问的几个问题以及我建议的回答思路最后整理几个我当面试官时高频提问的问题给同样要面这类岗位的同学一些参考。7.1 “你们系统为什么用集群为什么用分布式”这个问题看似简单但答不好会显得只是背概念。正确思路是结合你们公司的实际业务来讲比如因为单机QPS只能支持800业务期望2000所以把无状态应用扩展成3个节点通过Nginx负载均衡这是集群后来用户量和功能模块越来越多订单和支付耦合在一个进程里发版相互牵制于是拆成了独立服务这是分布式。能结合自身实际场景回答的人我基本都会给加分。7.2 “集群和分布式分别解决了什么问题”不能只说“集群是多台机器分布式是拆分系统”要展开成集群解决垂直容量和可用性瓶颈通过复制和负载均衡提升抗压能力分布式解决业务复杂度膨胀通过化整为零提升扩展性和团队研发效率。同时要补充两者在数据一致性、监控运维上的差异这样才能显示出你真正理解架构背后的思考。7.3 “什么是分布式锁实现方案有哪些”这题考察实战经验。可以先说使用场景比如防止库存超卖、防止定时任务重复执行再说实现方案Redis方案、ZooKeeper方案、数据库乐观锁方案最后做个对比Redis性能最好但一致性弱ZK一致性更强但性能略差数据库乐观锁适用范围有限。能主动提到看门狗续期这个细节的人说明他踩过坑我会重点考察。7.4 “什么是分布式事务有没有更好的方案”回答时建议顺着一条线先说为什么需要分布式事务订单和库存不一致的问题然后说2PC为什么不好用同步阻塞、资源锁定、协调者单点再说工程界常用的最终一致性方案比如本地消息表、事务消息、Saga补偿分别适用于什么场景。最后补一句“分布式事务没有银弹最好的设计是不引入分布式事务比如把库存操作放到订单服务内部完成或者通过消息驱动来解耦”一下就能和其他候选人拉开差距。8. 踩过几次坑之后我的一些总结思考聊得差不多了回到最初的问题。分布式和集群的区别是什么这个问题没有标准答案不同面试官期待的回答侧重也不同。但我个人觉得理解它们的正确姿势是记住集群是“多干”分布式是“分工”然后到真实系统里去观察它们如何叠加。我刚入行的时候也死记概念直到亲手搭建过Kafka集群参与过微服务拆分处理过分布式锁超时才真正理解这两者的差异和联系。你如果现在还在困惑不要急找一套开源系统比如部署一套Kafka集群或者拿Spring Cloud搭一套微服务demo把服务多启动几个实例关掉其中一个看看整体行为变化比背十篇文章都管用。最后分享一个小建议日常讨论架构时别把注意力放在“这个词叫集群还是分布式”上而是多追问一句“这个设计是为了解决什么问题”。是为了抗住流量是为了故障转移是为了模块解耦还是为了独立扩展搞清楚目标你再回头看这两个概念会发现根本不需要死记定义它们已经长在你脑子里了。
返回列表