1. 分布式计算概述:分布式系统的定义、发展历史、核心挑战
大家好,我是你们的老朋友。今天咱们正式开讲分布式计算框架的第一章。
说实话,我刚开始接触分布式系统时,觉得这东西特别神秘。一堆机器连在一起,还能像一台机器一样工作,想想就觉得很酷。但后来真正上手做项目,才发现——嗯,这玩意儿坑也不少。
这一章,咱们先把地基打牢。我会从定义讲起,聊聊分布式系统是怎么一步步发展到今天的,然后重点剖析它的核心挑战。尤其是CAP理论和一致性模型,这两个东西你搞不懂,后面写代码会吃大亏。
1.1 什么是分布式系统?
先给个定义。分布式系统,说白了就是一群独立的计算机,通过网络连接起来,对外表现得像一台计算机。
你想想看,你每天用的微信、淘宝、抖音,背后都是成千上万台服务器在协同工作。但你用的时候,感觉就像在跟一台超级计算机打交道。这就是分布式系统的魅力。
我个人习惯把分布式系统拆成三个关键词来理解:
- 独立:每台机器都有自己的CPU、内存、硬盘,各自运行着操作系统
- 网络:机器之间靠网络通信,消息会延迟,也会丢包
- 统一:对外暴露的是一个整体,用户不需要知道背后有多少台机器
核心要点:分布式系统的本质,就是用多台普通机器,拼出一台"超级机器"。但代价是——你得处理网络带来的各种不确定性。
1.2 发展历史:从单机到集群
分布式系统不是一天建成的。我把它分成几个阶段,这样好理解:
| 年代 | 阶段 | 特点 | 代表系统 |
|---|---|---|---|
| 1980s | 萌芽期 | 局域网、文件共享、RPC雏形 | Sun NFS、CORBA |
| 1990s | 探索期 | 分布式文件系统、集群计算 | AFS、GFS(论文) |
| 2000s | 爆发期 | 互联网大爆发、海量数据 | Google三驾马车、Hadoop |
| 2010s至今 | 成熟期 | 云原生、容器化、流式计算 | Kubernetes、Spark、Flink |
我记得2004年Google发表GFS论文时,整个业界都震动了。那时候大家还在用单机数据库硬扛,突然发现——原来可以用上千台廉价PC来存数据、做计算。这思路,太颠覆了。
后来Hadoop开源,把Google的这套思想带给了全世界。我2012年第一次部署Hadoop集群,三台破机器,跑了整整一个周末才把配置调通。但跑通的那一刻,看着数据被分到不同节点上处理,那种成就感,至今难忘。
1.3 核心挑战:为什么分布式这么难?
好,定义和历史讲完了。咱们来聊聊最核心的问题——分布式系统到底难在哪?
你想想看,单机系统里,所有东西都在一台机器上。内存读写是纳秒级的,硬盘读写是毫秒级的,而且不会突然"断网"。但分布式系统呢?
- 网络延迟:从几毫秒到几秒不等
- 网络分区:交换机坏了,集群被切成两半
- 节点故障:硬盘坏了、内存满了、进程挂了
- 时钟不同步:每台机器的时间可能不一样
说白了,分布式系统要面对的,是一个充满不确定性的世界。
我曾经踩过的坑:有一次线上系统突然变慢,查了半天发现是两台机器的时间差了30秒。我们的分布式锁依赖时间戳,结果锁全乱了。从那以后,我每部署一个集群,第一件事就是检查NTP同步。
1.4 CAP理论:分布式系统的"不可能三角"
聊分布式,绕不开CAP理论。这是2000年Eric Brewer教授提出来的,后来被证明为定理。
CAP三个字母分别代表:
- C(Consistency)一致性:所有节点看到的数据是一样的
- A(Availability)可用性:每个请求都能收到响应(不保证数据是最新的)
- P(Partition Tolerance)分区容错性:系统出现网络分区时,仍能正常工作
CAP理论的核心就一句话:网络分区发生时,你必须在C和A之间二选一。
为什么会这样?我举个例子你就明白了。
假设你有两台服务器,分别在北京和上海。突然,北京到上海的网络断了(分区了)。这时候:
- 如果你选择一致性(C):那你就得拒绝所有写请求,直到网络恢复。因为一旦写了一台,另一台的数据就不一致了。这就是"牺牲可用性"。
- 如果你选择可用性(A):那你就允许两边各自写数据。等网络恢复后,再想办法合并。这就是"牺牲一致性"。
你想想看,没有完美的方案。只能根据业务场景来选。
我的经验:大部分互联网系统,选的是AP。比如淘宝的商品库存,偶尔超卖几件可以接受,但系统不能挂。而银行系统,选的是CP。宁可拒绝交易,也不能账目对不上。
1.5 一致性模型:从强到弱
CAP理论里提到了一致性。但一致性本身,也有不同的"强度"。我按从强到弱的顺序,给你梳理一下:
| 模型 | 描述 | 典型场景 |
|---|---|---|
| 强一致性 | 写完后,任何读都能看到最新数据 | 银行转账、分布式锁 |
| 最终一致性 | 写完后,过一段时间所有节点数据会一致 | DNS、CDN缓存 |
| 因果一致性 | 有因果关系的操作,顺序一致 | 社交网络评论 |
| 读己之写 | 自己写的数据,自己一定能读到 | 用户个人设置 |
| 单调读 | 一旦读到某个值,后续不会读到更旧的值 | 新闻推送 |
我个人的习惯是:能用最终一致性,就别用强一致性。因为强一致性的代价太高了——性能下降、可用性降低、代码复杂度飙升。
举个例子。你在朋友圈发了一条动态。你的好友A刷新时看到了,好友B刷新时没看到。这其实没关系,过几秒B也能看到。这就是最终一致性。如果非要强一致,那每次发朋友圈都得等所有服务器同步完才能返回,体验就太差了。
避坑指南:我曾经在一个项目里,所有数据都要求强一致性。结果系统上线后,高峰期经常超时。后来我们分析发现,大部分数据其实不需要那么强的一致性。把非关键数据改成最终一致性后,系统吞吐量提升了3倍。
1.6 本章小结
好,这一章的内容就到这里。咱们回顾一下:
- 分布式系统就是一群独立计算机,通过网络协同,对外像一台机器
- 从80年代的萌芽,到现在的云原生,分布式系统已经走过了40年
- 核心挑战在于网络的不确定性:延迟、分区、故障
- CAP理论告诉我们:分区发生时,必须在一致性和可用性之间做取舍
- 一致性模型有强弱之分,选型要结合业务场景
下一章,咱们会深入讲分布式计算框架的架构设计。到时候我会拿MapReduce和Spark来举例,看看它们是怎么解决这些挑战的。
记住一句话:没有银弹,只有权衡。分布式系统的设计,本质上就是在各种约束下,找到最适合你业务的平衡点。
咱们下章见。