现成的技术解决方案太多,redis 的并发性能真的是没得说,关键是想问问都是怎么处理数据同步的问题的。
发布秒杀活动,发布成功后就直接入 redis ?
if (insert ok) redis.set('ms:itemid',stock) ?
入 redis 失败了呢? redis 挂掉这阶段的数据没保存呢(还没来得及 fsync)?
活动结束后 怎么删除(不能用 setnx 的场景,没过期时间,售完算完)?
if(decr('ms:itemid')<0) del('ms:itmeid') ?
怎么及时的删除脏数据?
大半夜睡不着不知道自己在纠结什么。 :(
1
hareandlion 2017-09-04 07:17:40 +08:00 via iPhone
额,启用热备,一个备份不够就多上几个?剩下的就是预防成本高于实际需求的小概率情况了吧?
|
2
jalja27 2017-09-04 07:31:20 +08:00 via Android
‘ 1
|
3
linpf 2017-09-04 09:09:35 +08:00 9
讲道理,业务上改一改规则的话,没必要完全实现秒杀,假设同一秒有 1 万个用户抢购 100 件商品,nginx 直接按照 97%的几率抛弃请求,返回“抢购失败,还有机会,请重新抢购”,省下大约 300 个请求,直接用 mysql 就行了。这样购买时间都是同一秒的请求,用户也不知道他到底在这 1 秒之内的顺序。对活动方来说,活动效果也实现了。毕竟运气也是实力的一部分。
|
6
jyz19880823 2017-09-04 13:55:49 +08:00
@linpf 666
|
9
cevincheung OP @linpf #3 23333
|
10
cevincheung OP @linpf #3 就直接 select for update 了?
|
11
paragon 2017-09-04 15:44:37 +08:00
前面加验证码 后面提交验证的验证码就丢了
|
13
MrFireAwayH 2017-09-04 16:24:35 +08:00
@kamushin #12 虽然不是很懂 但是我觉得判断一下并发请求数目后再进行 97%概率抛弃是能做到的吧
|
14
yexiangyang 2017-09-04 17:14:13 +08:00
1.if(decr('ms:itemid')<0) del('ms:itmeid') ?
可以修改为 if(decr('ms:itemid')=0) del('ms:itmeid') 2.入 redis 失败了呢? redis 挂掉这阶段的数据没保存呢(还没来得及 fsync)? 建议采用 sentinel 模式 挂掉后故障转移,时间不会很久,期间可以业务失败 |
15
caijihui11 2017-09-04 19:27:42 +08:00
@linpf 这个实现 6,但我们也要维护参与活动的公平性,不能以运气来搞
|
16
qiyuey 2017-09-04 21:20:31 +08:00
@caijihui11 随机难道不公平吗
|
18
linpf 2017-09-05 08:19:32 +08:00
@caijihui11 这就要看为了这点公平性,提升的成本能不能接受了
|
19
linpf 2017-09-05 09:24:09 +08:00
@caijihui11 而且每个用户访问请求接口,网络环境的不同也会存在延迟也有几毫秒到几秒的随机,其实请求到达服务器的顺序本身就已经不是按照点按钮的顺序了。
|
20
tausi0661 2017-09-05 10:57:33 +08:00
@qiyuey 吹毛求疵的说, "秒杀"的意思是"比谁快". 而随机意味着"我比你快, 但我被随机掉了"
(3#666, 我也打算这么实现...) |
21
zhengwenk 2017-09-05 13:24:08 +08:00
@caijihui11 其实也可以把请求入队列,只消费前 300 个,之后的请求都抛弃掉。
|
22
1cming 2018-05-10 20:44:05 +08:00
3#666
|