高可用架构 学习笔记(第 7 部分)
3.3 CAP 权衡示例
CP 方案:强一致性优先
javascript
// CP 系统: 一致性优先
class CPSystem {
constructor() {
this.nodes = ['node1', 'node2', 'node3']
this.data = {}
this.lock = new DistributedLock()
}
// 写入数据 (保证一致性)
async write(key, value) {
// 1. 获取分布式锁
const lockAcquired = await this.lock.acquire(key)
if (!lockAcquired) {
throw new Error('无法获取锁,写入失败')
}
try {
// 2. 写入所有节点
const writePromises = this.nodes.map(node =>
this.writeToNode(node, key, value)
)
// 3. 等待所有节点写入成功
await Promise.all(writePromises)
// 4. 释放锁
await this.lock.release(key)
return { success: true }
} catch (error) {
// 任何节点写入失败,整个操作失败
await this.lock.release(key)
throw new Error('写入失败,数据不一致')
}
}
// 读取数据
async read(key) {
// 从任意节点读取 (数据一致)
const node = this.nodes[0]
return this.readFromNode(node, key)
}
async writeToNode(node, key, value) {
// 模拟节点写入
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.1) {
this.data[key] = value
resolve()
} else {
reject(new Error(`节点 ${node} 写入失败`))
}
}, 10)
})
}
async readFromNode(node, key) {
return this.data[key]
}
}
// 分布式锁
class DistributedLock {
async acquire(key) {
// 使用 Redis 实现分布式锁
return true
}
async release(key) {
return true
}
}AP 方案:可用性优先
javascript
// AP 系统: 可用性优先
class APSystem {
constructor() {
this.nodes = ['node1', 'node2', 'node3']
this.data = {
node1: {},
node2: {},
node3: {}
}
}
// 写入数据 (保证可用性)
async write(key, value) {
const successfulNodes = []
const failedNodes = []
// 尝试写入所有节点,但不等待全部成功
for (const node of this.nodes) {
try {
await this.writeToNode(node, key, value)
successfulNodes.push(node)
} catch (error) {
failedNodes.push(node)
console.log(`节点 ${node} 写入失败,但继续`)
}
}
// 只要有至少一个节点成功,就返回成功
if (successfulNodes.length > 0) {
// 异步同步到失败的节点
this.syncToFailedNodes(failedNodes, key, value)
return {
success: true,
writtenNodes: successfulNodes.length
}
} else {
throw new Error('所有节点写入失败')
}
}
// 读取数据
async read(key) {
// 从最近的节点读取
for (const node of this.nodes) {
try {
const value = await this.readFromNode(node, key)
if (value !== undefined) {
return value
}
} catch (error) {
continue
}
}
return null
}
// 异步同步到失败的节点
async syncToFailedNodes(nodes, key, value) {
// 后台任务:最终一致性
setTimeout(async () => {
for (const node of nodes) {
try {
await this.writeToNode(node, key, value)
console.log(`节点 ${node} 同步成功`)
} catch (error) {
console.log(`节点 ${node} 同步失败,稍后重试`)
}
}
}, 1000)
}
async writeToNode(node, key, value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.3) {
this.data[node][key] = value
resolve()
} else {
reject(new Error())
}
}, 10)
})
}
async readFromNode(node, key) {
return this.data[node][key]
}
}四、集群架构 vs 分布式架构
4.1 架构对比
| 对比维度 | 集群架构 | 分布式架构 |
|---|---|---|
| CAP 特性 | CA (一致性 + 可用性) | CP 或 AP |
| 部署方式 | 多节点部署相同应用 | 多节点部署不同服务 |
| 数据一致性 | 强一致性 | 最终一致性 |
| 扩展性 | 垂直扩展为主 | 水平扩展为主 |
| 故障影响 | 单节点故障影响小 | 服务间故障可能传播 |
| 复杂度 | 相对简单 | 较复杂 |