MST

星途 面试题库

面试题:微服务架构中Spring Cloud分布式系统的缓存策略与性能优化

在Spring Cloud构建的微服务分布式系统里,为提升性能常使用缓存。请详细说明如何选择合适的缓存策略(如本地缓存、分布式缓存),并以实际业务场景为例,设计一个缓存方案,同时阐述缓存更新和一致性问题该如何解决。
28.8万 热度难度
后端开发微服务架构

知识考点

AI 面试

面试题答案

一键面试

缓存策略选择

  1. 本地缓存
    • 适用场景:适用于单机应用或对缓存数据一致性要求不高的场景。例如,在一个小型的单服务器Web应用中,应用内的某些配置信息很少变动,使用本地缓存可以减少对外部存储的访问,提高响应速度。
    • 优点:访问速度极快,因为数据存储在应用进程内,无需网络开销。
    • 缺点:数据共享困难,多实例环境下难以保证缓存一致性;缓存容量受限于应用服务器内存大小。
  2. 分布式缓存
    • 适用场景:在微服务分布式系统中广泛适用,尤其是多实例、跨节点的应用场景。比如电商系统中,商品的基本信息、库存等数据,多个微服务可能会频繁读取,适合使用分布式缓存。
    • 优点:可扩展性强,能通过增加节点来扩展缓存容量;支持多实例共享缓存数据,保证数据一致性。
    • 缺点:存在网络开销,相比本地缓存,访问速度略慢;需要额外的维护和管理,如集群配置等。

实际业务场景缓存方案设计 - 以电商商品详情为例

  1. 缓存策略选择:选择分布式缓存,如Redis。电商系统通常是分布式架构,多个微服务(如商品展示微服务、订单微服务等)可能需要读取商品详情数据,分布式缓存能满足多实例共享数据的需求。
  2. 缓存数据结构设计:使用Redis的哈希(Hash)结构存储商品详情。例如,以商品ID作为Key,商品的各个属性(如名称、价格、描述等)作为Hash的Field和Value。
    // 示例代码(Java + Jedis)
    Jedis jedis = new Jedis("localhost", 6379);
    String productId = "12345";
    jedis.hset("product:" + productId, "name", "Sample Product");
    jedis.hset("product:" + productId, "price", "19.99");
    // 读取商品名称
    String productName = jedis.hget("product:" + productId, "name");
    
  3. 缓存过期策略:为商品详情设置合理的过期时间,如24小时。可以在添加缓存时设置过期时间。
    jedis.setex("product:" + productId, 24 * 60 * 60, productDetailsJson);
    

缓存更新和一致性问题解决

  1. 缓存更新策略
    • 读写穿透:写操作时,先更新数据库,再更新缓存。读操作时,先查询缓存,若缓存不存在则查询数据库,并将结果写入缓存。
    • 异步更新:写操作更新数据库后,通过消息队列异步更新缓存。这样可以避免写操作时直接更新缓存带来的性能问题,但要注意消息队列的可靠性。
  2. 缓存一致性问题解决
    • 缓存版本号:为缓存数据设置版本号,每次数据更新时,版本号加1。读取数据时,不仅读取数据本身,还读取版本号,若发现版本号不一致则重新从数据库加载数据。
    • 分布式锁:在更新缓存时,使用分布式锁(如Redis的SETNX命令实现简单的分布式锁),确保同一时间只有一个实例可以更新缓存,避免并发更新导致的数据不一致问题。但要注意锁的粒度和锁的释放,防止死锁。