目前我涉及到做点赞这块,起初的设计是直接落库,用户的点赞和取消点赞直接对记录进行加减,这样的方案似乎很简单看起来也没啥问题,但是一旦流量多了起来,数据库肯定扛不住这么频繁的读写。
我参考了一些网上教程,基本都是采用 redis 异步入库,就是点赞和取消都交给 redis,redis 记录了点赞人和被点赞人,同时在另外记录点赞总数,然后通过定时任务进行异步落库并删除 redis 中的指定数据。
但是现在新的问题来了,当我要查询某个文章的点赞总数的时候,怎么保证数据的一致性呢,岂不是查询的总数的时候需要 mysql+redis = 总数才能保证唯一性,因为 redis 入库后记录就被删除了,防止内存庞大,而且 redis 并不会做持久化,麻烦做过这方面的大牛给我指点指点
1
IMCA1024 2020-08-11 15:02:14 +08:00
非要实时的点赞数据吗,有特殊需求?
|
2
totoro52 OP 有的,点赞在前台展示是需要保证实时的
|
3
fdingiit 2020-08-11 15:05:16 +08:00
为什么要删 redis 数据?
|
4
Veneris 2020-08-11 15:06:10 +08:00 2
|
6
palmers 2020-08-11 15:07:31 +08:00
是不是可以通过期策略 来解决部分问题?
|
8
luckyrayyy 2020-08-11 15:15:14 +08:00 1
超大并发下查询准确实时的点赞数量,本身不就是个伪需求嘛...谁会关心这个?
|
9
yuzo555 2020-08-11 15:20:06 +08:00 1
Redis 设置过期时间,根据周期使用不同的 Redis 键名,比如周期一天,文章 ID 是 123,那么点赞键名比如说是 like_123_20200811 (计数),like_123_20200811_user ( list,记录用户)。
第一次创建时(用 incr 增加计数键,判断返回值即可知道是否为第一次)设置一个 25 小时的过期时间。 定时比如每天 0:30 统计昨天的数量,加到数据库。 |
10
yuzo555 2020-08-11 15:21:26 +08:00
如果更短的周期可以用时间戳除以周期秒数取整来代替日期
|
11
ericgui 2020-08-11 15:22:54 +08:00
|
12
rushssss 2020-08-11 15:22:56 +08:00
入库后删 redis 数据是个啥操作
|
13
liyunlong41 2020-08-11 15:26:43 +08:00 via iPhone
Redis 使用 hash,大 key 使用文章 ID,小 key 为 userid,定时任务隔一段时间落库,没做过点赞,不知道这样是否能满足需求?
|
14
limboMu 2020-08-11 15:28:13 +08:00
mysql 里记录的数也可以放到 redis 啊,只要加一个版本号,按版本更新 redis 和 mysql 里的值就好了呀
|
15
rogwan 2020-08-11 15:33:39 +08:00 1
实时入库并没有什么大的压力,主要是查询。每次请求都要查询很多个点赞数的统计,这个有点过渡消耗了。一个取巧的方式是超过一定数量之后,就不再计算了,之间显示 “999” 这样。如果点赞数是一个重要的指标,那还是 redis 实时处理,批量入库。
|
16
lithbitren 2020-08-11 15:36:25 +08:00
点赞的精确需求一般都是前端解决,来回点赞取消前端先切数量,其他人的赞可以延迟处理
|
17
sujin190 2020-08-11 16:41:17 +08:00 1
多高的并发啊,就算 mysql update +1 这个性能是非常高的吧,再加上分库分表啥的,十万级 tps 应该是能轻松达到的吧,而点赞的日志会受限写入性能,那么完全可以异步队列落地就是了
先把点赞数加上去,前端缓存结果,然后用队列异步落地点赞记录,绰绰有余了 再不行把点赞数加在 redis 里,点赞记录也在 redis 加缓存,然后点赞记录推队列,异步落地 mysql 一小短时间后再回写 redis 确保准确,这样还不够你用的话,估计预算该上亿了吧,还问啥啊,找点牛人再做一个专门为点赞优化的的数据库就是了,千万级 tps 都小 case 了 |
18
CoderGeek 2020-08-11 17:06:19 +08:00
redis 自增为啥不行呢
|
19
janxin 2020-08-11 17:39:08 +08:00
感觉是个伪需求,要看你们的数据量大概是什么样子的。
其实你提到的加和处理就是一个方案,而且基本也能满足绝大部分场景下的需求。 更进一步方案需要根据你的数据量评估啊,比如你并发很高但是热点很集中和并发很高热点数据不是相对集中做法都是不一样的... |
20
wysnylc 2020-08-11 17:43:30 +08:00
要性能就得接受延时,要实时就得接受低速,二者不可皆得
|
21
microget 2020-08-11 17:43:53 +08:00
产品经理的 KPI 吧
|
22
swulling 2020-08-11 17:46:06 +08:00 via iPhone
其实以你们产品的并发,根本就用不上 redis
|
23
wweir 2020-08-11 17:56:08 +08:00 via Android
既要实时又要高并发,单点可以实现,不过说起来很多业务不敢这么玩
|
24
totoro52 OP 哈哈哈 谢谢各位的回复,我懂了,我明天 TM 就把产品经理杀了祭天
|
25
locoz 2020-08-11 18:21:00 +08:00 via Android
消息队列慢慢入库+伪实时数量?
|
26
1018ji 2020-08-11 18:21:20 +08:00
实时点赞,这真是个牛逼的需求
|
27
Leigg 2020-08-11 18:26:16 +08:00 via Android
实时点赞真没必要,非要解决的话上数据放内存里。
|
28
kisshere 2020-08-11 22:30:25 +08:00 via Android
都能把 MySQL 的 update+1 给写崩溃了,你这站的访问量也太大了吧,如果真有那么大,别拿 MySQL 存点赞数,拿其他硬盘型的 nosql 存
|
29
CoderGeek 2020-08-13 09:50:26 +08:00
减少数据库更新 第一次从库加载在到 redis 做自增 一段时间 定期刷库 不好吗
|