Redis + Caffeine多级缓存电商场景深度解析

Redis + Caffeine多级缓存

  • Redis + Caffeine多级缓存电商场景深度解析
    • 一、实施目的
    • 二、具体实施
      • 2.1 架构设计
      • 2.2 组件配置
      • 2.3 核心代码实现
    • 三、实施效果
      • 3.1 性能指标对比
      • 3.2 业务指标改善
      • 3.3 系统稳定性
    • 四、关键策略
      • 4.1 缓存预热
      • 4.2 一致性保障
      • 4.3 监控配置
        • Prometheus监控指标
    • 电商多级缓存完整实现方案
      • 1. 基础配置
        • 1.1 Maven依赖
        • 1.2 配置文件
      • 2. 核心实现类
        • 2.1 缓存配置类
        • 2.2 商品服务实现
        • 2.3 库存服务实现
      • 3. 辅助组件
        • 3.1 缓存预热
        • 3.2 监控端点
      • 关键点说明
        • 1. 多级缓存流程
        • 2. 缓存策略
        • 3. 一致性保障
        • 4. 监控能力
        • 5. 性能优化

Redis + Caffeine多级缓存电商场景深度解析

一、实施目的

  1. 性能优化

    • 降低商品详情页访问延迟
    • 提升系统整体吞吐量
  2. 成本控制

    • 减少Redis集群规模
    • 降低数据库查询压力
  3. 稳定性保障

    • 应对秒杀等高并发场景
    • 实现故障自动降级

二、具体实施

2.1 架构设计

用户请求 → Nginx → 应用服务器(Caffeine) → Redis集群 → MySQL/分库分表

2.2 组件配置

Caffeine配置

spring.cache.caffeine.spec=maximumSize=50000,expireAfterWrite=60s,refreshAfterWrite=30s,recordStats

Redis集群配置

spring.redis.cluster.nodes=192.168.1.101:6379,192.168.1.102:6379
spring.redis.lettuce.pool.max-active=500
spring.redis.lettuce.pool.max-wait=2000

2.3 核心代码实现

商品查询服务

public ProductDetail getProductDetail(Long productId) {// 本地缓存查询ProductDetail detail = caffeineCache.get(productId, k -> {// Redis查询String redisKey = "pd:" + productId;ProductDetail value = redisTemplate.opsForValue().get(redisKey);if (value == null) {// 数据库查询value = productDao.findById(productId);// 异步写入Redisexecutor.execute(() -> {redisTemplate.opsForValue().set(redisKey, value,60 + ThreadLocalRandom.current().nextInt(30),TimeUnit.MINUTES);});}return value;});return detail;
}

库存扣减服务

public boolean deductStock(Long productId, int num) {// 本地库存标记if (!localStockMark.tryLock(productId)) {return false;}try {// Redis原子扣减Long remain = redisTemplate.execute(new DefaultRedisScript<>("local stock = tonumber(redis.call('GET', KEYS[1]))\n" +"if stock >= tonumber(ARGV[1]) then\n" +"    return redis.call('DECRBY', KEYS[1], ARGV[1])\n" +"else\n" +"    return -1\n" +"end",Long.class),Collections.singletonList("stock:" + productId),String.valueOf(num));if (remain >= 0) {// 异步记录库存变更mq.sendStockMessage(productId, num);return true;}return false;} finally {localStockMark.unlock(productId);}
}

三、实施效果

3.1 性能指标对比

指标单Redis架构多级缓存架构提升幅度
平均响应时间68ms9ms655%
峰值QPS12万85万608%
数据库查询量100%8%减少92%

3.2 业务指标改善

  1. 秒杀场景

    • 下单成功率从35%提升至89%
    • 超卖问题完全杜绝
  2. 常规场景

    • 商品详情页加载时间从1.2s→180ms
    • 服务器成本降低40%

3.3 系统稳定性

  1. Redis故障时:

    • 核心商品仍可提供服务
    • 系统存活时间从<1分钟延长至30分钟
  2. 大促期间:

    • 流量波动减少70%
    • CPU负载降低55%

