关于点赞模块在高并发下的优化处理,求方案

2020-08-11 14:57:26 +08:00
 totoro52

目前我涉及到做点赞这块,起初的设计是直接落库,用户的点赞和取消点赞直接对记录进行加减,这样的方案似乎很简单看起来也没啥问题,但是一旦流量多了起来,数据库肯定扛不住这么频繁的读写。

我参考了一些网上教程,基本都是采用 redis 异步入库,就是点赞和取消都交给 redis,redis 记录了点赞人和被点赞人,同时在另外记录点赞总数,然后通过定时任务进行异步落库并删除 redis 中的指定数据。

但是现在新的问题来了,当我要查询某个文章的点赞总数的时候,怎么保证数据的一致性呢,岂不是查询的总数的时候需要 mysql+redis = 总数才能保证唯一性,因为 redis 入库后记录就被删除了,防止内存庞大,而且 redis 并不会做持久化,麻烦做过这方面的大牛给我指点指点

8423 次点击
所在节点    Redis
29 条回复
IMCA1024
2020-08-11 15:02:14 +08:00
非要实时的点赞数据吗,有特殊需求?
totoro52
2020-08-11 15:03:58 +08:00
有的,点赞在前台展示是需要保证实时的
fdingiit
2020-08-11 15:05:16 +08:00
为什么要删 redis 数据?
Veneris
2020-08-11 15:06:10 +08:00
totoro52
2020-08-11 15:06:12 +08:00
@IMCA1024 我的考虑是不实时,然后异步入库的定时时间设置短点,比如 5 分钟,但是这样的解决方案不满足需求。
palmers
2020-08-11 15:07:31 +08:00
是不是可以通过期策略 来解决部分问题?
totoro52
2020-08-11 15:07:38 +08:00
@fdingiit 防止内存庞大
luckyrayyy
2020-08-11 15:15:14 +08:00
超大并发下查询准确实时的点赞数量,本身不就是个伪需求嘛...谁会关心这个?
yuzo555
2020-08-11 15:20:06 +08:00
Redis 设置过期时间,根据周期使用不同的 Redis 键名,比如周期一天,文章 ID 是 123,那么点赞键名比如说是 like_123_20200811 (计数),like_123_20200811_user ( list,记录用户)。

第一次创建时(用 incr 增加计数键,判断返回值即可知道是否为第一次)设置一个 25 小时的过期时间。

定时比如每天 0:30 统计昨天的数量,加到数据库。
yuzo555
2020-08-11 15:21:26 +08:00
如果更短的周期可以用时间戳除以周期秒数取整来代替日期
ericgui
2020-08-11 15:22:54 +08:00
@luckyrayyy 其实这些都可以解决的,但就看你花费多大的成本。

比如,超大并发下查询交易金额(双十一),这绝地的刚需,必须保证数据准确,对吧
但超大并发下查询点赞数,就有点那啥了,确实没必要。
rushssss
2020-08-11 15:22:56 +08:00
入库后删 redis 数据是个啥操作
liyunlong41
2020-08-11 15:26:43 +08:00
Redis 使用 hash,大 key 使用文章 ID,小 key 为 userid,定时任务隔一段时间落库,没做过点赞,不知道这样是否能满足需求?
limboMu
2020-08-11 15:28:13 +08:00
mysql 里记录的数也可以放到 redis 啊,只要加一个版本号,按版本更新 redis 和 mysql 里的值就好了呀
rogwan
2020-08-11 15:33:39 +08:00
实时入库并没有什么大的压力,主要是查询。每次请求都要查询很多个点赞数的统计,这个有点过渡消耗了。一个取巧的方式是超过一定数量之后,就不再计算了,之间显示 “999” 这样。如果点赞数是一个重要的指标,那还是 redis 实时处理,批量入库。
lithbitren
2020-08-11 15:36:25 +08:00
点赞的精确需求一般都是前端解决,来回点赞取消前端先切数量,其他人的赞可以延迟处理
sujin190
2020-08-11 16:41:17 +08:00
多高的并发啊,就算 mysql update +1 这个性能是非常高的吧,再加上分库分表啥的,十万级 tps 应该是能轻松达到的吧,而点赞的日志会受限写入性能,那么完全可以异步队列落地就是了

先把点赞数加上去,前端缓存结果,然后用队列异步落地点赞记录,绰绰有余了

再不行把点赞数加在 redis 里,点赞记录也在 redis 加缓存,然后点赞记录推队列,异步落地 mysql 一小短时间后再回写 redis 确保准确,这样还不够你用的话,估计预算该上亿了吧,还问啥啊,找点牛人再做一个专门为点赞优化的的数据库就是了,千万级 tps 都小 case 了
CoderGeek
2020-08-11 17:06:19 +08:00
redis 自增为啥不行呢
janxin
2020-08-11 17:39:08 +08:00
感觉是个伪需求,要看你们的数据量大概是什么样子的。

其实你提到的加和处理就是一个方案,而且基本也能满足绝大部分场景下的需求。

更进一步方案需要根据你的数据量评估啊,比如你并发很高但是热点很集中和并发很高热点数据不是相对集中做法都是不一样的...
wysnylc
2020-08-11 17:43:30 +08:00
要性能就得接受延时,要实时就得接受低速,二者不可皆得

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/697374

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX