分布式系统概述
分布式系统是由多个独立的计算机节点组成的系统,这些节点通过网络通信协调工作,对用户呈现为单一的连贯系统。
为什么需要分布式系统?
单机系统的局限性
随着业务规模增长,单机系统面临诸多挑战:
- 计算能力有限:单个CPU核心数有限,无法处理海量并发请求
- 存储容量有限:硬盘容量和内存都有物理限制
- 可用性低:硬件故障导致服务中断
- 地理分布受限:用户地理位置分散,需要就近访问
分布式系统的优势
| 优势 | 说明 |
|---|---|
| 横向扩展 | 通过增加节点来提升系统容量和性能 |
| 高可用 | 多副本机制,单节点故障不影响整体服务 |
| 高性能 | 并行处理多个请求,负载均衡 |
| 地理分布 | 部署在多个数据中心,降低访问延迟 |
分布式系统的挑战
分布式系统虽然解决了单机系统的局限性,但也带来了新的挑战:
1. 网络问题
- 消息丢失:网络传输过程中可能出现丢包
- 消息延迟:网络传输存在不确定的延迟
- 网络分区:网络故障导致节点间无法通信
2. 节点故障
- 硬件故障:硬盘损坏、内存故障、服务器宕机
- 软件故障:程序崩溃、死锁、资源耗尽
- 人为失误:误操作、配置错误
3. 时钟同步
分布式系统中,不同节点上的事件顺序难以确定:
节点A: 10:00:00 写入X=1
节点B: 10:00:01 写入X=2
节点C: 10:00:00 读取X,应该得到什么值?
4. 分布式事务
多个节点的数据操作需要保证原子性,这比单机事务复杂得多。
分布式系统架构模式
1. 客户端-服务器模式
最基础的分布式模式:
2. 三层架构
3. 微服务架构
将应用拆分为多个小型服务:
4. 事件驱动架构
核心概念
1. 冗余与复制
通过在多个节点保存相同数据副本提高可用性:
// 主从复制示意
class ReplicationExample {
// 主节点处理写入
void write(MasterDB db, String key, String value) {
db.write(key, value);
// 异步复制到从节点
for (ReplicaDB replica : replicas) {
replica.asyncReplicate(key, value);
}
}
// 从节点处理读取
String read(ReplicaDB replica, String key) {
return replica.read(key);
}
}
2. 分区
将数据分散存储到不同节点:
// 简单分区策略
class ShardingExample {
// 哈希分区
int hashSharding(String key, int shardCount) {
return Math.abs(key.hashCode() % shardCount);
}
// 范围分区
String rangeSharding(int userId) {
if (userId < 1000000) return "shard1";
if (userId < 2000000) return "shard2";
return "shard3";
}
}
3. 负载均衡
将请求分配到多个节点:
分布式系统设计原则
1. 拥抱故障
分布式系统应该能够容忍节点故障:
// 失败重试示例
class RetryExample {
public String callWithRetry(String service) {
int maxRetries = 3;
for (int i = 0; i < maxRetries; i++) {
try {
return callService(service);
} catch (Exception e) {
if (i == maxRetries - 1) throw e;
// 指数退避
Thread.sleep((long) Math.pow(2, i) * 100);
}
}
throw new RuntimeException("重试次数耗尽");
}
}
2. 冗余设计
关键组件应有备份:
// 多副本写入
class RedundancyExample {
List<Replica> replicas;
void writeWithQuorum(String key, String value) {
// 写入多数派节点
int written = 0;
for (Replica replica : replicas) {
if (replica.write(key, value)) {
written++;
}
}
// 至少写入多数派
if (written < replicas.size() / 2 + 1) {
throw new QuorumNotMetException();
}
}
}
3. 异步通信
减少系统间的耦合:
// 异步消息处理
class AsyncMessagingExample {
MessageQueue queue;
void processOrder(Order order) {
// 异步写入消息队列,不阻塞
queue.send("orders", order);
// 立即返回
return "订单已受理";
}
}
课程大纲
本教程将深入探讨分布式系统的核心概念:
-
分布式理论基础
- CAP定理:一致性、可用性、分区容错性的权衡
- BASE理论:最终一致性解决方案
- FLP不可能定理
-
分布式一致性
- 一致性模型(强一致性、最终一致性等)
- 分布式事务(2PC、3PC、TCC)
- 共识算法(Paxos、Raft)
-
分布式数据管理
- 数据分区与分片
- 数据复制策略
- 分布式缓存
-
分布式计算
- 批处理(MapReduce)
- 流处理
- 任务调度
-
服务治理
- 服务发现
- 负载均衡
- 熔断与限流
-
实践案例
- 分布式ID生成
- 分布式锁
- 分布式事务实现
小结
分布式系统是现代大规模互联网应用的基础架构。本章我们学习了:
- 为什么需要分布式系统:解决单机系统的计算、存储、可用性和地理分布问题
- 分布式系统的挑战:网络问题、节点故障、时钟同步、分布式事务
- 常见的分布式架构模式:客户端-服务器、三层架构、微服务架构、事件驱动架构
- 核心概念:冗余与复制、分区、负载均衡
- 设计原则:拥抱故障、冗余设计、异步通信
在后续章节中,我们将深入学习分布式系统的核心理论和实践技术。