← 返回分布式系统
🌐 互联网架构 · 工程实践

分布式系统的典型应用场景

从用户敲下回车到数据落盘,现代互联网服务几乎每一层都是分布式的。一文讲清各层到底在用什么、为什么这么用、怎么实现。

🗺️ 全局视角:一个请求经历了什么

先建立一个"全景图"。下面是一套典型的互联网服务架构,几乎每一层都由分布式系统支撑。后面的每个场景,都是这个图里的一块。

客户端
🌐 浏览器 / App 📱 小程序 🤖 第三方调用方
边缘 / 接入
🛰️ CDN ⚖️ 四层负载 LVS 🔀 七层网关 Nginx 🚪 API Gateway
应用 / 服务
🧩 微服务集群 🔍 注册中心 🪪 分布式 Session ⏰ 分布式任务
中间件
⚡ 分布式缓存 Redis 📨 消息队列 Kafka 🔎 搜索引擎 ES 🗄️ 对象存储
数据 / 存储
🐬 分库分表 MySQL 🌿 分布式 DB TiDB 🐘 列式存储 HBase
计算 / 平台
📊 离线批处理 Spark 🌊 实时流 Flink 🧭 协调/配置 ZK·Etcd
💡
"分布式"不是某个组件,而是一种架构策略:把原本单机就能做的事, 拆到多台机器上协同完成,用可水平扩展高可用去换单机性能上限与单点故障风险。 代价是引入了网络不可靠、数据一致性、时钟与故障难以观测等全新难题。

⚖️ 一、接入与流量层

任何互联网服务的第一关:如何让海量请求公平、均匀地落到后端,同时挡掉恶意流量、就近返回静态资源。

🔀
1. 负载均衡(Load Balancing)
把流量分摊到多台应用服务器,消除单点、提升吞吐
客户端
海量并发
负载均衡器
LVS / Nginx
轮询·最小连接
应用节点 A
无状态
应用节点 B
无状态
应用节点 C
无状态

为什么需要

单机有连接数与 CPU 上限,且一旦宕机整站不可用。负载均衡通过多实例集群 + 流量分发,让系统能随业务横向加机器。

如何实现

  • 四层(LVS / IPVS):基于 IP+端口做转发,性能极高,常在流量最前端。
  • 七层(Nginx / APISIX):能解析 HTTP,按 URL、Header、Cookie 做路由与灰度。
  • 调度算法:轮询、加权轮询、最小连接、一致性哈希(保证同一用户落到同一节点)、源 IP 哈希。
  • 健康检查:定期探测后端存活,自动摘除故障节点,实现"无缝"故障转移。
🏢
真实案例:淘宝/字节的接入层通常是 LVS(四层)Nginx/OpenResty(七层) 两层,再接业务网关。大促时只要横向扩容应用节点即可。
🛰️
2. CDN 内容分发
把静态资源放到离用户最近的边缘节点,大幅降低延迟与源站压力

实现:源站把图片/视频/JS/CSS 推送到遍布各地的边缘节点。用户请求时,DNS 解析到最近的边缘节点;命中则直接返回,未命中才回源拉取并缓存。

缓存内容
静态为主
图片、视频、字体
前端构建产物
可缓存的 API 响应
核心机制
就近 + 缓存
边缘节点就近返回
TTL 过期回源
智能 DNS 调度
收益
性能 + 成本
首屏延迟 ↓
源站带宽 ↓
抗 DDoS 能力提升
💡
CDN 本质是一个分布式的只读缓存网络——它把"内容"这一数据,以最终一致性方式复制到全球边缘。

二、分布式缓存

"加一层缓存"是互联网解决性能问题最常用的一招。单机内存不够,就用分布式缓存把热点数据分散到多台机器。

Redis Cluster:把缓存摊到多机
单机 Redis 内存/连接有上限,集群化才能支撑亿级热点

为什么需要

热点数据(商品详情、用户会话、排行榜)直接打数据库会瞬间击穿。缓存放在内存,读延迟亚毫秒级,但需要的内存远超单机容量。

