Posts for: #架构视界

宏观战略视角。聚焦云原生、高并发分布式设计、微服务治理、中台架构设计与技术选型的深度思考。

分布式系统演进:从 CAP 到 PACELC 的架构思考

CAP 定理是分布式系统的「牛顿第一定律」——它定义了这个领域的基本约束。但在真实的工程实践中,CAP 定理过于粗粒度,以至于它无法指导我们在实际系统中做出正确的设计决策。我们需要一个更精细的模型。

CAP 定理的再理解

2000 年,Eric Brewer 提出 CAP 猜想;2002 年,Gilbert 和 Lynch 给出了形式化证明。CAP 定理告诉我们:

在一个分布式系统中,以下三个特性最多只能同时满足两个:

C (Consistency)  - 一致性:所有节点在同一时刻看到相同的数据
A (Availability) - 可用性:每个请求都能在合理时间内收到非错误响应
P (Partition Tolerance) - 分区容错:网络分区发生时系统仍能运行

大多数架构师对 CAP 的理解停留在「三选二」的层面。但这个理解有几个问题:

问题 1:P 不是一个可选项

在真实的分布式系统中,网络分区是必然会发生的事情——交换机故障、光缆被挖断、数据中心之间的网络抖动。所以 P 不是你可以「选择放弃」的特性,它是一个既定事实。

真正的选择是在 C 和 A 之间,而且这个选择只在分区发生时才有意义。

没有分区时:C 和 A 可以同时满足
发生分区时:必须在 C 和 A 之间选择

CP 系统:分区时拒绝服务,保证一致性
  例:ZooKeeper、etcd、HBase

AP 系统:分区时继续服务,可能返回过期数据
  例:Cassandra、DynamoDB、CouchDB

问题 2:CAP 是全局的,但需求是局部的

同一个系统中,不同的业务操作可能有不同的一致性需求:

电商系统的一致性需求:

操作 A:扣减库存
  → 需要强一致性(不能超卖)→ CP

操作 B:展示商品评价
  → 可以接受最终一致性(延迟几秒看到新评价无所谓)→ AP

操作 C:用户修改收货地址
  → 需要强一致性(改错了会寄错地方)→ CP

操作 D:商品浏览量计数
  → 可以接受最终一致性(少计几次没关系)→ AP

一个成熟的分布式系统不会在全局层面选择 CP 或 AP,而是在每个操作级别做精细的选择。

[阅读全文]

Redis 高并发缓存架构:击穿、穿透、雪崩全解

缓存是提升系统吞吐量最简单的手段,但它引入的问题也比你想象的更多。击穿、穿透、雪崩——这三个听起来像地质灾害的名词,是每一个高并发系统设计者必须跨越的三道坎。

缓存的基本模型

在深入三个核心问题之前,先建立一个标准的缓存读写模型:

标准缓存读取流程:

客户端 → 缓存层(Redis)→ [命中] → 直接返回
                         → [未命中] → 数据库层 → 写入缓存 → 返回

标准缓存写入流程:

方案 A(Cache Aside):先更新数据库,再删除缓存
方案 B(Read/Write Through):通过缓存层代理读写
方案 C(Write Behind):只写缓存,异步刷入数据库

在绝大多数互联网场景中,Cache Aside(旁路缓存)是最常用的模式——代码直接操作 Redis 和数据库,简单透明。但正是这种简单性,隐藏着三大问题。

问题一:缓存穿透(Cache Penetration)

定义:查询一个根本不存在的数据,缓存中没有,数据库中也没有。每次请求都会穿透缓存直接打到数据库。

正常请求:
  查询 user_id=123 → 缓存命中 → 返回(快)

穿透请求:
  查询 user_id=-1 → 缓存未命中 → 查数据库 → 数据库也没有 → 返回空
  查询 user_id=-1 → 缓存未命中 → 查数据库 → 数据库也没有 → 返回空
  查询 user_id=-1 → 缓存未命中 → 查数据库 → 数据库也没有 → 返回空
  
  如果每秒 10000 次这样的请求,数据库直接被压垮

穿透通常由恶意攻击或业务 Bug 引起——攻击者构造大量不存在的 ID,绕过缓存直接攻击数据库。

[阅读全文]

微服务治理演进:从 Netflix OSS 到 Service Mesh

微服务架构的流行带来了一个悖论:系统被拆分成更小的单元以降低复杂度,但服务之间的通信却创造了一个更复杂的分布式系统。如何治理这个「服务间的混沌」,是过去十年基础架构领域最重要的课题之一。

第一阶段:蛮荒时代(2014 之前)

在微服务概念刚刚兴起的时候,服务治理几乎等于「手写一切」:

服务 A 调用服务 B:

1. 自己实现服务发现(查 ZooKeeper / Nginx upstream)
2. 自己实现负载均衡(轮询 / 随机)
3. 自己实现重试(try-catch + 循环)
4. 自己实现超时(设置 HTTP timeout)
5. 自己实现熔断(状态机 + 计数器)

每一个服务的开发者都要重复实现这些逻辑,而且不同团队的实现质量参差不齐

这个阶段的核心问题是:治理逻辑和业务逻辑耦合在应用代码中。每一次修改治理策略(比如调整超时时间),都需要修改业务代码、重新编译、重新部署。

第二阶段:SDK 时代(2014-2017)

Netflix 开源了一整套微服务治理工具(Netflix OSS),标志着微服务治理进入 SDK 时代:

Netflix OSS 全家桶:

Eureka    → 服务注册与发现
Ribbon    → 客户端负载均衡
Hystrix   → 熔断器
Feign     → 声明式 HTTP 客户端
Zuul      → API 网关
Archaius  → 动态配置

Spring Cloud 在此基础上做了封装,让 Java 开发者可以用注解的方式快速接入:

@FeignClient(name = "user-service", fallback = UserServiceFallback.class)
public interface UserServiceClient {
    @GetMapping("/users/{id}")
    User getUser(@PathVariable("id") Long id);
}

@Component
public class UserServiceFallback implements UserServiceClient {
    @Override
    public User getUser(Long id) {
        return User.defaultUser();  // 熔断降级
    }
}

SDK 模式的问题

Netflix OSS 解决了「重复造轮子」的问题,但它引入了新的痛点:

[阅读全文]

云算力 vs 本地破解:2026 年加密文件恢复方案选型指南

作为一名架构师,我习惯用系统思维来分析问题——即使这个「问题」是忘了自己加密文件的密码。加密文件密码恢复本质上是一个算力密集型任务,而算力的获取方式无非两种:本地和云端。这篇文章从架构角度对比两种方案的优劣,帮你做出理性的选择。

密码恢复的算力需求模型

先建立一个定量的认知框架。不同的加密格式,每次密码尝试的计算成本差异巨大:

各格式单次密码尝试的计算成本(从低到高):

WPA2 握手包:     PBKDF2-SHA1, 4096 迭代     → 约 1,600 FLOPs/次
ZIP (ZipCrypto): RC4-40                       → 约 500 FLOPs/次
RAR3:            AES-128 + SHA1               → 约 5,000 FLOPs/次
Office 2007:     AES-128 + SHA1, 50K 迭代     → 约 20,000 FLOPs/次
RAR5:            AES-256 + SHA256, 可配置迭代  → 约 50,000 FLOPs/次
Office 2013+:    AES-256 + SHA512, 100K 迭代  → 约 100,000 FLOPs/次
BitLocker:       AES-256 + SHA256, 高迭代     → 约 100,000 FLOPs/次

这意味着同一个 GPU,恢复 WPA2 密码的速度是恢复 Office 2013+ 密码的 60 倍以上

[阅读全文]