广告:Codex Token 低价中转站稳定接口 · 快速接入 · 开发者备用通道
Engineering article

技术负责人 | 缓存架构 | 面试高频

缓存架构是技术负责人面试中最高频的考点之一,掌握它能让你在技术面试中脱颖而出。2024年至今,缓存设计已经从单纯的内存存储演变为多级缓存协同、分布式一致性、热点数据回收等复杂问题。我见过不少候选人只会背 Redis 的基本命令,却对缓存穿透、雪崩、击穿等场景的处理方案一知半解。真正的缓存架构设计需要你理解业务场景、数据模型和系统负载的关系

技术负责人 | 缓存架构 | 面试高频
配图来源于网络和AI生成,仅供参考。
▌ 技术引导
缓存架构是技术负责人面试中最高频的考点之一,掌握它能让你在技术面试中脱颖而出。2024年至今,缓存设计已经从单纯的内存存储演变为多级缓存协同、分布式一致性、热点数据回收等复杂问题。我见过不少候选人只会背 Redis 的基本命令,却对缓存穿透、雪崩、击穿等场景的处理方案一知半解。真正的缓存架构设计需要你理解业务场景、数据模型和系统负载的关系。缓存命中率直接影响请求延迟和服务器压力,在实际业务中,命中率越高,系统稳定性越强。我做过一个高并发电商项目,缓存穿透导致秒级请求延迟飙升,后来通过布隆过滤器和 Redis 的 TTL 配合,才把问题稳住。如果你在面试中能说出 Redis 的淘汰策略、本地缓存的实现方式、多级缓存的层级划分,那你就赢了。别只背概念,要能举例子,能说配置,能讲性能数据。

▌ 技术参考


缓存架构的核心在于数据一致性、性能和可用性之间的平衡。在2024-2026年的实际项目中,90%以上的缓存问题都源于缓存穿透或缓存失效策略不完善。比如,在Java中使用Caffeine实现本地缓存时,配置项`maximumSize(10000)`和`expireAfterWrite(Duration.ofMinutes(5))`是基本的,但高级用法例如`refreshAfterWrite`和`weakKeys`却很少人能说清。设置`refreshAfterWrite`时,必须确保缓存更新的逻辑不会因为缓存重建导致服务短暂不可用。比如,用`@Cacheable`注解时,配合`@CachePut`确保缓存的更新同步,否则缓存数据会滞后于数据库。


在分布式系统中,Redis 是最常见的缓存中间件,但它的局限性显而易见。2026年不少团队开始采用多级缓存方案,比如本地缓存+Redis+CDN。本地缓存由于作用域局限,容易导致脏数据,但它的读写性能远高于 Redis。Caffeine 是一个高性能的 Java 本地缓存库,适合处理频繁读取的小数据。用 Caffeine 时,建议设置`maximumSize(100000)`和`expireAfterWrite(60, TimeUnit.MINUTES)`,并结合`CacheLoader`实现懒加载。当 Redis 集群扩容时,记得用`redis-cli --cluster reshard`命令重新分配槽位,否则会有数据倾斜的风险。


缓存穿透的处理方式有多种,最常用的是布隆过滤器。在2025年,我做过的高并发支付系统,布隆过滤器是用 Java 的 Guava 库实现的,配置时需要指定`expectedInsertions`和`falsePositiveProbability`。比如,`BloomFilter.create(HashFunction.murmur128(), 1000000, 0.01)`,这个参数设置得当可以将误判率控制在1%以内。但布隆过滤器也有缺点,比如不能删除数据,所以需要配合 Redis 的`TTL`机制,比如`set key value ex 300`,让缓存数据在一定时间后自动过期。如果发现频繁的穿透请求,建议监控 Redis 的`keyspace`,分析未命中键的分布,从而优化过滤器的参数。


缓存雪崩问题通常出现在 Redis 集群大量键同时过期时,会导致瞬间请求被打垮。为解决这个问题,应该在 Redis 的`TTL`设置上做文章。比如,`set key value ex 3600`设置为固定过期时间,但实际中更推荐使用`expireAt()`方法,将过期时间随机化,比如`set key value exat 1699245600`,这样能避免大量键在同一时间失效。此外,可以结合本地缓存,在 Redis 失效前预加载部分数据到本地,比如用`Caffeine.newBuilder().maximumSize(100000).build()`,再通过异步线程定期同步到 Redis。雪崩问题还可能出现在分布式集群中,这时候需要使用 Redis 的`cluster`模式,并确保所有节点的过期策略一致。


