<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>秒杀 on 勇气</title><link>https://courages.us/tag/%E7%A7%92%E6%9D%80/</link><description>Recent content in 秒杀 on 勇气</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Tue, 14 Jul 2015 09:36:13 +0800</lastBuildDate><atom:link href="https://courages.us/tag/%E7%A7%92%E6%9D%80/index.xml" rel="self" type="application/rss+xml"/><item><title>MySQL秒杀优化</title><link>https://courages.us/%E7%A7%92%E6%9D%80/</link><pubDate>Sun, 12 Jul 2015 17:08:24 +0800</pubDate><guid>https://courages.us/%E7%A7%92%E6%9D%80/</guid><description>&lt;p&gt;今天学习了&lt;a class="link" href="http://weibo.com/dbatools" target="_blank" rel="noopener"&#10; &gt;楼方鑫先生&lt;/a&gt;的 &lt;a class="link" href="http://www.infoq.com/cn/presentations/seckill-solution-based-sql" target="_blank" rel="noopener"&#10; &gt;《基于SQL的秒杀解决方案》&lt;/a&gt;，讲解了如何定位和优化秒杀业务中问题。&lt;br&gt;&#10;首先介绍了库存业务，库存可以分为前端库存，后端库存，实体库存。秒杀时，存在的主要问题&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;库存数据不准确，下单、付款后，得知零库存；超卖或少卖&lt;/li&gt;&#10;&lt;li&gt;废单较多，只下单不付款，转化率低&lt;/li&gt;&#10;&lt;li&gt;热点商品，拖垮整个站&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;秒杀过程中，需要解决的技术点包括&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;余额减一&lt;/li&gt;&#10;&lt;li&gt;操作明细，方便追溯对账，防止一个帐号多次参与&lt;/li&gt;&#10;&lt;li&gt;完整事务，保障记录明细与扣减库存同时完成&lt;/li&gt;&#10;&lt;li&gt;数据落地，内存数据不可靠&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;针对库存技术要求，做了多个库存解决方案，比如Mysql + Read /Write Cache 。Read Cache方案不足是读有延迟影响用户体验；Write Cache方案存在多个APP写数据不一致性。Mysql + Cache + NoSQL方案则太复杂未实现。&lt;/p&gt;&#10;&lt;p&gt;于是又重新回到优化Mysql上。Mysql优势在于事务机制成熟，程序稳定。存在技术难点：单行并发，热点商品，瞬间压力，前一分钟，千万用户，容易堵塞，拖垮网站。于是从以下几个方面进行优化&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;事务优化，单行更新&lt;/li&gt;&#10;&lt;li&gt;并发优化，最大并发数&lt;/li&gt;&#10;&lt;li&gt;排队优化，抢同一商品&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;分析秒杀时的处理逻辑，扫描系统代码，发现大部分程序都在等待确认Update记录数，才提交事务。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;开启事务&lt;/li&gt;&#10;&lt;li&gt;Insert库存明细&lt;/li&gt;&#10;&lt;li&gt;Update库存余额&lt;/li&gt;&#10;&lt;li&gt;提交事务&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;在良好设计下，Mysql的Insert操作，不使用自增列是不会阻塞请求。但是Mysql的Update同一条记录是串行的，需要等远程客户端发送提交命令后才能释放锁，让其他会话继续。简单的更新操作，不考虑IO和锁冲突，一条语句执行的时间大约是0.1ms，一般条件下的网络时延为0.4-0.8ms，即等待事务提交通知的时间比真正SQL执行的时间长数倍。&lt;br&gt;&#10;于是扩展了SQL语法（&lt;a class="link" href="http://www.onexsoft.com/onesql" target="_blank" rel="noopener"&#10; &gt;OneSQL&lt;/a&gt;），指定在Update执行完后自动提交，不需要等待客户端发送提交命令，从而节约这一个网络来回的事务等待时间，提升网络性能。&lt;/p&gt;&#10;&lt;p&gt;秒杀时如果遇到大量请求需要进行排队，以免太多的请求拖垮Mysql&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;在应用层排队的缺点，应用需要改造，使用统一框架（需要考虑跨语言)，应用集群扩容时，控制不准确（连接数分配）&lt;/li&gt;&#10;&lt;li&gt;在Mysql排队的优点，应用改造极少，只需修改少量SQL语句，无需统一框架，排队精确，发挥InnoDB性能。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;于是开发了兼容Mysql的分布式数据访问层（&lt;a class="link" href="http://www.onexsoft.com/oneproxy" target="_blank" rel="noopener"&#10; &gt;OneProxy&lt;/a&gt;），为并发请求进行排队。&lt;/p&gt;&#10;&lt;p&gt;另外，还对热点商品进行独立数据库拆分和优化。目前，双十一前商品便已挂出，用户可以收藏或预购，对于商家而言可以准备更多商品；对于平台而言可以预先发现热点商品做优化。&lt;/p&gt;&#10;&lt;p&gt;总结，对于业务优化，需要循序渐进，深入了解业务逻辑和技术点，比较不同的解决方案，就算是平常的update操作也有优化空间；同时需要从其他方面进行特定优化，如高并发排队，热点数据分离等。&lt;/p&gt;&#10;&lt;p&gt;除了后端数据库优化，对于秒杀抽奖业务，问题的解决核心就是控制单位时间内的流量，使其不超过后端的处理能力。前端的做法包括&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;分批次（少量多次)进行秒杀&lt;/li&gt;&#10;&lt;li&gt;先玩游戏再抢购，如抽奖&lt;/li&gt;&#10;&lt;li&gt;随机过滤掉部分请求，仅部分进入系统，如1/10&lt;/li&gt;&#10;&lt;li&gt;阈值控制，一旦达到阈值，不再接收新请求&lt;/li&gt;&#10;&lt;li&gt;预约排号，未排号用户返回失败（用户分类）&lt;/li&gt;&#10;&lt;li&gt;验证码验证&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;另外，&lt;a class="link" href="http://www.onexsoft.com/oneproxy/oneproxy-connection-pool" target="_blank" rel="noopener"&#10; &gt;OneProxy 提供的连接池功能&lt;/a&gt;对于PHP非常有用。PHP运行在CGI下面，每一个请求到来便需要重新创建一个数据库连接与Mysql进行交互，并发量大量的情况下便会出现：too many connetion，乃至拖垮数据库：mysql server has gone away，影响其他业务。因此Mysql连接池，对于PHP显得非常重要。&lt;/p&gt;&#10;&lt;p&gt;更新：&lt;a class="link" href="http://www.infoq.com/cn/presentations/the-use-of-minority-languages-in-venture-company" target="_blank" rel="noopener"&#10; &gt;小米网在开发抢购系统&lt;/a&gt;的时候，最早使用PHP + Mysql碰到了一些问题，例如并发性能，数据一致性，在OneSQL上面都已经做了改进优化，只是小米自己使用Go语言重构，开发大秒系统（BigTap）。&lt;/p&gt;&#10;&lt;p&gt;参考链接：&lt;br&gt;&#10;&lt;a class="link" href="http://www.iteye.com/problems/101435" target="_blank" rel="noopener"&#10; &gt;限量秒杀等高并发活动的正确性如何保证？&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://imysql.com/2014/06/07/mysql-percona-mariadb-onesql-tpcc-benchmark.shtml" target="_blank" rel="noopener"&#10; &gt;MySQL 5.6.17/Percona5.6.16/MariaDB 10.0.11/OneSQL 5.6.16 TpmC测试&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://coolshell.cn/articles/6470.html" target="_blank" rel="noopener"&#10; &gt;由12306.cn谈谈网站性能技术&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.csdn.net/article/2014-11-07/2822545" target="_blank" rel="noopener"&#10; &gt;“米粉节”背后的故事——小米网抢购系统开发实践&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.csdn.net/article/2014-11-28/2822858" target="_blank" rel="noopener"&#10; &gt;Web系统大规模并发——电商秒杀与抢购&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.onexsoft.com/oneproxy/oneproxy-connection-pool" target="_blank" rel="noopener"&#10; &gt;OneProxy : 如何给PHP页面以及其他Ruby/Python/Go程序添加连接池功能？&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://github.com/LinkedDestiny/swoole-doc/blob/master/03.Timer%E5%AE%9A%E6%97%B6%E5%99%A8%E3%80%81%E5%BF%83%E8%B7%B3%E6%A3%80%E6%B5%8B%E5%8F%8ATask%E8%BF%9B%E9%98%B6%E5%AE%9E%E4%BE%8B%EF%BC%9Amysql%E8%BF%9E%E6%8E%A5%E6%B1%A0.md" target="_blank" rel="noopener"&#10; &gt;基于Swoole实现的Mysql连接池&lt;/a&gt;&lt;/p&gt;&#10;</description></item></channel></rss>