描述
点赞、收藏、浏览量等信息的存储位置取决于具体的业务需求和系统架构,但通常会结合数据库和缓存来进行设计。
常见的做法是:
初始时,将点赞、收藏、浏览量等信息存储在数据库中。
然后,将这些数据同步到缓存中,并在用户进行相关操作(如点赞、收藏)时,同时更新数据库和缓存。
这样可以在保证数据准确性的同时,提高系统的性能和响应速度。
改进
以下是一种可能更优的方案,考虑了数据一致性、并发处理和性能优化:
引入分布式锁:
在对点赞、收藏和浏览量进行操作时,获取分布式锁,以确保并发情况下数据的准确性。
异步更新数据库:
先更新缓存,然后将更新数据库的操作放入消息队列中异步处理,以提高响应速度。
缓存预热:
在系统启动或定期将热门文章的相关数据加载到缓存中,减少首次访问时的数据库查询。
点击查看代码
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 {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private ArticleRepository articleRepository;
@Autowired
private DistributedLockManager lockManager; // 假设使用分布式锁管理组件
@Autowired
private MessageQueueProducer messageQueueProducer; // 消息队列生产者
// 增加点赞数
@Transactional
public 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);
}
}
// 类似地实现获取收藏数和浏览量的方法
}
核心部分: