首页实时更新,人气最高的十个商品。
思路:
由于在首页,排行榜访问量比较大,避免重复、频繁的从数据库查询同一商品,利用缓存 redis 保存信息。
利用 redis 的 zSet 做排行榜,根据商品人气给商品排名。
- 从 mysql 拉取数据,通过 sql 语句条件查询出人气最高的十个商品。(sql 代码参考)
SELECT cp.id, count( cbr.consumer_product_id ) as bidCount FROM consumer_product cp, consumer_bid_record cbr WHERE cp.id = cbr.consumer_product_id AND cp.state = 1 AND cp.bid_state = 2 GROUP BY cp.id ORDER BY count( cbr.consumer_product_id ) DESC Limit 0,9
2.存入 redis,zSet 有序集合。作为人气排行榜。并给 zset 设置过期时间,保证数据一致性。
redisTemplate.opsForZSet().add(Constants.BIG_PRICE_PRODUCT_RANKE, hotProductRankDto.getId() + "",hotProductRankDto.getBidCount()); //设置五分钟过期一次 redisTemplate.expire(Constants.BIG_PRICE_PRODUCT_RANKE , 5 ,TimeUnit.MINUTES);
3.取出 redis zSet 集合根据人气排序后的结果,根据商品 id 从数据源查出商品信息并保存到 redis,设置过期时间
//redis中取出 出价排行榜 前十的商品 Set<String> hotProduct = redisTemplate.opsForZSet().reverseRange(Constants.BIG_PRICE_PRODUCT_RANKE, 0, 9);
4.根据实际场景,给 zSet
编写自增逻辑。并做好数据一致性。比如更新商品信息是,删除 redis 中排行榜、商品缓存信息。
/** * 在redis 有序set 中 商品id增加一 并且更新缓存中hotProduct当前价格 */ public Double bidPriceToRank(Integer productId){ //给排行榜中该字段 自增1 Double score = redisTemplate.opsForZSet().incrementScore(Constants.BIG_PRICE_PRODUCT_RANKE, productId + "", 1); // 删掉 hotProduct 缓存,case: 更新当前价 redisTemplate.delete(Constants.HOT_PRODUCT_ID + productId); return score; }
/** * 拍卖结束时,删掉redis热排榜中该商品排名 * @param productId */ private void delBigPriceProductRankeByKey(Integer productId){ redisTemplate.opsForZSet().remove(Constants.BIG_PRICE_PRODUCT_RANKE,productId); }
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于