求完美的 PHP 并发锁机制

2016-11-23 21:36:10 +08:00
 yangwenqian
要做一个抢红包的功能,环境是使用红包接口, 10 万用户在同 1 秒种进行抢红包的操作,红包只有 10 个,在高并发的情况下,就无法控制了。
一般是先从数据库 count 红包记录,大于 0 个的话,就调用红包接口,然后在数据库写一条记录。
10 万用户在同一毫秒请求,数据库读写间隔时间太长了,导致 count 出来都是 0 ,没法限制 10 个。
请问该怎么锁?
网上有很多锁,试过大部分用 cache 锁或文件锁实现,我试了,在压力测试下,cache读写间隔时间比数据库少很多,但还是有间隔时间,仍然没有办法限制 10 个红包。
求解决办法。谢谢。
11141 次点击
所在节点    PHP
44 条回复
langmoe
2016-11-23 21:40:59 +08:00
数据库读锁
lynnworld
2016-11-23 21:45:15 +08:00
redis incr
batnss
2016-11-23 21:46:12 +08:00
redis 生成一个 10 个元素的队列
virusdefender
2016-11-23 21:53:16 +08:00
二楼说的对, redis incr 可以
cxbig
2016-11-23 22:01:09 +08:00
同 2 楼,十万用户还是交给缓存来处理。
php71
2016-11-23 22:04:05 +08:00
让请求只能进来 10 个,不直接操作数据库,我看别人做秒杀也是这个思路
Yunhao
2016-11-23 22:08:36 +08:00
无脑写入,把前一百的用户请求存起来,排个序,前十的给个红包 (逃...
cuebyte
2016-11-23 22:47:22 +08:00
@php71 怎么做才能让请求只进来十个?
tulongtou
2016-11-23 23:27:18 +08:00
JS 上做个处理,提交的时候截掉一部分,请求到后台了再截掉一部分,剩下的到业务逻辑的就不多了,再去进行秒杀
php71
2016-11-23 23:52:21 +08:00
@cuebyte redis 的 ordered set 当 set 里有 10 个的时候,其他请求就可以不用处理了吧,没意义了。

zadd 添加 /zcard 计算有多少个
orvice
2016-11-24 00:14:31 +08:00
@cuebyte 代码层上控制百分 90 的请求直接 return 失败。
abelyao
2016-11-24 00:32:11 +08:00
先抽奖,中奖的话再去 count 数据库,再确认是否真的中奖,可以很大很大的降低数据库请求量。
helloccav
2016-11-24 00:43:35 +08:00
@php71 正如楼主所说, "cache 读写间隔时间比数据库少很多,但还是有间隔时间,仍然没有办法限制 10 个红包", redis 也一样吧?
lslqtz
2016-11-24 01:12:42 +08:00
@orvice 代码层上控制百分 90 的请求直接 return 失败。
用户数并不是固定的啊
lianyue
2016-11-24 01:21:11 +08:00
。。。。。。 很简单吧

INSERT 发布的红包 (id, count) values(1, 10)

result = UPDATE 发布的红包 SET count = count - 1 WHERE id = 1 AND count > 0;
if (result === true) {
INSERT 已经抢了的红包 .....
}
lianyue
2016-11-24 01:24:50 +08:00
这样绝对不会多 可能会少一个进程异常中断等。。造成

如果要绝对的强一致性 可以用 sql 事务
mindcat
2016-11-24 03:49:55 +08:00
@Yunhao 做排序的剁死喵
ryd994
2016-11-24 04:25:17 +08:00
很明显你那个锁就是错的
对的锁只有慢的没有不一致的
这种需求不要用 SQL ,反正数据量不大,加内存用 Redis
Time2
2016-11-24 08:56:13 +08:00
redis 队列正解
qq496844026
2016-11-24 09:15:10 +08:00
Nginx 控制请求数量,然后 redis 的 incr 保证处理的正确性.这样可以最大程度的处理高并发了

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

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

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

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

© 2021 V2EX