如何实现(两种主流方案)

  • 把数据空间切成 16384 个 slot,均匀分布到多个 master 节点。
  • 每个 master 配若干 replica 做高可用,master 挂了 replica 顶上。
  • 节点间用 gossip 协议互通拓扑,客户端可重定向(MOVED)到正确节点。
  • 扩缩容时通过 reshard 迁移 slot,对业务影响可控。
  • 客户端用 一致性哈希把 key 映射到哈希环上的节点。
  • 节点增减只影响环上相邻的一小段 key,避免全量重映射(缓存雪崩)。
  • 通常配合 虚拟节点让数据更均匀。
⚠️
三个经典坑:缓存穿透(查不存在的 key → 打库,用空值缓存/布隆过滤器)、缓存击穿(热点 key 过期瞬间并发打库,用互斥锁/逻辑过期)、缓存雪崩(大量 key 同时过期,用随机 TTL + 多级缓存)。
🏢
真实案例:微博「热搜」、抖音「点赞数」、12306「余票查询」都重度依赖分布式缓存扛峰值读。

🗄️ 三、存储与数据库

当数据量超过单机磁盘与单机写入能力,就必须把存储本身分布化。这里同时出现了"分库分表"的工程折中和"原生分布式数据库"的新范式。

🐬
3. 分库分表(Sharding)
把一张大表拆成 N 个物理表,分散到多库多机

为什么需要

单表几千万行后,B+ 树变深、索引维护变慢、写入锁竞争剧烈。分库分表把数据水平拆分到多个库/表,突破单机容量与性能上限。

如何实现

SQL 请求
带 user_id
Sharding 中间件
ShardingSphere
路由改写
库0·表_00
hash%4=0
库1·表_01
hash%4=1
  • 分片键(sharding key)是核心:选错会导致"跨分片查询/热点"。常用 user_id、订单 id、tenant_id。
  • 路由算法:取模、范围、一致性哈希、基因法(让关联数据落同一分片)。
  • 中间件:ShardingSphere、MyCat 拦截 SQL,自动改写路由、聚合跨分片结果。
  • 代价:分布式事务变难、跨分片 JOIN/分页复杂、扩容需迁移数据。
🌿
4. 原生分布式数据库(NewSQL)
无需手动分库分表,数据库自身就是分布式的

TiDB、CockroachDB、OceanBase 为代表:计算与存储分离,数据自动按 range 分片(Region),多副本通过 Raft 保证一致性与高可用,对业务暴露标准 SQL。

维度分库分表原生分布式 DB(TiDB 等)
分片业务/中间件手动管理内核自动分片 + 自动均衡
事务需引入分布式事务方案原生支持 ACID( Percolator 模型)
扩容需停机/脚本迁移在线加节点,自动 rebalance
适用legacy MySQL 改造新业务 / 海量数据
💡
它们本质是把 NoSQL 的可扩展性 + 关系型的事务/SQL 揉在一起,是"分布式系统理论"在存储层的集大成者。
🔎
5. 分布式搜索引擎(Elasticsearch)
全文检索、日志分析、聚合统计的标配

实现:数据写入经倒排索引构建;索引被拆成多个 shard(分片,可分布多机),每个 shard 有 replica(副本)。查询时协调节点把请求扇出到相关 shard,归并结果。近实时(refresh 间隔内可见)。

🏢
真实案例:电商商品搜索、App 内搜索、日志检索(ELK)、安全风控的字段聚合,几乎都用 ES 集群扛高并发查询。
🗂️
6. 对象存储 / 分布式文件系统
海量图片、视频、备份文件的可靠存储

实现:以 Ceph、MinIO、阿里云 OSS 为例,文件被切分成多个数据块,按三副本纠删码(EC)跨机架/跨机房存放,保证任意单点故障不丢数据;大文件上传走分片上传 + 合并。

📨 四、消息队列与异步解耦

这是分布式系统"削峰填谷、解耦服务、最终一致"的基石。没有它,微服务之间会耦合到寸步难行。

📨
7. 消息队列(Kafka / RocketMQ)
生产者-消费者解耦,流量削峰,事件驱动

三个典型用途

🔌 异步解耦
服务不直接调用
下单后发"订单创建"事件
库存/积分/通知各自订阅
下游挂了不影响下单
🌊 削峰填谷
抗突发流量
大促瞬时写进 MQ
消费者按自己节奏消费
保护后端数据库
⚖️ 最终一致
跨服务事务
本地事务+发消息
下游消费对账补偿
实现跨服务一致性

Kafka 的关键分布式设计

  • Topic → Partition:分区是并行单元,也是顺序保证单元(同分区内有序)。
  • Replication + ISR:每个分区多副本,Leader 处理读写,Follower 通过 ISR 同步,Leader 挂了从 ISR 选新 Leader。
  • Consumer Group:同组消费者分摊分区,实现水平消费能力扩展。
  • 顺序写盘 + 零拷贝:让 Broker 吞吐极高,单机可达百万级 TPS。
// 典型:下单成功后发事件,下游解耦处理
public void createOrder(Order o) {
    orderRepo.save(o);                 // 1. 本地事务落库
    kafkaTemplate.send("order-created", o.id); // 2. 发事件
}
// 库存/积分/风控服务各自 @KafkaListener 消费,互不阻塞
🏢
真实案例:美团订单、滴滴派单、字节推荐埋点,都是"入口写 MQ、下游几十个消费者各取所需"的事件驱动架构。

🧩 五、微服务与协同

把一个大应用拆成多个小服务,每个服务独立部署、独立扩展——这本身就是把一个进程内的调用,变成了跨网络的分布式调用。

🔍
8. 服务注册与发现
动态环境下,调用方如何找到被调方实例

问题:实例 IP 随时在变(扩缩容、重启、迁移),硬编码地址不可能。实现:服务启动时把自己注册到注册中心(Nacos / ZooKeeper / Etcd / Consul);调用方从注册中心拉取可用实例列表,配合负载均衡选一个调用;实例下线时注册中心通知调用方摘除。

服务 A
启动时注册
注册中心
Nacos/Zk
心跳保活
服务 B
拉列表调用
🪪
9. 分布式 Session
登录态在多台应用实例间共享

为什么:无状态应用多实例部署后,用户第一次请求打到节点 A 登录,第二次请求被负载均衡到节点 B,B 不认识这个 Session。

集中存储
最常用
Session 存 Redis
所有节点共享
推荐方案
粘性会话
简单但有损
同一用户固定节点
节点挂则掉登录
JWT 无状态
令牌自包含
信息加密进 token
服务端不存,难吊销
10. 分布式定时任务
避免多实例重复执行同一任务

问题:定时任务在多实例下会"每人都跑一次",导致重复扣款、重复发券。实现:用 Elastic-Job、XXL-JOB、SchedulerX 等,借助注册中心做分片调度——把任务数据按分片键拆开,每台机器只跑自己分片的那部分;或通过选举/分布式锁保证同一时刻只有一个实例执行。

// XXL-JOB 分片示例:3 个实例分别处理 user_id % 3 == 0/1/2 的用户
int shardIndex = shardingUtil().getIndex();
int shardTotal = shardingUtil().getTotal();
List<User> users = userDao.findByMod(shardTotal, shardIndex);

🧭 六、协调服务与一致性原语

分布式系统需要一个"大家都能信任的裁判":谁是当前主节点?配置变了怎么通知所有人?一把锁怎么在多机间互斥?这层提供最基础的分布式原语。

🔒
11. 分布式锁
跨进程/跨机器的互斥,保证关键操作串行

场景:秒杀扣库存、幂等防重、定时任务防并发。单机 synchronized 在多机无效。

// SET key value NX PX 30000 原子加锁,带过期防死锁
boolean ok = redis.set("lock:order:1001", uuid,
                    "NX", "PX", 30000);
if (ok) {
   try { /* 临界区 */ } finally { /* 用 Lua 校验 uuid 后释放 */ }
}

高可用场景可用 Redlock(向多个独立 Redis 节点申请,多数成功才算拿到锁)。

  • /locks 下创建临时顺序节点
  • 判断自己是不是序号最小者:是则拿到锁,否则监听前一个节点。
  • 客户端宕机 → 临时节点自动消失 → 后一个节点被唤醒(避免死锁)。
  • 优点:自动释放、可重入、公平;缺点:写放大、依赖 Zk 可用性。
