首页实时更新,人气最高的十个商品。
思路:
由于在首页,排行榜访问量比较大,避免重复、频繁的从数据库查询同一商品,利用缓存 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);
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于