2013-04 淘宝丁奇:秒杀场景下MySQL的低效--原因和改进(DTCC2013)

文字内容
1. DTCC2013 秒杀场景下MySQL的低效 --原因和改进 @淘宝丁奇 2009-8-22
2. DTCC2013 1. 秒杀/热卖商品背景 2. 性能问题 3. 几种解决方案
3. 秒杀/热卖商品背景 a)商品库存是有量的 b)买家下单以后库存要减掉 c)不能减成负数 DTCC2013
4. 秒杀/热卖商品背景 DTCC2013 基本逻辑 Start transaction Insert … Insert … Update set 库存 = 库存 – n where … Commit
5. 秒杀/热卖商品背景 DTCC2013
6. 秒杀/热卖商品背景 DTCC2013 多个用户 Start transaction Insert … Insert … Update set 库存 where 商品id…(互相等待) Commit 原因:InnoDB的行锁
7. 性能问题 原因是: 行锁串行导致性能下降吗? 分析: 问题可以简化为,很多线程更新同一行 CREATE TABLE `t1` ( `a` int(11) NOT NULL, `b` int(11) DEFAULT NULL, PRIMARY KEY (`a`) ) ENGINE=InnoDB; Insert into t1 values($i, 2147483647); 插入50行数据 DTCC2013
8. 性能问题 DTCC2013 tps 25000 20000 15000 tps 10000 5000 0 1 2 3 4 5 6 7 8 9 10 20 30 50 线程数 1 2 3 4 5 6 7 8 9 10 20 30 50 阶段结论 : 6个线程并发各自更新一行性能最高 TPS 6100 12700 16357 18570 19160 19160 18320 17000 16577 15700 15000 14250 13000
9. 性能问题—现象 DTCC2013 tps 20000 18000 16000 14000 12000 10000 tps 8000 6000 4000 2000 0 1 6 12 24 48 96 192 384 768 1536 线程数 1 6 12 24 48 96 192 384 768 1536 tps 6100 19160 14000 10000 9800 7000 3600 2000 600 150
10. 性能问题—分析 DTCC2013 1、随着并发线程增加,tps急剧下降 2、每个商品有128个线程并发请求的时候,tps已经跌到600 不可接受 3、 坏消息是,秒杀的时候,一个商品何止128个人来抢?
11. 性能问题—分析 DTCC2013 当并发线程多时,MySQL在做什么 因此,串行并不是问题,问题是InnoDB内部存在太多线程
12. 解决方案 在那之前,先回顾这张图片 DTCC2013
13. 解决方案 1 -- 关掉死锁检测 方案特点:  很直接  很暴力 正常的业务死锁会变成超时  不治标 除掉老大,还有老二,问题的症结没有解决 DTCC2013
14. 性能效果 DTCC2013 20000 线程数 TPS1 TPS2 1 6100 6100 6 19000 19000 12 14000 14000 24 12000 12000 48 9800 10000 TPS1 96 7000 8500 TPS2 192 3600 7200 384 2000 4800 768 600 2500 1536 150 1300 18000 16000 14000 12000 10000 8000 6000 4000 2000 0 1 6 12 24 48 96 192 384 768 虽然啊在1536线程时性能是8倍,但依然不可接受 1536
15. 性能效果分析 并发 线程 为什么平时我们没有这个问题? DTCC2013
16. 解决方案 2 – 关于症结 DTCC2013 固定车道的公路,最流畅的方式是什么
17. 解决方案 2 – 系统最优值 DTCC2013 在固定的硬件条件下、每个系统都有一个对应的状态最优值 InnoDB的线程数 将排队队列提到进入引擎层前
18. 解决方案 2 – 排队 DTCC2013
19. 解决方案 2 – 排队 DTCC2013
20. 解决方案 2 – 性能 DTCC2013 20000 18000 16000 14000 12000 TPS1 10000 TPS2 TPS3 8000 6000 4000 2000 0 1 6 12 24 48 96 192 TPS不随着线程数增加而下跌,维持在1.5w Update /*UPDATE_STOCK 1*/ t set b=b-1 where a=1; 384 768 1536
21. 解决方案 3 – 排队优化  想想排队买票的事儿 排队优化,成组提交 DTCC2013
22. 解决方案 2 – 排队优化 DTCC2013
23. 解决方案 2 – 排队优化 DTCC2013
24. 解决方案 2 – 排队优化 DTCC2013
25. 解决方案 3 – 性能对比 DTCC2013 100000 90000 80000 70000 60000 TPS1 TPS2 50000 TPS3 40000 tps4 30000 20000 10000 0 1 6 TPS 稳定在8.5w 12 24 48 96 192 384 768 1536
26. DTCC2013 解决方案 3—限制 语句: update /*UPDATE_STOCK 6784 1 '1' 'H<=Fquantity‘*/ tbl_name set withholding_quantity = withholding_quantity + 1, gmt_modified = NOW() where auction_id = 6784 and (withholding_quantity - 1) <= quantity; “太定制” 1、跟业务逻辑绑定较紧密 2、使用常见必须符合“可组提交”的限制 26
27. 总结 DTCC2013 多线程并发下,InnoDB内部要做死锁检测等操作,对性能 影响及其严重 明确的串行事务,则server层串行 Group commit减少引擎执行次数
28. 提问时间 DTCC2013 谢谢大家! 28