描述
点赞、收藏、浏览量等信息的存储位置取决于具体的业务需求和系统架构,但通常会结合数据库和缓存来进行设计。
常见的做法是:
初始时,将点赞、收藏、浏览量等信息存储在数据库中。
然后,将这些数据同步到缓存中,并在用户进行相关操作(如点赞、收藏)时,同时更新数据库和缓存。
这样可以在保证数据准确性的同时,提高系统的性能和响应速度。
改进
以下是一种可能更优的方案,考虑了数据一致性、并发处理和性能优化:
引入分布式锁:
在对点赞、收藏和浏览量进行操作时,获取分布式锁,以确保并发情况下数据的准确性。
异步更新数据库:
先更新缓存,然后将更新数据库的操作放入消息队列中异步处理,以提高响应速度。
缓存预热:
在系统启动或定期将热门文章的相关数据加载到缓存中,减少首次访问时的数据库查询。
点击查看代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class ArticleService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Autowiredprivate ArticleRepository articleRepository;@Autowiredprivate DistributedLockManager lockManager; // 假设使用分布式锁管理组件@Autowiredprivate MessageQueueProducer messageQueueProducer; // 消息队列生产者// 增加点赞数@Transactionalpublic void incrementLikes(Long articleId) {String lockKey = "article_likes_lock:" + articleId;try {// 获取分布式锁if (lockManager.acquireLock(lockKey)) {String likesKey = "article_likes:" + articleId;Long likesInCache = redisTemplate.opsForValue().increment(likesKey, 1);// 将更新数据库的操作放入消息队列异步处理messageQueueProducer.sendUpdateLikesMessage(articleId, likesInCache);}} finally {// 释放锁lockManager.releaseLock(lockKey);}}// 增加收藏数和浏览量的方法类似// 获取点赞数public Long getLikes(Long articleId) {String likesKey = "article_likes:" + articleId;Long likesInCache = redisTemplate.opsForValue().get(likesKey);if (likesInCache == null) {// 如果 Redis 中没有,从数据库中获取并设置到 Redis 中Long likesInDB = articleRepository.getLikes(articleId);if (likesInDB!= null) {redisTemplate.opsForValue().set(likesKey, likesInDB.toString());return likesInDB;}return 0L;} else {return Long.parseLong(likesInCache);}}// 类似地实现获取收藏数和浏览量的方法
}
核心部分: