9.4 分布式系统理论

面试重要程度:⭐⭐⭐⭐⭐

常见提问方式: "CAP定理是什么?如何理解一致性Hash算法?"

技术深度: 分布式理论基础、算法原理、实际应用

预计阅读时间:35分钟

🎯 CAP定理

CAP定理基础

CAP定理指出,在分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance)三者不可能同时满足,最多只能满足其中两个。

三要素详解:

/**
 * CAP定理演示
 */
public class CAPTheoremDemo {
    
    /**
     * 一致性(Consistency)
     * 所有节点在同一时间看到相同的数据
     */
    public void consistencyExample() {
        /*
         * 强一致性示例:
         * 用户在节点A更新了个人信息
         * 立即从节点B查询,必须能看到最新信息
         * 
         * 实现方式:
         * - 同步复制
         * - 分布式锁
         * - 两阶段提交
         */
    }
    
    /**
     * 可用性(Availability)
     * 系统在任何时候都能响应用户请求
     */
    public void availabilityExample() {
        /*
         * 高可用性示例:
         * 即使部分节点故障,系统仍能正常服务
         * 
         * 实现方式:
         * - 冗余备份
         * - 故障转移
         * - 负载均衡
         */
    }
    
    /**
     * 分区容错性(Partition Tolerance)
     * 系统能够容忍网络分区故障
     */
    public void partitionToleranceExample() {
        /*
         * 分区容错示例:
         * 网络故障导致节点间无法通信
         * 系统仍能继续运行
         * 
         * 实现方式:
         * - 数据复制
         * - 分布式一致性算法
         * - 故障检测机制
         */
    }
}

CAP权衡策略

/**
 * 不同系统的CAP选择
 */
@Component
public class CAPTradeoffs {
    
    /**
     * CP系统:选择一致性和分区容错性
     * 牺牲可用性,在网络分区时停止服务
     */
    public void cpSystemExample() {
        /*
         * 典型代表:
         * - MongoDB(强一致性模式)
         * - HBase
         * - Redis Cluster
         * 
         * 适用场景:
         * - 金融交易系统
         * - 库存管理系统
         * - 账户余额系统
         */
    }
    
    /**
     * AP系统:选择可用性和分区容错性
     * 牺牲一致性,允许数据暂时不一致
     */
    public void apSystemExample() {
        /*
         * 典型代表:
         * - Cassandra
         * - DynamoDB
         * - CouchDB
         * 
         * 适用场景:
         * - 社交媒体
         * - 内容分发
         * - 日志收集
         */
    }
}

/**
 * 实际项目中的CAP权衡
 */
@Service
public class PracticalCAPImplementation {
    
    @Autowired
    private DistributedLock distributedLock;
    
    /**
     * CP模式实现:订单创建
     */
    @Transactional
    public Order createOrderCP(CreateOrderRequest request) {
        String lockKey = "order:create:" + request.getUserId();
        
        if (!distributedLock.tryLock(lockKey, 30000)) {
            throw new ServiceUnavailableException("系统繁忙,请稍后重试");
        }
        
        try {
            // 强一致性检查
            if (!checkInventoryConsistency(request.getProductId(), request.getQuantity())) {
                throw new InsufficientStockException("库存不足");
            }
            
            Order order = new Order(request);
            return orderRepository.save(order);
        } finally {
            distributedLock.unlock(lockKey);
        }
    }
    
    /**
     * AP模式实现:用户信息更新
     */
    public void updateUserInfoAP(Long userId, UserInfo userInfo) {
        try {
            // 异步更新所有副本
            CompletableFuture.allOf(
                updateUserInfoAsync("primary", userId, userInfo),
                updateUserInfoAsync("replica1", userId, userInfo),
                updateUserInfoAsync("replica2", userId, userInfo)
            );
        } catch (Exception e) {
            log.warn("部分用户信息更新失败,将通过后台任务同步", e);
            recordFailedUpdate(userId, userInfo);
        }
    }
}

🔄 BASE理论

BASE理论概述

BASE理论是对CAP定理的延伸:

  • BA(Basically Available):基本可用
  • S(Soft State):软状态
  • E(Eventually Consistent):最终一致性
/**
 * BASE理论实现
 */
@Component
public class BASEImplementation {
    
    /**
     * 基本可用(Basically Available)
     */
    @Service
    public class BasicAvailabilityService {
        
        public UserInfo getUserInfo(Long userId) {
            // 尝试从主节点获取
            try {
                return primaryNode.getUserInfo(userId);
            } catch (Exception e) {
                log.warn("Primary node unavailable, trying backup nodes");
            }
            
            // 主节点不可用,尝试备份节点
            for (DataNode backupNode : backupNodes) {
                try {
                    UserInfo userInfo = backupNode.getUserInfo(userId);
                    if (userInfo != null) {
                        userInfo.setDataSource("backup");
                        return userInfo;
                    }
                } catch (Exception e) {
                    log.warn("Backup node {} unavailable", backupNode.getName());
                }
            }
            
            // 返回缓存数据
            return cacheService.getCachedUserInfo(userId);
        }
    }
    
    /**
     * 最终一致性(Eventually Consistent)
     */
    @Service
    public class EventualConsistencyService {
        
        @Transactional
        public void updateUserBalance(Long userId, BigDecimal amount) {
            // 1. 更新主数据
            User user = userRepository.findById(userId);
            user.setBalance(user.getBalance().add(amount));
            userRepository.save(user);
            
            // 2. 发布变更事件
            BalanceChangeEvent event = new BalanceChangeEvent();
            event.setUserId(userId);
            event.setAmount(amount);
            event.setNewBalance(user.getBalance());
            
            messageProducer.send("user.balance.changed", event);
        }
        
        @EventListener
        @Async
        public void handleBalanceChanged(BalanceChangeEvent event) {
            // 异步更新各个副本
            dataNodes.parallelStream().forEach(node -> {
                try {
                    node.updateUserBalance(event.getUserId(), event.getNewBalance());
                } catch (Exception e) {
                    log.error("Failed to sync balance to node: {}", node.getName(), e);
                    recordSyncFailure(node.getName(), event);
                }
            });
        }
        
        // 定时一致性检查
        @Scheduled(fixedRate = 300000)
        public void checkConsistency(

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

Java面试圣经 文章被收录于专栏

Java面试圣经,带你练透java圣经

全部评论
欢迎讨论
点赞 回复 分享
发布于 09-06 11:26 江西
干货满满,楼主牛逼
点赞 回复 分享
发布于 09-02 14:05 陕西

相关推荐

A了2.5,笔试题还比较常规,大家感觉如何?
咩咩子_:不是就一道题吗 ,我的是 有向图+最短路径
点赞 评论 收藏
分享
08-15 13:50
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务