{T}

高可用架构 学习笔记(第 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
部署方式多节点部署相同应用多节点部署不同服务
数据一致性强一致性最终一致性
扩展性垂直扩展为主水平扩展为主
故障影响单节点故障影响小服务间故障可能传播
复杂度相对简单较复杂