缓存击穿是指某个热点数据在缓存失效后,大量请求直接打到数据库导致性能骤降。解决这个问题的常见方法是使用互斥锁(Mutex Lock)。在 Java 中,可以用`Redisson.getLock("lock:hotkey")`来实现分布式锁,具体操作是:当缓存失效时,先尝试加锁,如果成功则去数据库加载,并更新缓存,如果失败则等待锁释放。实际代码中,需要设置锁的过期时间,比如`lock.expire(10, TimeUnit.SECONDS)`,避免死锁。此外,可以结合 Redis 的`setnx`命令,在热点数据失效时,用`set key value nx ex 300`来实现单机锁。不过,这种方案在多节点环境下效果不佳,必须用分布式锁。


Redis 的淘汰策略是面试中必须掌握的点之一。2024年后的 Redis 版本支持`volatile-lru`、`volatile-lfu`、`volatile-random`和`volatile-ttl`四种策略。在实际业务中,`volatile-lfu`和`volatile-ttl`的组合使用效果最好。比如,用`maxmemory-policy volatile-lfu`和`maxmemory 10gb`的配置,可以优先淘汰使用频率低的数据。但要注意,LFU 策略在某些场景下会带来内存浪费,比如冷热数据切换频繁时。我曾在一个推荐系统中遇到 LFU 导致内存占用过高,最终改用`volatile-lru`并配合`maxmemory-samples 10`,让系统更稳定地处理内存压力。


Redis 的集群模式在2025年后逐渐成为主流,尤其是在大规模数据场景下。集群分片的配置可以通过`redis-cli --cluster create`命令完成,例如:`redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 --cluster-replicas 1`。这个命令会创建一个包含三个节点的集群,并设置每个主节点一个副本。集群模式下,数据会自动分片,但必须确保每个节点的配置一致,比如`cluster-enabled yes`和`cluster-node-timeout 5000`。当集群节点宕机时,使用`redis-cli --cluster check`来检查节点状态,并通过`redis-cli --cluster rebalance`手动触发数据再平衡,避免数据不均衡。


本地缓存的使用要根据业务场景灵活选择。Caffeine 是首选,因为它在2025年后的 Java 生态中性能最优。例如,使用`Caffeine.newBuilder().maximumSize(10000).expireAfterWrite(5, TimeUnit.MINUTES)`来配置本地缓存,再结合`CacheLoader`实现数据加载。如果业务需要并发读写,可以使用`@Cacheable`配合`@CachePut`,让缓存自动更新。但本地缓存也有弊端,比如数据不一致,所以必须确保业务逻辑的幂等性。例如,在支付完成后,用`@CachePut`更新缓存,避免多次写入。


缓存与数据库的同步策略是缓存架构中的关键点。在2026年的项目中,我们采用的是“写穿透+异步更新”的方案。具体做法是:当业务写入数据库后,用消息队列(如 Kafka)触发缓存更新。例如,用`kafka-console-producer.sh`发送消息:`echo "key1,value1" | kafka-console-producer.sh --broker-list localhost:9092 --topic update-cache`。然后在消费者中,用`Caffeine.get`读取缓存,如果不存在则去 Redis 取,如果存在则直接返回。这种方案能减少数据库压力,但要注意消息的延迟和可靠性,比如通过`acks=all`来确保消息被所有副本确认。


在多级缓存设计中,CDN 缓存是最外层,适合静态资源。例如,使用 Nginx 配置 CDN 缓存:`proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_stale=on`。这个配置允许 Nginx 缓存静态资源,并在后端服务不可用时返回缓存内容。但要注意,CDN 缓存的更新策略必须与后端缓存同步,否则可能出现数据过时。我见过一个视频网站,CDN 缓存更新延迟10秒,导致用户看到过期视频,最终通过设置`proxy_cache_lock on`和`proxy_cache_lock_timeout 5s`进行优化,确保缓存同步。

十一
Redis 的持久化策略在面试中经常被问到。2024年后,`RDB`和`AOF`两种方式依然是主流。RDB 是快照方式,适合备份,但可能会丢数据;AOF 是日志方式,保证数据安全,但性能略低。实际配置中,推荐使用`appendonly yes`和`auto-aof-rewrite-percentage 100`,让 Redis 自动进行 AOF 持久化。如果需要高可用,可以使用 Redis 的 Sentinel 模式,或者直接部署为集群。在 Sentinel 模式中,`sentinel monitor mymaster 127.0.0.1 6379 2`是关键配置,确保主从切换时服务不中断。

