Skip to content

Latest commit

 

History

History
295 lines (214 loc) · 6.31 KB

File metadata and controls

295 lines (214 loc) · 6.31 KB

5.1 CAP定理与BASE理论

📍 导航返回目录 | 下一节:一致性模型


CAP定理

三要素

  • C (Consistency) - 一致性:所有节点同一时刻看到相同数据
  • A (Availability) - 可用性:每个请求都能得到响应(成功或失败)
  • P (Partition Tolerance) - 分区容错性:网络分区时系统仍能工作

核心结论

分布式系统在网络分区(P)存在时,只能在一致性(C)和可用性(A)之间权衡取舍!

⚠️ 注意:常见的"三选二"表述并不准确。在分布式环境中,网络分区是客观存在的,因此P是必选项。实际上是在P的前提下,在C和A之间进行权衡。

     C
    / \
   /   \
  /     \
 / CP AP \
A ------- P
   (CA不现实)

现实选择

网络分区不可避免 → 必须选择 P

因此实际选择:

  • CP系统:牺牲可用性,保证一致性
  • AP系统:牺牲一致性,保证可用性

CP系统

特点

  • 网络分区时,少数节点不可用
  • 保证数据强一致性

典型系统

1. Zookeeper / etcd

// etcd事务:保证强一致性
_, err := cli.Txn(ctx).
    If(clientv3.Compare(clientv3.Value(key), "=", oldValue)).
    Then(clientv3.OpPut(key, newValue)).
    Commit()

2. HBase

  • Region Server宕机时,该Region不可用
  • 保证读取到最新数据

3. MongoDB(默认配置)

// 写入时等待主节点确认
db.collection.insertOne({...}, {writeConcern: {w: "majority"}})

AP系统

特点

  • 网络分区时,所有节点仍可用
  • 允许数据短暂不一致
  • 最终一致性

典型系统

1. Cassandra

-- 调整一致性级别
SELECT * FROM users WHERE id = 1 
USING CONSISTENCY ONE;  -- 只需一个节点响应

2. DynamoDB

  • 多副本架构
  • Quorum机制:W + R > N

3. Eureka(服务注册中心)

  • AP优先
  • 允许短暂的服务信息不一致

BASE理论

CAP的补充

  • BA (Basically Available) - 基本可用
  • S (Soft state) - 软状态
  • E (Eventually consistent) - 最终一致性

核心思想

放弃强一致性,追求最终一致性


最终一致性实现

1. 读修复(Read Repair)

func ReadWithRepair(key string, replicas []Node) (value string, err error) {
    responses := make(map[string]int)
    
    // 并发读取所有副本
    for _, node := range replicas {
        val, _ := node.Get(key)
        responses[val]++
    }
    
    // 找到最新值(版本号最大)
    latestValue := findLatest(responses)
    
    // 修复不一致的节点
    for _, node := range replicas {
        val, _ := node.Get(key)
        if val != latestValue {
            node.Set(key, latestValue)  // 修复
        }
    }
    
    return latestValue, nil
}

2. 写时冲突解决

Vector Clock(向量时钟)

type VectorClock map[string]int

func (vc VectorClock) Increment(nodeID string) {
    vc[nodeID]++
}

func (vc VectorClock) Compare(other VectorClock) string {
    less, greater := false, false
    
    for k, v := range vc {
        if otherV, ok := other[k]; ok {
            if v < otherV {
                less = true
            } else if v > otherV {
                greater = true
            }
        }
    }
    
    if less && !greater {
        return "LESS"  // vc < other
    } else if greater && !less {
        return "GREATER"  // vc > other
    } else if !less && !greater {
        return "EQUAL"
    } else {
        return "CONCURRENT"  // 冲突
    }
}

3. 消息队列

// 通过异步消息保证最终一致性
func UpdateUser(userID string, data UserData) error {
    // 1. 更新主库
    if err := db.Update(userID, data); err != nil {
        return err
    }
    
    // 2. 发送同步消息
    msg := SyncMessage{
        UserID: userID,
        Data:   data,
    }
    return messageQueue.Publish("user.sync", msg)
}

// 消费者同步到其他系统
func Consumer() {
    messageQueue.Subscribe("user.sync", func(msg SyncMessage) {
        cache.Update(msg.UserID, msg.Data)
        searchEngine.Update(msg.UserID, msg.Data)
        // ... 其他系统
    })
}

实战案例

电商库存系统

需求

  • 高可用(不能因为网络问题导致无法下单)
  • 最终一致(允许短暂超卖,后续补偿)

方案:AP + 最终一致性

// 1. 预扣库存(本地)
func PreDeductStock(productID string, quantity int) bool {
    localStock := localCache.Get(productID)
    if localStock >= quantity {
        localCache.Decr(productID, quantity)
        return true
    }
    return false
}

// 2. 异步同步到数据库
func AsyncSyncStock(productID string, quantity int) {
    msg := StockMessage{
        ProductID: productID,
        Quantity:  quantity,
        Timestamp: time.Now(),
    }
    mq.Publish("stock.sync", msg)
}

// 3. 定时对账
func ReconcileStock() {
    ticker := time.NewTicker(10 * time.Minute)
    for range ticker.C {
        // 对比本地缓存和数据库
        // 发现超卖则退款补偿
    }
}

系统选型建议

场景 选择 理由
金融交易 CP 强一致性要求
配置中心 CP 配置错误影响大
社交Feed AP 可用性优先
电商库存 AP 高可用,允许补偿
分布式锁 CP 互斥性要求
服务注册 AP 可用性优先

本章小结

关键要点

  • ✅ CAP定理:分布式系统的铁律
  • ✅ 网络分区不可避免,必须选择CP或AP
  • ✅ BASE理论:放弃强一致,追求最终一致
  • ✅ 根据业务场景选择合适的一致性模型

扩展阅读


💡 思考题

  1. 为什么CA系统在分布式环境中不现实?
  2. 如何设计一个最终一致性系统?
  3. 电商秒杀应该选择CP还是AP?

⏮️ 返回目录 | ⏭️ 下一节:一致性模型