ARTICLE DETAIL

资讯详情

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

分布式系统核心考点全梳理:从CAP到分布式锁与事务

分布式系统核心考点全梳理:从CAP到分布式锁与事务 看到“牛客面经八股”这几个字很多准备校招的朋友都会会心一笑分布式几乎是大厂技术栈的必考章节也是很多人背得最痛苦的部分。你背了CAP、背了两阶段提交、背了Redis分布式锁但面试官往往不止问“是什么”还喜欢追问“为什么”和“还有没有更好的方案”。今天这篇我想以面经题为线索把分布式的核心考点串一遍里面会揉进我实际做项目、刷题和面试时积累的经验希望能帮你把散落在牛客讨论区里的零散八股变成一套能说清楚、能抗追问的完整知识体系。我见过太多人拿着厚厚的一摞八股文档从“分布式事务”背到“分布式锁”看起来什么都知道可一被追问就卡壳。问题不在于背得不够多而在于没有把这些点连成一张网。分布式不是一堆孤立的技术名词而是一整套应对“系统变大之后复杂度上升”的思考方式。所以这篇不止是罗列知识点更会讲清楚每个方案背后的取舍以及面试回答时怎么讲才有层次。1. 面经里的分布式到底在考你什么1.1 为什么分布式成了必考模块早年很多公司的技术栈都是单体应用一个工程打包部署数据库挂在下面用户量不大时完全够用。但随着业务增长单机服务器的CPU、内存、磁盘总有一个先到瓶颈再往后业务模块越来越多团队几十上百人同时在一个工程里改代码发布一次要协调所有人风险极高。于是大家开始把系统拆开按业务边界拆成订单服务、库存服务、用户服务每个服务独立部署、独立伸缩。这就是分布式系统最基本的形态。但拆分之后原本在同一个进程里的方法调用变成了跨服务的网络调用原本由一个数据库事务搞定的一致性变成了多个服务、多个数据库之间的一致性问题原本用JVM锁就能实现的并发控制变成了多节点之间的分布式锁问题。这些就是分布式架构的核心难点也是面试官最想考察的地方。分布式考点背后其实是在考察候选人有没有能力处理“系统复杂度上升”这件事。校招虽然不会要求你有大规模生产环境的经验但至少要知道系统为什么会变复杂复杂在哪业界有哪些成熟的解法。所以分布式成为必考不是因为“流行”而是因为它直接反映候选人的系统设计思维。1.2 高频考点全景图把牛客上关于分布式的面经题汇总一下其实高频考点非常集中我整理了一个全景图供大家自测考点领域代表问题重要程度架构理论CAP、BASE、一致性哈希必背微服务组件注册中心、网关、配置中心、熔断降级必背远程调用RPC原理、Feign/Dubbo、序列化高频分布式事务2PC、3PC、TCC、可靠消息、Seata必背分布式锁Redis锁、ZooKeeper锁、数据库锁必背分布式缓存穿透、击穿、雪崩、缓存一致性必背分布式存储分片、副本、分布式ID、一致性哈希高频分布式调度XXL-Job、ElasticJob、ShedLock高频消息队列削峰、异步解耦、最终一致性高频链路追踪日志串联、TraceId、SkyWalking加分从表格能看出来分布式知识覆盖面很广但真正的高频题目其实就集中在“架构理论 数据一致性 高可用方案”这三块。准备的时候不建议平均用力优先把必背的搞透再往加分项扩展。1.3 面试官考察的核心能力很多同学会把八股题当成“背诵题”来准备但面试官真正想看的是你面对一个具体问题时能不能做出合理的技术选型。比如同样是“分布式锁”这道题初级回答是背出SET NX EX命令中级回答是能说出Redisson看门狗、可重入锁高级回答是能对比Redis和ZooKeeper锁的优劣并结合业务场景说清楚为什么选Redis而不是ZK以及主从切换时锁可能丢失怎么兜底。从初级到高级的差别不在于知识点的数量而在于有没有把“背答案”变成“做权衡”。分布式系统里几乎没有银弹每个方案都有代价追求强一致可能要牺牲可用性追求高性能可能要先接受最终一致。面试官想听到的是你能把这种权衡讲明白而不是机械地罗列名词。2. 分布式架构与微服务从CAP到Spring Cloud2.1 为什么需要从单体走向分布式聊分布式之前必须先理解单体架构的痛点。单体应用最直接的问题有两个一是资源无法按需扩展用户量上来之后你只能把整个应用堆到更大的机器上但可能真正吃性能的只有一两个模块二是故障没有隔离一个模块出现内存泄漏或者死循环整个进程可能直接宕掉所有业务一起受影响。微服务架构把系统按业务拆分成多个服务每个服务独立进程、独立部署、独立扩缩容。这样订单服务压力大就只扩容订单服务库存服务出故障也只会影响库存相关的功能。但拆分是有代价的服务之间从本地方法调用变成网络调用网络就会带来延迟、超时、重试、幂等等一系列新问题原本一个数据库事务能搞定的事情现在要跨服务、跨库所以分布式事务才成了必须讨论的话题。我刚接触微服务时有个误区觉得服务拆得越细越好。后来在一个项目里把一个模块拆成了七八个服务结果一个简单的查询要串五六个服务排查问题链路长得离谱。拆分的本质是“在合适的粒度上划清边界”而不是追求数量。面试聊到微服务时如果能主动说出“过度拆分也是一种坏味道”会给面试官留下很深的印象。2.2 CAP与BASE分布式系统的底层坐标系CAP理论几乎是分布式面试的第一个必考题。C是一致性A是可用性P是分区容错性。所谓分区容错指的是分布式系统里网络节点之间可能出现消息丢失或延迟这个情况叫“网络分区”。在一个分布式系统里网络分区是不可避免的所以P必须满足剩下的C和A只能二选一。可以这样理解两台机器之间的网线断了这时候你收到一个读请求。如果选择一致性你需要让请求失败告诉调用方“我现在无法保证数据是最新的”这就是CP比如ZooKeeper如果选择可用性你会继续返回数据哪怕可能是旧数据等网络恢复后再同步这就是AP比如Eureka。实际的分布式系统尤其是互联网业务往往更偏向AP和最终一致性因为用户不能接受“请稍后再试”的概率太高。BASE理论是CAP在工程实践的落地基本可用、软状态、最终一致。基本可用指系统在异常时尽量保证核心功能可用比如大促时降级非核心功能软状态指允许系统存在中间状态最终一致指经过一段时间数据最终会达成一致。缓存和数据库之间的异步同步、消息队列的异步处理本质上都是BASE思想。2.3 RPC与注册中心服务之间怎么互相找到分布式服务之间需要通信最简单的方式是HTTP接口但HTTP在性能、传输效率和接口语义上不够直接所以企业里更多用RPC框架比如Dubbo、gRPC、Spring Cloud中的Feign。RPC的过程可以简化成客户端本地调用一个代理对象代理把方法名、参数序列化成字节流通过网络发送给服务端服务端反序列化后执行真实方法再把结果返回给客户端。对业务代码来说看起来就像调用本地方法一样。但服务有多个实例客户端怎么知道该调用哪个IP和端口这就轮到注册中心登场。服务提供方启动时往注册中心注册自己的地址服务消费方启动时从注册中心拉取服务列表再通过负载均衡策略选一个实例发起调用。常见的注册中心有Eureka、ZooKeeper、Nacos、Consul它们的区别本质上还是落回CAPEureka偏向APZooKeeper偏向CPNacos支持切换模式。面试时如果被问到“服务调用失败怎么办”不能只说“重试”。要考虑幂等性如果下游处理成功但响应超时重试会带来重复操作所以接口设计里通常需要幂等键同时还要考虑重试次数过多导致的雪崩所以需要熔断和限流。2.4 Spring Cloud微服务架构的一次请求链路Spring Cloud是目前微服务生态里最常被问到的技术栈。一个典型的请求链路大概是外部请求先到API网关网关做统一鉴权、限流、路由然后转发到具体业务服务业务服务通过Feign或RestTemplate调用其他服务调用过程从注册中心拉取服务列表配置从配置中心拉取链路信息通过SkyWalking或Zipkin收集如果某个下游服务开始异常熔断器会快速失败而不是一直等待如果流量过大还会触发限流和降级。面经里常见的“Spring Cloud分布式架构设计”问题其实就是要你把这个链路讲清楚。推荐画一张示意图网关在最外层下面是各业务服务右侧是注册中心、配置中心、熔断器、链路追踪等基础设施。然后面试官问哪一个组件你就往深聊哪一个。比如问“服务间负载均衡怎么做”就聊Ribbon的负载均衡策略问“配置动态刷新怎么做”就聊Spring Cloud Config或Nacos的配置监听。还有一点容易被忽略微服务不是把服务拆完就结束还需要配套的监控、日志、告警。没有链路追踪一个跨五个服务的请求出现问题你连日志都串不起来。所以面试时说微服务最好把“可观测性”也带上这是区分有没有真实落地经验的关键。2.5 分布式定时任务的架构方案单机架构下定时任务用Spring Scheduled就能解决。但一旦服务部署多个实例Scheduled的同一任务会在每个实例上同时执行产生重复处理。比如定时给用户发送通知本来想发一次结果发了好几次。最简单的方案是“分布式锁定时任务”每次任务执行前先尝试获取分布式锁拿到锁的实例才执行其他实例直接跳过。这种方案优点是轻量缺点是任务路由不灵活无法做到分片。复杂一点的方案是引入分布式任务调度平台比如XXL-Job、ElasticJob部署独立的调度中心执行器注册上来调度中心负责任务触发执行器负责任务执行支持分片广播、失败重试、动态调整任务参数。在Spring Cloud环境下比较常见的做法是用ShedLock配合Redis实现轻量级分布式任务锁或者直接上XXL-Job。面试时建议把两种方案都讲出来说明各自适用场景而不是一上来就说“我们用XXL-Job”显得没有思考过程。3. 分布式事务别只会背2PCSeata原理才是加分项3.1 典型场景下单扣库存分布式事务最常见的面试场景是“订单与库存”。用户下单订单服务创建一条订单数据库存服务扣减一个库存这两个操作发生在不同的服务、不同的数据库里本地事务根本管不了。如果订单创建成功、库存扣减失败就会出现超卖如果库存扣减成功、订单创建失败就会出现库存被扣但用户没买到东西。这时候需要分布式事务来保证多个服务之间的数据一致性。但分布式事务的成本很高不能所有业务都无脑上。面试时会先问场景再问你选什么方案所以要把每个方案的适用场景和优缺点梳理清楚。3.2 分布式事务方案全景2PC、3PC、TCC、可靠消息、最大努力通知先全景式看一下常用方案方案一致性强度业务侵入适用场景2PC两阶段提交强一致低单体数据库跨库、传统X/Open分布式事务3PC三阶段提交强一致减少阻塞低对2PC改进工程落地少TCCTry/Confirm/Cancel强一致高金融、账务类业务可定义补偿逻辑可靠消息最终一致性最终一致中高并发、允许短暂不一致的业务最大努力通知最终一致低跨平台支付回调、第三方结果通知2PC是最经典的方案分为准备阶段和提交阶段。协调者先问所有参与者“能不能提交”所有人都说可以才进入提交阶段只要有一个参与者说不能就全部回滚。缺点也很明显所有参与者要一直持有数据库资源等协调者命令容易出现同步阻塞协调者单点故障还会导致阻塞更久。3PC改进了超时机制但实际落地并不多。TCC更像一种业务层面的分布式事务方案把每个操作拆成Try预留资源、Confirm确认执行、Cancel回滚释放。比如订单服务在Try阶段创建待支付订单库存服务在Try阶段冻结库存Confirm阶段真正扣减库存、订单生效Cancel阶段释放冻结库存、订单关闭。TCC的优点是性能好、能做到强一致缺点是对业务侵入非常大每个操作都要写三套逻辑。可靠消息最终一致性则是通过消息队列实现把本地业务操作和消息发送放在同一个本地事务里消息发送成功后再由消费者消费消费者处理成功后再给生产者确认。这个过程允许数据短暂不一致但最终能对账成功。最大努力通知适合对接外部系统比如支付结果通知支付平台会反复回调直到收到成功应答或达到重试上限。3.3 Seata AT模式的核心原理Seata几乎是现在分布式事务面试的顶流话题。它的AT模式在原理上很像2PC但做得更自动化。Seata有三大角色TC事务协调者、TM事务管理器、RM资源管理器。TM向TC申请开启全局事务RM负责本地事务的提交和回滚TC负责全局事务的协调。AT模式的核心在于“快照undo log”。业务SQL执行前RM会先保存当前数据的快照然后执行业务SQL把业务数据和undo log写入同一本地事务并注册分支事务到TC如果全局事务提交就删除undo log如果全局事务回滚就根据undo log反向生成补偿SQL把数据恢复原样。相比TCCAT模式对业务代码侵入很小不需要写Confirm和Cancel。但它也不是万能的因为要使用全局锁来保证并发事务之间不会互相干扰性能会有一定损耗。面试时可以说清楚AT模式是把2PC的“人工准备”变成了“自动快照”用空间换开发效率这比只会背“Seata是阿里的分布式事务框架”要有深度得多。3.4 怎么把事务方案讲出层次感回答分布式事务题目时不要一上来就说“我们用Seata”。更推荐的顺序是先描述业务场景的一致性是强一致还是最终一致然后给出候选方案并说出每个方案的代价最后再结合场景选出最合适的。比如面试官问“订单和库存怎么保证一致”你可以这样回答如果扣库存操作必须和订单创建保持强一致可以选用Seata的AT模式虽然性能略有损耗但业务改动小。如果库存系统并发非常高、不希望被分布式事务拖慢可以把“扣库存”改为异步消息或预占库存接受短暂不一致通过定时对账来兜底。这种回答方式会显得你是在做技术选型而不是在背PPT。4. 分布式锁面试高频题型与Redisson落地4.1 问题的起点并发扣库存分布式锁这道题几乎每次面试都会被问到。面试官常给的场景是商品库存只有10件用户同时发起大量请求多个服务实例同时执行“判断库存0库存减一”的操作怎么保证不超卖单机环境下可以用synchronized或JUC的Lock但多个实例部署后每个实例的JVM锁互相看不到必须引入一个所有服务都能访问的“外部锁”。分布式锁的本质很简单让多个进程通过一个共享的第三方组件来竞争同一个资源谁抢到谁执行。4.2 Redis分布式锁的正确姿势最常见的实现是Redis分布式锁。最早有人用SETNX后来发现需要同时设置过期时间于是改用SET key value NX EX命令一条命令完成加锁和设置超时。value要存一个唯一标识比如UUID释放锁时先比对value再删除这是为了防止误删别人的锁。释放锁这一步必须用Lua脚本保证原子性不能先GET再DEL。因为如果某个线程的锁过期了另一个线程加锁成功第一个线程再来释放锁时不加判断会把别人的锁给删掉。Lua脚本如下if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end还要注意锁的过期时间设置。过期时间太短任务还没执行完锁就自动释放太长一旦持有锁的实例宕机其他实例要等很久才能获取锁。所以能不能给锁自动续期就成了一个很关键的面试点。4.3 Redisson看门狗与可重入Redisson封装了分布式锁的很多细节面试时一定要会讲。Redisson的RLock是基于Redis Hash结构实现的同一个线程可以多次加锁并释放这就是可重入。更厉害的是看门狗机制默认锁的leaseTime是30秒如果持有锁的线程还在执行看门狗会每10秒自动续期一次把锁的时间拉回30秒避免业务没执行完锁就过期。但看门狗也不是万无一失。如果Redis主节点宕机锁数据还没来得及同步到从节点另一个实例可能会在同一把锁上加锁成功。Redis官方提出了RedLock算法在多个独立Redis节点上同时加锁超过半数成功才认为加锁成功。但RedLock本身也有争议很多工程团队并不推荐因为复杂度高且仍然存在时钟跳跃等问题。面试时能提到这个争议会显得你真的思考过可靠性问题。4.4 ZooKeeper分布式锁和数据库锁除了RedisZooKeeper也常被用来实现分布式锁。方案是在ZooKeeper的某个持久节点下创建临时顺序节点如果自己创建的节点序号最小就说明拿到锁否则监听前一个节点前一个节点被删除时再尝试获取锁。ZooKeeper锁最大的优势是“临时节点会话超时”机制客户端崩掉会话结束临时节点自动删除锁自然释放不会像Redis那样存在锁超时没人续期的问题。而且ZooKeeper是CP模型一致性更强。缺点是性能不如Redis创建节点和监听事件都有额外开销高并发场景下可能成为瓶颈。数据库锁也有两招。悲观锁用SELECT ... FOR UPDATE性能不高乐观锁用版本号更新时带上version条件适合冲突较少的场景。但数据库锁本身不适合高并发分布式锁面试中提一下即可重点还是Redis和ZK的对比。4.5 锁选型与避坑经验实际项目里怎么选我的经验是如果追求高性能并且能接受极端场景下锁丢失用RedisRedisson如果业务对可靠性要求极高比如不允许出现并发重复写入用ZooKeeper锁。避坑方面第一锁粒度要尽量小能用订单维度就不要用商品维度避免把不相关的操作互相阻塞第二锁内代码一定要快不要在锁里面做远程调用和耗时IO否则吞吐量会非常难看第三多个锁嵌套时要保证加锁顺序一致否则会出现死锁第四释放锁必须放在finally里并配合Lua脚本比对value。这些细节比单纯背命令更能体现你的工程素养。5. 分布式缓存与存储穿透、击穿、雪崩和集群架构5.1 缓存三兄弟穿透、击穿、雪崩缓存是分布式系统里提升性能最直接的手段但用不好会带来三个经典问题。缓存穿透查询一个根本不存在的数据比如用一个不存在的用户ID缓存里没有请求直接打到数据库如果被攻击者批量构造不存在的ID数据库压力会非常大。解决方案缓存空值但设置较短过期时间更彻底的办法是用布隆过滤器在请求缓存前先判断数据是否存在不存在直接返回。缓存击穿某个热点key在缓存过期的瞬间大量请求同时打到数据库。解决思路是“单点重建缓存”用互斥锁让一个线程去查数据库并回填缓存其他线程等待或先返回旧值或者对热点key设置“逻辑过期”缓存里存的是旧数据后台异步刷新。缓存雪崩大量key在同一时间集中过期或者Redis实例宕机导致所有请求涌向数据库。解决方法是给key的过期时间增加随机值避免同一时刻大面积过期同时做Redis高可用和多级缓存兜底。面试时建议用“先讲表象再讲解决方案最后讲怎么避免”的结构这样逻辑最清晰。5.2 缓存一致性先更新DB还是先删缓存缓存和数据库双写时保证一致性是另一道高频题。业界最常用的是Cache Aside模式读的时候先读缓存没命中就读数据库再回填缓存更新的时候先更新数据库再删除缓存。为什么不更新缓存而是删除缓存因为并发更新缓存很可能产生旧值覆盖新值的问题。删除缓存策略也有一个问题如果先更新数据库、再删缓存删缓存这步失败老缓存依然存在数据还是不一致。常见补救是“延迟双删”先删除缓存更新数据库再睡一小段时间再删除一次缓存。但延迟时间很难精确控制最终一致性要求高的场景更推荐订阅MySQL的binlog由Canal把数据库变更事件推给消费者消费者再去删除或者更新缓存这样不侵入业务代码。这道题没有完美答案重点是把方案演进过程说清楚从最简单的“先更新DB再删缓存”到“延迟双删”再到“binlog异步同步”每一步都是为了解决上一步的缺陷。5.3 Redis Cluster与缓存分片单机Redis内存有上限比如128G的机器Redis能用的远小于这个值而且单机性能和容量终究有限所以需要集群。Redis Cluster把数据分片到多台节点上通过16384个哈希槽管理数据分布。客户端计算key的CRC16值并取模16384得到这个key属于哪个槽再找到对应节点。这里有一个很容易混淆的点Redis Cluster是“分片主从”的组合分片解决容量扩展主从解决高可用。主节点挂了从节点自动提升为主节点继续服务。但在主从切换过程中会有短暂的数据丢失或不可用这是CAP里选择AP或者说弱一致的体现。面试里还常问一致性哈希。一致性哈希的核心价值是节点增减时只影响少量key的迁移不像简单取模那样需要大规模重新映射。虚拟节点是为了解决数据倾斜问题。理解一致性哈希的关键是“把数据映射到一个环上而不是线性取模”可以用经典的“服务器节点顺时针查找”来记忆。5.4 分布式存储基础概念缓存之外还有一类问题是怎么在海量数据上做分布式存储。面试通常不会考太深但基础概念要能讲清楚。数据分片把大表的数据按某种规则分散到多个存储节点。按ID范围分片容易热点按哈希分片相对均匀但范围查询困难。副本每个分片保存多份数据既保证高可用也能分摊读压力。分布式存储系统的核心设计问题就是“数据怎么分、副本怎么同步、节点故障怎么恢复”。对象存储、分布式文件系统、分布式数据库这些概念在面经里也可能出现不需要每个都精通但要能说出它们的共同点通过分片扩展容量通过副本保证可用性通过一致性协议保证数据可靠。5.5 分布式ID有哪些方案分布式存储和分库分表之后数据库自增主键就不够用了因为每个分片各自生成自增ID会导致全局重复。于是分布式ID成了必问题。方案优点缺点UUID本地生成、无网络开销无序、太长、不适合作为索引进而影响性能数据库号段性能好、趋势递增依赖数据库需要做高可用雪花算法趋势递增、不依赖外部组件依赖机器时钟时钟回拨会出问题雪花算法是重点。它生成的64位long类型ID通常由1位符号位41位时间戳10位机器ID12位序列号组成。核心思路是“时间戳在高位同一个毫秒内用序列号区分”所以生成的ID呈趋势递增趋势。缺点在机器时钟回拨时可能产生重复ID解决办法是记录上次生成ID的时间发现回拨就等待或直接报错。分布式UUID这道题面试官还想听你对方案做选型而不是简单列举。6. 分布式任务调度、压测与爬虫考点延展与实战经验6.1 分布式任务调度平台XXL-Job架构速览前面聊定时任务时提到了XXL-Job这里展开一下它的核心架构。XXL-Job分成调度中心和执行器两部分。调度中心是一个独立的Web应用负责任务的CRUD、触发和调度执行器是业务服务里集成的一个组件启动后自动注册到调度中心。当到达触发时间调度中心把任务分发给一个或多个执行器执行。常见的路由策略有轮询、第一个、最后一个、随机、故障转移、分片广播等。分片广播适合大数据处理场景比如有10台执行器要处理100万条数据每台执行器按自己的分片序号处理1/10的数据。这个设计思想很重要它可以用来回答“如果任务执行耗时太长怎么办”“怎么让多台机器分摊任务”等问题。如果只是轻量场景不想引入独立平台也可以用ShedLockRedis。ShedLock的原理是给任务加上一个分布式锁拿到锁的实例才能执行其他实例跳过。它不适合做复杂路由但胜在简单。面试时两种方案都讲面试官会觉得你有实际选型能力。6.2 本地联调如何用IDEA启动多个实例很多人在牛客上搜过“idea怎么分布式启动项目就是一个模块起多个”这确实是很实用的本地调试技巧。本地是单体IDEA工程但你想模拟分布式环境比如验证某个服务启动两个实例后Feign能不能负载均衡、分布式锁会不会生效那就要在IDEA里启动多份同一服务。具体步骤打开Run/Debug Configurations复制一份现有Spring Boot启动配置在VM options里加-Dserver.port8081再复制一个改成8082然后同时启动即可。如果项目用了Nacos或Eureka两个实例会自动注册到同一个服务名下访问接口时可以通过网关或者负载均衡看到请求会被分发到不同端口。本地多实例调试时有一个坑如果服务里用了本地缓存或者内存存储多实例之间数据不共享可能产生和线上不一致的行为。但换个角度看这恰恰能帮你发现“哪些数据必须用Redis或者数据库存储”。我当年就是用这种方式验证了一个分布式任务重复执行的问题印象非常深刻。6.3 JMeter分布式压测本地跑不出高并发怎么办压测是分布式系统里绕不开的话题。JMeter单机压测时一台机器所能产生的并发请求数量有限搞不好压测机自己先成了瓶颈。想要更大的压力就需要JMeter的分布式压测模式由一台Master调度多台Slave执行机共同向目标系统发起请求。配置并不复杂准备一台Master和多台Slave所有机器都安装JMeter在Slave上启动jmeter-server在Master的jmeter.properties里配置remote_hosts填上Slave的IP和端口然后在Master上启动测试计划选择“远程启动”即可把测试任务分发下去。执行完成后聚合结果会汇总到Master展示。压测看起来简单细节决定成败。要确保Master和Slave的JDK版本、JMeter版本一致测试计划里的文件路径要保证每台Slave都能访问目标系统是否需要独立的压测数据集否则会互相影响。压测是定位系统瓶颈的手段压测前要明确目标是JVM内存不够还是数据库连接池打满还是CPU被计算逻辑吃光了。每轮压测后先看监控数据再调优而不是盲目加大并发数。6.4 分布式爬虫任务队列与去重分布式爬虫在面经里出现频率不算特别高但一旦出现很多人会懵。其实它不是特别神秘核心问题和分布式任务调度非常像单机爬虫只能串行或有限并行分布式爬虫要让多台机器协同抓取。通常的做法是引入一个共享的任务队列比如Redis List或RabbitMQ某个Worker每次从队列里取一个URL请求解析出新的URL后放回队列为了避免不同Worker爬到同一个URL还需要一个去重集合比如Redis的Set或者布隆过滤器记录已经抓取过的URL。Scrapy-Redis就是把Scrapy的调度器和去重器改成基于Redis实现从而支持多台Worker协同工作。面试时不需要讲得太深但要能说出“队列负责任务分发去重负责避免重复Worker负责执行抓取”这样一个架构思路顺便和分布式任务调度平台做类比就能体现你举一反三的能力。6.5 容易被追问的“分布式冷门点”除了上面这些主流考点偶尔会遇到几个冷门概念比如分布式版本控制、分布式账本、分布式DMA等。分布式版本控制其实是最常见的Git每个开发者的本地仓库都是完整历史大家通过pull和push协作和中心化版本控制的理念正好相反。分布式账本则是区块链里的底层概念多个节点共同维护一份账本通过共识机制保证一致概念上可以理解成“一种特殊的分布式数据库”。像分布式DMA这种更底层的硬件概念如果面试官不是做底层研发一般不会深问。遇到完全没听过的问题不用慌诚实说“这个方向我没有深入研究但我的理解是……”并尽量往熟悉的概念上靠。面试官更看重的是你的思维过程而不是知识点全知全能。碰到冷门题也是展示学习能力的机会。准备分布式八股我的真实体会是不要按章节死记硬背而是给自己准备一个“场景库”。每遇到一个考点就把它套进一个具体业务场景里比如下单扣库存、秒杀抢购、分布式任务跑批反复在心里推演这个场景会遇到什么问题有哪些方案各自代价是什么。然后再用IDEA把服务多启动几个实例亲手试一把你会发现很多背不下来的原理在做完实验之后就自然而然地长在脑子里了。这也是为什么我在上面花了大量篇幅讲本地调试和压测因为面试时能讲出“我实际跑过”的经验比任何八股答案都更有说服力。
返回列表