十二
缓存监控是缓存架构中容易被忽视但极其重要的部分。使用 Prometheus + Grafana 可以实时监控 Redis 的命中率、内存使用、连接数等指标。例如,在 Redis 中开启`config set monitor 1`,然后通过`redis-cli monitor`获取所有操作日志,再用脚本分析。不过,`monitor`命令会影响性能,所以建议在测试环境使用。实际生产中,可以使用`INFO memory`查看内存使用情况,`INFO stats`查看命中率和请求量。如果发现命中率低于80%,就要考虑是否需要增加缓存热点数据。

十三
Redis 的内存管理是技术负责人面试中必须提到的点。2026年后的 Redis 更强调使用`maxmemory-policy`来控制内存占用,比如`allkeys-lru`、`volatile-lru`和`allkeys-random`。在实际部署中,建议将`maxmemory`设为服务器内存的70%左右,保留部分内存给操作系统和其他服务。例如,在`redis.conf`中设置`maxmemory 10gb`和`maxmemory-policy allkeys-lru`。同时,`maxmemory-samples 10`可以提升内存回收的准确性。另外,使用`RedisTemplate`时,配置`RedisCacheManager`并设置`maxEntriesLocalCache(-1)`可以优化本地缓存的内存使用。

十四
在分布式缓存场景中,使用 Redis 的`cluster`模式时,要注意节点的负载均衡。2025年后的 Redis 集群会自动分配槽位,但如果你需要手动调整,可以用`redis-cli --cluster rebalance`命令进行再平衡。例如,执行`redis-cli --cluster rebalance 127.0.0.1:6379`可以触发集群重新分配数据。此外,`redis-cli --cluster check`能帮助你发现节点状态是否正常。如果某个节点出现延迟,可以通过`redis-cli --cluster failover`手动触发主从切换,避免服务中断。

十五
Redis 的高可用方案中,Sentinel 和 Cluster 是最常问的。Sentinel 更适合小规模部署,而 Cluster 更适合大规模。Sentinel 的配置可以通过`sentinel monitor mymaster 127.0.0.1 6379 2`实现,其中第三个参数是投票数。生产环境中,建议将 Sentinel 节点部署在不同的服务器上,提升容灾能力。Cluster 配置则需要通过`redis-cli --cluster create`生成,例如:`redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 --cluster-replicas 1`。配置完成后,确保每个节点的`cluster-enabled yes`和`cluster-node-timeout`设置合理,避免节点频繁失联。

十六
在2026年的实际项目中,我们发现 Redis 的内存占用过高,导致频繁扩容。解决这个问题的关键是使用`eviction`策略,并结合`info memory`分析内存使用情况。例如,在 Redis 中设置`maxmemory 10gb`和`maxmemory-policy volatile-lru`,同时开启`lazyfree-lazy-eviction yes`和`lazyfree-lazy-expire yes`,让 Redis 在内存回收时更高效。如果发现内存回收不及时,可以通过`config set maxmemory 20gb`临时扩容,但长期解决方案还是得优化数据模型,比如减少不必要的字符串类型,改用哈希或集合。

十七
缓存架构的落地需要结合具体业务场景,比如电商、金融、社交等。在电商系统中,商品详情和用户购物车数据适合本地缓存,而订单状态和支付结果适合 Redis 缓存。在2025年的项目中,我们采用 Redis + Caffeine 的双层缓存策略,用`@Cacheable`和`@CachePut`确保数据同步。同时,结合`Guava`的布隆过滤器防止穿透。在部署时,Redis 集群使用`redis-cli --cluster check`确保各节点状态一致,并通过`redis-cli --cluster rebalance`平衡负载。这种方案在高并发场景下表现稳定,但需要大量监控和调优。

十八
缓存架构的设计还涉及一致性与性能的取舍。在2026年,我遇到一个支付系统,缓存一致性要求极高,所以放弃了 Redis 的异步更新,转而使用同步更新。例如,在数据库事务完成后,立即使用`redis-cli set key value ex 300`更新缓存,但这样会增加数据库压力。最终,我们通过引入异步消息队列(如 Kafka)来解耦,同时设置`maxmemory-policy volatile-ttl`确保缓存数据不会堆积。这种方式在金融系统中被广泛采用,但必须配合幂等校验,防止重复更新或数据不一致。