
教程【免费下载链接】Grokking-System-DesignSystems design is the process of defining the architecture, modules, interfaces, and data for a system to satisfy specified requirements. Systems design could be seen as the application of systems theory to product development.项目地址https://gitcode.com/gh_mirrors/gr/Grokking-System-Design点击查看免费下载导读本文基于 designs/facebook-messenger.md 展开该文档以「概述图 细节图」两张架构图精炼地承载了 Facebook Messenger 类聊天系统的完整设计脉络先给出用户经聊天服务器互发消息的基础链路再给出负载均衡、聊天服务器集群、数据库分片与缓存集群组成的分布式扩展架构。读完本文你将掌握即时消息系统从单点到集群的演进路径、图中每个组件的职责以及仓库基础文档负载均衡、分片、缓存、实时通信、队列、冗余、CAP 定理等在聊天场景中的具体落点可直接用于系统设计面试的讲解与复盘。一、文档概览两张图讲清一个完整设计与仓库中大多数设计文档如 designs/short-url.md 的需求清单、容量估算、API 表格、数据模型等长篇结构不同facebook-messenger.md采用极简的组织方式正文仅一个## Summary小节所有技术内容全部封装在两张架构图中——概述图img/facebook-messenger-overview.png展示最基础的聊天系统形态回答消息如何从一个人传到另一个人并落盘细节图img/facebook-messenger-detail.png展示分布式扩展后的完整形态回答用户量大之后如何拆分与加速。这两张图恰好对应了系统设计面试中先设计最小可行系统再识别瓶颈、逐步扩展的标准节奏参见 README.md 的 Interview Process 一节。二、基础架构单聊天服务器的消息流转概述图描绘了一个最简单的点对点聊天拓扑共 4 个组件、4 条消息流向组件职责按图示User 1/User 2消息的发送方与接收方Chat Server消息转发的核心枢纽Data storage消息的持久化存储数据流如下User 1向Chat Server发送消息 ASend Message AChat Server将消息 A 转发给User 2Receive Message AUser 2向Chat Server发送消息 BSend Message BChat Server将消息 B 转发给User 1Receive Message B在此过程中Chat Server与Data storage之间为双向读写即消息既要落盘持久化也要在必要时从存储中取回例如离线消息、历史消息查询。2.1 架构含义解读从这张图可以提炼出聊天系统的两个本质约束双向实时通信用户与聊天服务器之间不是一问一答的普通 HTTP 请求而是需要服务器能主动向客户端推送消息。仓库的 basics/client-server-communication.md 列出了从标准 HTTP、Ajax 轮询、HTTP 长轮询、WebSocket 到 Server-Sent EventsSSE的演进其中WebSocket基于单条 TCP 连接的全双工通道、低通信开销、实时数据传输最贴合发送 接收对称的场景消息必须持久化Chat Server与Data storage的双向箭头表明消息不是转瞬即逝的网络包而是要落库的数据对象这决定了后续数据模型与存储选型SQL/NoSQL、分片的设计空间。2.2 显而易见的瓶颈基础架构只有一个Chat Server和一个Data storage两者都是典型的单点故障与性能瓶颈单台聊天服务器承载所有连接与转发CPU、内存、文件描述符每个长连接都会占用很快耗尽单一存储无法支撑海量消息的写入与读取任一组件宕机整个聊天服务即不可用。这正是细节图要解决的问题。三、分布式扩展架构从单点走向集群细节图给出了完整的规模化方案图中组件包括用户层User A、User B、User C图中以 3 个用户示意海量用户第一级负载均衡Load Balancer - User to Chat Server Mapping负责把用户映射到具体的聊天服务器聊天服务层Chat Servers集群图中含 4 台服务器实例存储层DB Shard数据库分片图中含 4 个分片实例每台聊天服务器直连分片读写缓存层Load Balancer - User to Cache Server Mapping负载均衡 Cache集群图中 3 台实例同时DB Shard整体向缓存层供数即缓存以数据库为数据源。3.1 分层数据流串联把图中的箭头连起来可以得到完整的请求链路用户User A/B/C首先命中Load Balancer - User to Chat Server Mapping负载均衡按映射策略把用户分发到Chat Servers集群中的某一台实例聊天服务器直接读写对应的DB Shard消息按分片规则落到不同数据库实例聊天服务器与数据库都接入缓存层聊天服务器通过Load Balancer - User to Cache Server Mapping访问Cache集群数据库分片向缓存层同步/供数从而把高频读请求从数据库卸载到缓存。3.2 两个关键设计点1为什么用户到聊天服务器的映射需要专门一个负载均衡聊天连接本质上是有状态的一个用户与某台聊天服务器之间通常维持着 WebSocket 或长轮询连接服务器侧保存着该用户的会话状态。若负载均衡随机分发用户每次重连都可能落到不同服务器导致状态丢失、连接反复重建。因此图中用「User to Chat Server Mapping」明确表达负载均衡需要按用户维度做映射可理解为会话保持 / IP hash 之类的粘性策略让同一用户尽量稳定落在同一台聊天服务器上。2为什么存储要分片、读要缓存消息数据具有按用户/会话天然可分的特征适合用DB Shard水平拆分来扩展写入与存储容量而历史消息、会话列表、用户资料等读取频繁且局部性强适合引入Cache集群加速并通过缓存负载均衡把聊天服务器对缓存的访问与数据库解耦。四、图中关键组件的原理深挖仓库基础文档佐证细节图中的每个组件在仓库 basics 目录下都有对应的原理文档下面逐一对应展开。4.1 负载均衡聊天的两级 LBbasics/load-balancing.md 指出负载均衡帮助系统跨不断增多的服务器水平扩展并给出了三个典型部署位置用户与 Web 服务器之间Web 服务器与内部平台层应用服务器、缓存服务器之间内部平台层与数据库之间。细节图正好呈现了前两类Load Balancer - User to Chat Server Mapping位于用户与聊天服务器之间Load Balancer - User to Cache Server Mapping位于聊天服务器与缓存之间此外聊天服务器与 DB 分片之间同样可以再设一层 LB形成文档所述的第三个位置。负载均衡算法方面仓库列出最少连接least connection、最少响应时间least response time、最少带宽least bandwidth、轮询round robin、加权轮询weighted round robin、IP hash。对聊天系统而言IP hash天然具备同一来源 IP 落到同一服务器的特性可作为用户-聊天服务器映射的简单实现实现方式上可以是智能客户端、硬件负载均衡器或软件负载均衡器。4.2 数据库分片DB Shard 的拆分方式basics/sharding.md 系统介绍了数据分区方法水平分区range-based sharding按行拆分到不同表/库缺点是若分区键选取不当会导致服务器负载不均垂直分区按功能域拆分到独立服务器实现直观但对应用扩展有后续限制目录式分区通过查找服务抽象分区方案便于扩库但自身可能成为单点。分区准则上聊天消息最常用的是key/hash-based partitioning对某键属性如user_id或会话 ID施加哈希得到分区号其痛点是新增服务器可能改变哈希函数、需要数据重分布仓库给出的缓解方案是 consistent hashing——把键与服务器都哈希到环上、顺时针找首个节点扩容缩容时只需重映射k/n个键并可引入虚拟副本缓解热点。分片后还需面对三个常见问题同样见 basics/sharding.md跨分片的 join 效率低可反规范化但引入数据不一致、外键等引用完整性难保证交由应用层维护、以及数据分布不均时的再平衡。聊天场景通常以用户/会话为分片维度尽量保证单会话数据落在同一分片内从而规避跨分片 join。4.3 缓存层读多场景的加速器basics/caching.md 开宗明义缓存利用局部性原理最近被请求的数据很可能再次被请求存在于架构的各层但通常放在最靠近前端的位置。图中Cache集群被聊天服务器与数据库分片共同引用属于全局缓存形态——所有请求节点共享一个更快的存储聊天服务器访问缓存时由缓存服务器处理未命中。与缓存配套的三个决策点缓存失效策略写直达write-through缓存与存储同时写一致性好但写延迟高、写旁路write-around只写存储最近写入的数据读时易 miss、写回write-back只写缓存、异步落库写吞吐高但有宕机丢数风险——聊天历史消息这类读多写少的场景写旁路/写回与数据库向缓存供数的图示语义更契合淘汰策略FIFO、LIFO、LRU最近最少使用、MRU、LFU、随机替换仓库文档尤其强调 LRU 适用于丢弃最久未使用的语义分布式缓存 vs 全局缓存若聊天服务器实例很多也可用一致哈希把缓存数据分散到各节点分布式缓存便于扩容但节点丢失即丢缓存或像图中这样独立成缓存集群全局缓存由缓存服务器统一处理 miss。4.4 实时通信消息推送的协议选型basics/client-server-communication.md 完整对比了五种通信方式是如何让消息实时到达对端的答案标准 HTTP 请求一问一答无法推送Ajax 轮询客户端周期性如每 0.5 秒请求缺点是需要不停询问、大量空响应造成 HTTP 开销HTTP 长轮询服务器延迟响应直到有更新或超时客户端收到响应后立即发起新请求每个长轮询请求都有超时需周期性重连WebSocket单条 TCP 连接上的持久全双工通道握手后双方随时可发数据通信开销低、实时性高SSE服务器向客户端单向推送的实时流适合服务器循环产生多个事件下行的场景。对照概述图中 User 与 Chat Server 之间发送 接收对称的箭头WebSocket 是最贴合的选型在兼容性受限时可用 HTTP 长轮询兜底。需要注意的是长连接会长期占用聊天服务器的连接资源这也是必须把Chat Servers扩展为集群并做用户-服务器映射的根本原因之一。4.5 队列与异步化聊天的可选扩展手段图中虽未显式画出消息队列但 basics/queues.md 指出大规模分布式系统中不同组件需要异步协作队列是客户端请求与实际服务工作之间的抽象——客户端提交任务后无需等待结果队列还能在服务故障时提供缓冲保护。在 Messenger 场景中以下工作天然适合异步化消息的推送通知Push Notification投递离线消息的批量落库与上线后的补发消息送达回执与已读状态等非关键路径更新。也就是说可以在 Chat Server 与存储/推送服务之间插入队列把实时转发与后台处理解耦这也是从两张图推演后续演进时可以补充的一环文档本身未画故此处仅作设计思路说明。4.6 冗余与高可用basics/redundancy.md 定义冗余为对关键数据或服务的复制以提升系统可靠性典型手段包括服务器故障转移failover与共享无状态shared-nothing架构——每个节点独立运行、无中央状态管理、新节点可无特殊条件加入、无单点故障。细节图中的Chat Servers多实例本身就是服务层冗余单台实例宕机后负载均衡可以把映射切换到存活实例配合会话状态外置到缓存/存储可实现无缝故障转移。这正是概述图单服务器形态缺失、而细节图补上的高可用能力。4.7 一致性权衡CAP 视角basics/cap-theorem.md 指出网络分区发生时必须在一致性与可用性之间二选一——ACID 数据库选择一致性优先BASE 系统选择可用性优先而无分区时两者并不冲突。聊天系统对一致性有不同的层级要求消息内容与顺序同一会话内的消息必须有序、不丢失通常要求强一致或至少会话级有序已读状态、在线状态可以接受短暂不一致最终一致换取高可用与低延迟。因此在存储层选型与复制策略上需要按数据类别区分对待这正是 basics/cap-theorem.md 在 Messenger 设计中的具体落点。4.8 存储选型SQL vs NoSQLbasics/sql-vs-nosql.md 给出了选型框架SQL 以固定 schema、ACID 事务、纵向扩展见长NoSQL 以动态 schema、横向扩展加机器即可扩容、牺牲部分 ACID 换取性能见长常见形态包括键值存储Redis、Dynamo、文档库MongoDB、CouchDB、宽列库Cassandra、HBase与图数据库Neo4J。对聊天消息而言消息记录天然按会话/用户聚合文档或宽列模型的按 key 聚合读取特性贴合拉取某会话最近 N 条消息的查询模式海量消息需要水平扩展NoSQL 的廉价横向扩展更契合且可与 basics/sharding.md 的分片方案叠加若需要强事务如转账类业务消息则 SQL 更合适。仓库其他设计文档也体现了类似判断——例如 designs/short-url.md 在存储观察中明确写出NoSQL 更易扩展SQL 加分片也可行可作为同仓库内选型思路的参照。五、回到方法论如何用这两张图讲透一个系统设计README.md 将系统设计面试流程归纳为三步范围界定Scope the problem不要假设通过澄清问题理解约束与用例包括需求澄清与系统接口定义抽象设计Sketch up an abstract design列出系统的积木与关系包括粗略估算back-of-the-envelope estimation、定义数据模型、高层设计识别并解决瓶颈Identify and address the bottlenecks进入详细设计找出瓶颈并解决。facebook-messenger.md的两张图恰好是这套方法的可视化缩影概述图 第 2 步的高层设计先画出最小可运行系统细节图 第 3 步的详细设计与瓶颈解决单点 → 集群、单库 → 分片、无缓存 → 缓存层。如果想在面试中把这两张图扩展成一份完整的设计稿可以参照仓库中结构最完整的 designs/short-url.md它通常覆盖这些章节功能/非功能/扩展需求、容量估算QPS、存储、带宽、缓存内存、系统 API含参数表、数据库 schema、核心算法、数据分区与复制、缓存策略LRU、更新时机、负载均衡位置、过期数据清扫、遥测统计与安全权限。对 Messenger 而言对应的推演方向包括容量估算假设读多写少如 100:1 读:写比估算每秒消息量与存储增长需自行设定合理假设文档未给具体数字不可臆造数据模型消息表消息 ID、发送者、接收者/会话 ID、内容、时间戳、用户表、会话表分区按用户/会话哈希分片见 4.2缓存缓存最近会话与热用户状态LRU 淘汰见 4.3实时通道WebSocket 为主、长轮询兜底见 4.4。六、小结facebook-messenger.md用两张图完成了从 0 到 1、从 1 到 N的完整叙事概述图中的User ↔ Chat Server ↔ Data storage是聊天系统不可再简化的核心骨架细节图则在每个单点上做文章——用「用户-聊天服务器映射负载均衡」解决有状态连接的归属问题用Chat Servers集群解决连接与转发容量问题用DB Shard解决存储与写入扩展问题用Cache集群解决读放大问题。四个方向分别对应仓库基础文档中的负载均衡、冗余、分片含一致哈希与缓存原理而实时通信选型WebSocket/长轮询、异步队列与 CAP 权衡则是聊天系统区别于普通 Web 系统的独特维度。掌握这张图背后的组件职责与取舍逻辑即可在面试中把任何聊天类系统设计题讲得有条理、有依据。延伸阅读仓库 basics 目录下的 load-balancing.md、sharding.md、caching.md、client-server-communication.md、queues.md、redundancy.md、cap-theorem.md、sql-vs-nosql.md、consistent-hashing.md以及 README.md 中的系统设计面试方法论都是深入这一主题的配套材料。赞分享教程【免费下载链接】Grokking-System-DesignSystems design is the process of defining the architecture, modules, interfaces, and data for a system to satisfy specified requirements. Systems design could be seen as the application of systems theory to product development.项目地址https://gitcode.com/gh_mirrors/gr/Grokking-System-Design点击查看免费下载相关推荐10分钟上手RSpec-MocksRuby开发者必备测试工具快速入门10分钟上手RSpec MocksRuby开发者必备测试工具快速入门 RSpec Mocks是Ruby生态中最受欢迎的测试替身test double框架Resticker常见问题解决从锁冲突到存储连接错误的终极指南Resticker常见问题解决从锁冲突到存储连接错误的终极指南 Resticker是一款通过Docker容器运行自动restic备份的强大工具能够帮助用户轻运维HunyuanWorld-Mirror vs Fast3R单向前馈模型效率优势HunyuanWorld Mirror vs Fast3R单向前馈模型效率优势 在3D重建领域传统模型常受限于多阶段优化带来的计算瓶颈尤其在实时场景重建、教程上一篇Apache DolphinScheduler Doris 数据源接入指南参数详解、驱动安装与 MySQL 兼容连接原理下一篇scalar/fastify-api-reference 插件全解析为 Fastify 应用接入 Scalar API Reference 的完整实践指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考