这是我参与「第三届青训营 -后端场」笔记创作活动的第一篇笔记
1、 为什么要用redis做中间件实现点赞?
点赞属于高频操作,如果直接对数据库进行修改,大量用户线程会给mysql带来很大的压力。
2、如何实现?
思路一:用一个hash表来记录点赞操作
对于每个用户,创建一个user_id的hash,其中key-value分别为video_id和action_type
为了能统一管理,可以再创建一个all_user的hash/set来保存每一个user_id
因为需要查询用户点赞过的所有视频,所以用user_id做key而不是video_id
问题一:视频需要获取到具体的点赞数
解决一:无视它,用户虽然不能获取准确实时的数据,但是也能获取到大概。当然,对点赞数少的视频不友好
解决二:为每个视频维护一个video_id的set,查询点赞数时,加上set的数量就行。 既然都到了这一步,那同样也用一个all_video的hash/set来统一管理
好处:每次insert/delete一条点赞记录都需要对对应的点赞数+1/-1,当然也可以创建一个数组,每次 +1/-1先记录在数组里,最后再update。而每个video_id的set其实已经统计好了update的数目
坏处:如果有一条insert/delete失败了,那按set里面的数目更新可能就会有偏差
解决三:为每个视频维护一个set,但仅做查询,真正的update还是看insert成功了多少
问题二:redis写回mysql时,如何处理新的信息
解决:可以新建一个hash,让后续的操作指向新的hash。
可以保存两个值,一个是old_hash_name,一个是new_hash_name
写回时,创建一个新的hash,将key赋值给new_hash_name,
并将 new_hash_name赋值给 old_hash_name
问题三:写回时出现错误怎么处理
解决:对于这里的批量insert,事务貌似没有什么作用了。可以开启一个跳过默认事务的会话(可以考虑多线程插入)来进行插入(gorm的session方法)。对于错误的sql语句,保存到日志文件。