🧭
12. 协调 / 配置中心 / 选主
ZooKeeper · Etcd:分布式系统的"神经中枢"
选主(Leader Election)
HA 关键
主从架构选唯一 Master
Kafka/HBase/Storm 都用
配置中心
动态下发
配置改了秒级推送到全集群
Nacos/Apollo 基于此
命名/注册
服务发现
树形节点存实例列表
watch 机制感知变化
💡
ZooKeeper 用 Zab 协议、Etcd 用 Raft 协议保证集群内数据一致——它们是"一致性算法"在工业界最成功的落地,也是本文大量场景(注册中心、选主、锁)的共同底座。
🆔
13. 分布式 ID 生成
全局唯一、趋势递增、不依赖单库自增
Snowflake
雪花算法
41bit 时间戳
10bit 机器 id
12bit 序列号
号段(Leaf-segment)
美团方案
DB 批量取号段
本地递增,少访问 DB
UUID
最简单
无中心、无序
不适合做索引主键

📊 七、分布式大数据计算

当数据量大到单机算不动(TB/PB 级),就要把计算任务拆到成百上千台机器并行跑——这是分布式系统"计算向数据移动"的经典场景。

📊
14. 离线批处理(MapReduce / Spark)
每天跑一次的数仓 ETL、报表、特征计算

MapReduce 思想:把"大任务"拆成 map(各算各的分片)+ shuffle(按 key 聚合)+ reduce(汇总)。Spark 在此基础上用内存 RDD + DAG 省掉反复落盘,速度快数十倍。

HDFS 分片
block1..N
Map
并行映射
多机并行
Shuffle
按 key 聚合
Reduce
汇总输出
🌊
15. 实时流处理(Flink / Storm)
秒级延迟的实时风控、实时大屏、实时推荐

实现:把无限数据流切成小批次/逐条处理,算子并行度可任意调节;通过checkpoint(分布式快照)记录状态,故障后从最近快照恢复,实现精确一次(exactly-once)语义。

🏢
真实案例:双十一实时 GMV 大屏、支付宝实时反欺诈、抖音实时直播间数据,都由 Flink 集群逐条处理海量事件流。

🛡️ 八、稳定性与容灾保障

分布式天然有更多故障点。这一层用"限流、熔断、降级、多活"把"部分坏掉"隔离成"整体还能用"。

🚦
16. 限流 / 熔断 / 降级
保护系统不被流量压垮或被故障拖死
限流(Sentinel)
控入口
令牌桶 / 漏桶 / 滑动窗口
超阈值直接拒绝
保护自身资源
熔断(Circuit Breaker)
断依赖
错误率超阈值则开路
快速失败不堆积线程
半开探活恢复
降级(Fallback)
保核心
非核心功能返回默认
商品详情页先出骨架
评论/推荐可暂隐
雪崩效应:一个下游慢 → 上游线程池占满 → 上游也变慢 → 层层传导拖垮全站。限流/熔断正是切断这条传导链。
🌏
17. 多机房 / 异地多活
单机房挂了,业务不中断

实现:把流量按单元(Cell)切分,每个单元自包含(接入+应用+数据),用户被路由到固定单元;单元间通过数据同步(如 MySQL 主从、DRC)保持最终一致。灾难时把流量整体切到健康单元。典型如支付宝"三地五中心"。

🧭 总结:一句话记住每个场景

分布式系统不是"一个技术",而是"把一件事拆到多机协同"的方法论。下面按层次归纳本报告覆盖的 17 个典型场景。

层次典型场景核心分布式技术
接入流量负载均衡、CDNLVS/Nginx、DNS 调度、一致性哈希、健康检查
缓存分布式缓存Redis Cluster(16384 slot)、客户端一致性哈希
存储分库分表、NewSQL、ES、对象存储Sharding、Raft 多副本、倒排索引、纠删码
异步消息队列Partition、ISR、Consumer Group、零拷贝
微服务注册发现、Session、定时任务注册中心、集中式 Session、分片调度
协调分布式锁、选主、配置、IDZab/Raft、SET NX、临时有序节点、Snowflake
计算离线批处理、实时流MapReduce/Spark、Flink checkpoint
稳定性限流/熔断/降级、异地多活令牌桶、熔断器、单元化、数据同步
🧩
贯穿一切的主线:拆分(Scale-out)→ 复制(Replication)→ 共识(Consensus)→ 容错(Fault Tolerance)。理解了这 16 个字,就理解了为什么互联网架构长成今天这样。