1. 项目背景与需求分析烘焙坊电商系统的缓存模块和购物车功能是提升用户体验的关键组件。在高峰期我们的系统监测到商品详情页的QPS达到1200数据库负载经常超过75%这直接影响了用户浏览商品和下单的流畅度。同时未登录用户的购物车数据丢失问题导致30%的潜在客户流失。重要提示缓存设计必须考虑数据一致性和雪崩效应特别是在促销活动期间流量激增的场景下。2. 技术选型与架构设计2.1 缓存方案对比我们对比了三种主流方案本地缓存Caffeine访问速度最快1ms但集群环境下数据不一致Redis单机版读写性能约5万QPS存在单点故障风险Redis哨兵集群可用性达99.95%性能约8万QPS最终选择Redis哨兵集群方案主要考虑因素数据一致性要求购物车需要跨会话持久化容灾需求必须保证双十一期间服务可用性能指标预期峰值QPS 2万// 哨兵配置示例 Bean public RedisConnectionFactory redisConnectionFactory() { SentinelConfiguration config new SentinelConfiguration() .master(baking-master) .sentinel(sentinel1, 26379) .sentinel(sentinel2, 26380); return new JedisConnectionFactory(config); }2.2 购物车数据结构设计采用Hash结构存储购物车数据Key: cart:{userId}Field: 商品SKUValue: JSON格式包含{数量, 加入时间, 选中状态}HSET cart:10086 SKU1001 {quantity:2,selected:true,addTime:1659321000}3. 核心功能实现细节3.1 多级缓存实现构建本地缓存Redis的两级缓存体系本地缓存存储热点商品TTL 30秒Redis缓存全量商品数据TTL 5分钟public Product getProduct(Long id) { // 1. 查本地缓存 Product product localCache.get(id); if (product ! null) return product; // 2. 查Redis product redisTemplate.opsForValue().get(product:id); if (product ! null) { localCache.put(id, product); return product; } // 3. 查数据库 product dbQuery(id); redisTemplate.opsForValue().set(product:id, product, 5, MINUTES); return product; }3.2 购物车合并逻辑处理未登录→登录状态的购物车合并graph TD A[获取Cookie购物车] -- B{用户登录?} B --|否| C[仅操作Cookie] B --|是| D[合并Redis和Cookie数据] D -- E[去重处理] E -- F[数量叠加策略]实际开发中发现合并时要注意商品规格匹配不同规格的相同商品应视为不同项4. 性能优化实践4.1 缓存预热方案每日凌晨3点执行预热脚本查询未来24小时主推商品批量加载到Redis设置阶梯式TTL1-3小时随机#!/bin/bash # 预热TOP100商品 redis-cli --eval warmup.lua , 1004.2 热点Key检测通过Redis监控发现热点Key模式使用redis-cli --hotkeys识别对product:1234这类热点商品增加本地缓存比例采用缓存标记策略5. 异常处理与监控5.1 缓存击穿防护实现互斥锁方案public Product getProductWithLock(Long id) { String lockKey lock:product: id; try { Boolean locked redisTemplate.opsForValue() .setIfAbsent(lockKey, 1, 10, TimeUnit.SECONDS); if (locked) { Product product dbQuery(id); redisTemplate.opsForValue().set(product:id, product); return product; } Thread.sleep(50); return getProductWithLock(id); } finally { redisTemplate.delete(lockKey); } }5.2 监控指标配置Prometheus监控关键指标缓存命中率redis_keyspace_hits/redis_keyspace_misses购物车操作耗时histogram_quantile(0.95, rate(cart_api_duration_seconds_bucket[1m]))6. 踩坑实录缓存雪崩问题现象大量商品缓存同时失效导致DB压力飙升解决采用随机TTL基础值±20%浮动购物车并发修改现象商品数量出现负值解决改用Lua脚本保证原子性-- 购物车数量修改脚本 local key KEYS[1] local field ARGV[1] local delta tonumber(ARGV[2]) local current tonumber(redis.call(HGET, key, field)) or 0 local newVal math.max(0, current delta) redis.call(HSET, key, field, newVal) return newVal内存泄漏预警发现Redis内存每周增长5%原因未设置购物车数据过期时间修复对30天未更新的购物车设置TTL7. 扩展思考未来可引入RedisJSON模块处理复杂购物车数据结构考虑将购物车持久化到MySQL的归档表用于数据分析探索RedisGraph实现商品推荐功能我在实际部署中发现当Redis内存使用超过70%时响应时间会出现明显波动。建议设置内存警戒线为60%并配置自动告警规则。另外购物车合并逻辑中的规格匹配算法经过三次迭代最终采用商品ID规格ID的联合匹配方式准确率从82%提升到99.6%。
阅读完成 · 觉得有帮助?