这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
Redis实现点赞功能
为什么要使用redis进行点赞功能的开发?
直接写入Mysql是最简单的做法,点赞时查表查看用户是否对该视频点赞,若没点过,则将点赞记录插入到数据库,取消点赞时查看用户是否对该视频点赞,若点过,则将点赞记录从数据库中删除。
若以这种方式进行点赞与取消点赞功能的开发,对数据库压力极大,因为每次点赞或取消点赞时都会进行两次数据库操作,先查再插入或删除,导致数据库读写压力大,并且热门的文章会有很多用户点赞,或者短时间内有大量用户点赞,这样读写压力就更大。
而redis性能高,可以缓解数据库的读写压力。
如何使用redis完成点赞功能?
直接上代码:
myKey := key.KeyUserFavorite(userId) // 点赞key
isMember := global.RDB.SIsMember(myKey, videoId) // 判断是否点赞
if actionType == 1 && !isMember.Val() { // 点赞操作
global.RDB.SAdd(myKey, videoId)
//将点赞信息保存到数据库
like := model.Likes{
UserId: userId,
VideoId: videoId,
}
if err := global.DB.Create(&like).Error; err != nil {
zap.S().Error("create like err:", err.Error())
return nil, err
}
return &proto.DouyinFavoriteActionResponse{
StatusCode: 0,
StatusMsg: "点赞成功",
}, nil
} else if actionType == 2 && isMember.Val() { //取消点赞操作
global.RDB.SRem(myKey, videoId)
//将取消点赞信息保存到数据库
global.DB.Where("user_id = ? and video_id = ?", userId, videoId).Delete(&model.Likes{})
return &proto.DouyinFavoriteActionResponse{
StatusCode: 0,
StatusMsg: "取消点赞成功",
}, nil
}
其中actionType为1时是点赞操作,为2时是取消点赞操作。
代码分析: 使用redis的set集合完成此操作,将user_id作为Redis的key,通过redis判断是否进行点赞,再进行数据库的写入。
优化方向:若在用户量、点赞量非常大的场景下,我认为可以不用实时将redis中信息写入数据库,进行定期写入即可,可缓解数据库写操作压力。