四、关键策略

4.1 缓存预热

@Scheduled(cron = "0 0 3 * * ?")
public void dailyPreheat() {List<Long> hotItems = hotProductService.predictHotItems();hotItems.parallelStream().forEach(id -> {ProductDetail detail = productDao.getDetail(id);caffeineCache.put(id, detail);redisTemplate.opsForValue().set("pd:" + id,detail,6, TimeUnit.HOURS);});
}

4.2 一致性保障

@Transactional
public void updateProduct(Product product) {// 1.删除缓存caffeineCache.invalidate(product.getId());redisTemplate.delete("pd:" + product.getId());// 2.更新数据库productDao.update(product);// 3.延迟双删executor.schedule(() -> {redisTemplate.delete("pd:" + product.getId());}, 1, TimeUnit.SECONDS);
}

4.3 监控配置

Prometheus监控指标
 name: cache_hit_rateexpr: rate(caffeine_cache_hits_total[5m]) / (rate(caffeine_cache_hits_total[5m]) +  rate(caffeine_cache_misses_total[5m]))name: redis_latencyexpr: histogram_quantile(0.99, rate(redis_command_duration_seconds_bucket[1m]))

电商多级缓存完整实现方案

1. 基础配置

1.1 Maven依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>3.1.8</version></dependency>
</dependencies>
1.2 配置文件
spring:redis:host: 127.0.0.1port: 6379password: yourpasswordlettuce:pool:max-active: 16max-wait: 1000msmax-idle: 8caffeine:specs:productCache: maximumSize=10000,expireAfterWrite=60s,recordStatsstockCache: maximumSize=5000,expireAfterWrite=10s

2. 核心实现类

2.1 缓存配置类
@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic CacheManager cacheManager() {CaffeineCacheManager cacheManager = new CaffeineCacheManager();cacheManager.registerCustomCache("products", Caffeine.from(caffeineProperties().getSpec("productCache")).build());cacheManager.registerCustomCache("stocks",Caffeine.from(caffeineProperties().getSpec("stockCache")).build());return cacheManager;}@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new GenericJackson2JsonRedisSerializer());return template;}
}
2.2 商品服务实现
@Service
public class ProductServiceImpl implements ProductService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Cacheable(cacheNames = "products", key = "#productId")@Overridepublic ProductDetail getProductDetail(Long productId) {String redisKey = "product:" + productId;ProductDetail detail = (ProductDetail) redisTemplate.opsForValue().get(redisKey);if (detail == null) {detail = loadFromDB(productId);redisTemplate.opsForValue().set(redisKey, detail,60 + ThreadLocalRandom.current().nextInt(30),TimeUnit.MINUTES);}return detail;}private ProductDetail loadFromDB(Long productId) {// 数据库查询实现return productRepository.findById(productId);}
}
2.3 库存服务实现
@Service
public class StockServiceImpl implements StockService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Cacheable(cacheNames = "stocks", key = "#productId")@Overridepublic Integer getStock(Long productId) {String redisKey = "stock:" + productId;Integer stock = (Integer) redisTemplate.opsForValue().get(redisKey);if (stock == null) {stock = loadStockFromDB(productId);redisTemplate.opsForValue().set(redisKey,stock,10, TimeUnit.SECONDS);}return stock;}@CacheEvict(cacheNames = "stocks", key = "#productId")@Overridepublic boolean deductStock(Long productId, int quantity) {// 库存扣减逻辑return stockRepository.deductStock(productId, quantity);}
}

3. 辅助组件

3.1 缓存预热
@Component
public class CacheWarmUp implements CommandLineRunner {@Autowiredprivate ProductService productService;@Overridepublic void run(String... args) {List<Long> hotProducts = Arrays.asList(1001L, 1002L, 1003L);hotProducts.parallelStream().forEach(productService::getProductDetail);}
}
3.2 监控端点
@RestController
@RequestMapping("/cache")
public class CacheMonitorController {@Autowiredprivate CacheManager cacheManager;@GetMapping("/stats")public Map<String, Object> getCacheStats() {Map<String, Object> stats = new HashMap<>();CaffeineCache productsCache = (CaffeineCache) cacheManager.getCache("products");if (productsCache != null) {stats.put("products", productsCache.getNativeCache().stats());}return stats;}
}

关键点说明

1. 多级缓存流程
  1. 先查Caffeine本地缓存
  2. 未命中则查Redis
  3. 仍未命中则查数据库
  4. 回填各级缓存
2. 缓存策略
数据类型本地缓存TTLRedis TTL
商品数据60秒30-90分钟(随机)
库存数据10秒10秒
3. 一致性保障
  1. 使用@CacheEvict保证更新时缓存失效
  2. 库存采用短过期时间自动刷新
4. 监控能力
  1. 通过/cache/stats端点暴露缓存命中率
  2. 集成Spring Boot Actuator
5. 性能优化
  1. 并行预热热点数据
  2. Redis连接池配置
  3. 本地缓存大小控制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/75328.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端开发3D-基于three.js

基于 three.js 渲染任何画面&#xff0c;都要基于这 3 个要素来实现 1场景scene&#xff1a;放置物体的容器 2摄像机&#xff1a;类似人眼&#xff0c;可调整位置&#xff0c;角度等信息&#xff0c;展示不同画面 3渲染器&#xff1a;接收场景和摄像机对象&#xff0c;计算在浏…

代码随想录算法训练营--打卡day4

一.移除链表元素 1.题目链接 203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 2.思路 通过 while 循环来遍历链表&#xff0c;只要 cur 的下一个节点不为空&#xff0c;就继续循环。在循环中&#xff0c;对 cur 的下一个节点的值进行判断&#xff1a; 值不等于…

虚拟电厂:多元能源聚合,开启绿色电力新时代

虚拟电厂&#xff1a;多元能源聚合&#xff0c;开启绿色电力新时代 在“双碳”目标驱动下&#xff0c;电力系统正经历从集中式向分布式、从单一能源向多能互补的深刻变革。 作为能源互联网的核心载体&#xff0c;虚拟电厂通过数字化技术整合多种能源资源&#xff0c;而是像指…

高通Android10 铃声通话音频80%音量修改

先修改最高的音量step --- a/SC60_AP/frameworks/base/services/core/java/com/android/server/audio/AudioService.javab/SC60_AP/frameworks/base/services/core/java/com/android/server/audio/AudioService.java-311,14 311,14 public class AudioService extends IAudio…

类加载过程?类隔离了解过吗?

类加载过程详解 类加载是 JVM 将类的字节码从磁盘、网络或其他来源加载到内存&#xff0c;并转换为 Class 对象的过程&#xff0c;主要分为以下 五个阶段&#xff1a; 1. 加载&#xff08;Loading&#xff09; 任务&#xff1a;查找类的二进制字节流&#xff08;如 .class 文…

使用msmtp和mutt在CentOS上发送指定目录下的所有文件作为邮件附件

1.安装 msmtp&#xff1a; 如果尚未安装&#xff0c;请先通过以下命令安装msmtp。 sudo yum install msmtp 2.配置 msmtp 使用新浪邮箱&#xff1a; 创建或编辑配置文件~/.msmtprc&#xff0c;输入以下内容&#xff08;记得替换授权码&#xff09;。 defaults tls on tls_st…

Vue+Elementui首页看板

源码 <template><!-- 查询条件--><div class="optimize-norm" v-loading="selectDataLoading"><el-form :model="queryParams" ref="queryRef" style="padding-bottom:8px" :inline="true"…

汇编学习之《指针寄存器大小端学习》

什么是指针寄存器&#xff1f; 操作栈的寄存器 栈&#xff1a; 保存函数里面传递的参数&#xff0c;局部变量等。 EBP&#xff1a; 指向栈底的指针 ESP&#xff1a; 指向栈顶的指针。 计算入栈地址变化规则 通过OllDbg查看 有可能点击安装的时候栈区域第一次查看会没有显…

Oracle数据库数据编程SQL<3.7 PL/SQL 触发器(Trigger)>

触发器是Oracle数据库中的一种特殊存储过程&#xff0c;它会在特定数据库事件发生时自动执行。触发器通常用于实现复杂的业务规则、数据验证、审计跟踪等功能。 目录 一、触发器基本概念 1. 触发器特点 2. 触发器组成要素 二、触发器类型 1. DML触发器 2. DDL触发器 3.…

2025年渗透测试面试题总结-某 携程旅游-基础安全工程师(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 携程旅游-基础安全工程师 反序列化原理 核心原理 扩展分析 SQL注入本质 核心原理 扩展分析 SQL注…

CSS 边框(Border)样式详解

CSS 边框&#xff08;Border&#xff09;样式详解 CSS 提供了多种边框样式&#xff0c;使我们能够控制元素的外观。本文将详细介绍 CSS 边框的各种属性及应用示例。 1. 基本边框属性 CSS 主要使用 border 相关属性定义边框&#xff0c;基本语法如下&#xff1a; border: [边…

SpringCould微服务架构之Docker(6)

容器的基本命令&#xff1a; 1. docker exec &#xff1a;进入容器执行命令 2. docker logs: -f 持续查看容器的运行日志 3. docker ps&#xff1a;查看所有运行的容器和状态 案例&#xff1a;创建运行一个容Nginx容器 docker run--name myNginx -p 80:80 -d nginx 命…

unity3d端监听 uri scheme

一、消息监听 1.创建一个脚本命名为 “URISchemeListener” &#xff0c;用于接收URI消息&#xff08;代码如下&#xff09;。 using System; using System.Runtime.InteropServices; using UnityEngine; using UnityEngine.UI;public class URISchemeListener : MonoBehavio…

网络信息安全应急演练方案

信息安全应急演练方案 总则 &#xff08;一&#xff09;编制目的 旨在建立并完善应对病毒入侵、Webshell 攻击以及未授权访问等信息安全突发事件的应急机制&#xff0c;提升组织对这类事件的快速响应、协同处理和恢复能力&#xff0c;最大程度降低事件对业务运营、数据安全和…

电商场景下高稳定性数据接口的选型与实践

在电商系统开发中&#xff0c;API接口需要应对高并发请求、动态数据更新和复杂业务场景。我将重点解析电商场景对数据接口的特殊需求及选型方案。 一、电商API必备的四大核心能力 千万级商品数据实时同步 支持SKU基础信息/价格/库存多维度更新每日增量数据抓取与历史版本对比…

Android R adb remount 调用流程

目的&#xff1a;调查adb remount 与adb shell进去后执行remount的差异 调试方法&#xff1a;添加log编译adbd,替换system\apex\com.android.adbd\bin\adbd 一、调查adb remount实现 关键代码&#xff1a;system\core\adb\daemon\services.cpp unique_fd daemon_service_to…

多模态大语言模型arxiv论文略读(二)

Identifying the Correlation Between Language Distance and Cross-Lingual Transfer in a Multilingual Representation Space ➡️ 论文标题&#xff1a;Identifying the Correlation Between Language Distance and Cross-Lingual Transfer in a Multilingual Representat…

【运维】负载均衡

老规矩&#xff0c;先占坑&#xff0c;后续更新。 开头先理解一下所谓的“均衡”&#xff0c;不能狭义地理解为分配给所有实际服务器一样多的工作量&#xff0c;因为多台服务器的承载能力各不相同&#xff0c;这可能体现在硬件配置、网络带宽的差异&#xff0c;也可能因为某台…

大型语言模型Claude的“思维模式”最近被公开解剖

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Ubuntu环境安装

1. 安装gcc、g和make sudo apt update sudo apt install build-essential 2. 安装cmake ubuntu安装cmake的三种方法&#xff08;超方便&#xff01;&#xff09;-CSDN博客 3. 安装ssh sudo apt-get install libssl-dev