实现秒杀的几个想法(续)
轉(zhuǎn)自:http://blog.itpub.net/29254281/viewspace-1800617/
還是秒殺.
秒殺一般有幾個(gè)場(chǎng)景
1.電商秒殺商品
2.搶紅包
3.搶票
假設(shè)一個(gè)場(chǎng)景如下:
? ? 某電商公司搞活動(dòng),一折秒殺,推出幾種秒殺的商品,每種商品1000個(gè),預(yù)計(jì)100w人搶購(gòu)
要求:
? ? 不能超賣.絕對(duì)不可以賣多了.
? ? 數(shù)據(jù)庫(kù)要扣減庫(kù)存,并且記錄訂單明細(xì).
難點(diǎn)分析
1.不能阻塞.
海量的請(qǐng)求就像血栓一樣,遍走周身,一旦遇到瓶頸,就會(huì)堵塞整個(gè)血管.
所以一定要讓海量的用戶請(qǐng)求,盡快結(jié)束.
2.數(shù)據(jù)庫(kù)單行更新
大量的 update 庫(kù)存表 set 剩余數(shù)量=剩余數(shù)量-1 where 商品ID=?
這種單行更新,有行鎖,會(huì)阻塞其他事務(wù),占用寶貴的數(shù)據(jù)庫(kù)處理能力.
針對(duì)這種場(chǎng)景,綜合了很多資料
我覺得可以嘗試幾個(gè)關(guān)于秒殺的優(yōu)化.
1.Web服務(wù)器集群層,卸載流量
? ? 海量的用戶秒殺請(qǐng)求,本質(zhì)上是一個(gè)排序,先到先得.
????但是如此之多的請(qǐng)求,完全響應(yīng),難度又很大.
? ? 所以在Web服務(wù)器集群,可以考慮卸載流量.
? ? 比如每十個(gè)請(qǐng)求,隨機(jī)拋棄九個(gè),只放行一個(gè)請(qǐng)求到后續(xù)處理環(huán)節(jié).
? ? 把秒殺的排序模式,變?yōu)殡S機(jī)抽獎(jiǎng)的模式.
????
2.Web服務(wù)器集群層,縮小鎖范圍.
? ? 每次秒殺活動(dòng)開始之前.先計(jì)算活動(dòng)推出的商品數(shù)量,然后分配一個(gè)限額到每個(gè)Web服務(wù)器.
? ? 比如一個(gè)活動(dòng)推出秒殺商品
? ? 電視,手機(jī),衣服各1000件,那么每臺(tái)服務(wù)器的限額就是125件.
? ? 將這個(gè)限額寫入ZooKeeper,Web服務(wù)器監(jiān)聽到限額的變化,就會(huì)重新初始化各自的商品剩余數(shù)量.
模擬示例:
? ? 假設(shè)用戶請(qǐng)求秒殺電視機(jī),它只是鎖了該Web服務(wù)器電視機(jī)的數(shù)量。(該Web服務(wù)器手機(jī)和衣服還可以繼續(xù)并發(fā)處理,當(dāng)然其他的Web服務(wù)器也在同時(shí)處理電視機(jī)的秒殺請(qǐng)求)
? ? 這樣縮小了鎖定的范圍,增加了系統(tǒng)處理的吞吐量.
????如果這個(gè)剩余數(shù)量大于零,則將用戶ID放入電視機(jī)購(gòu)買隊(duì)列,然后告知用戶秒殺成功
? ? 如果這個(gè)剩余數(shù)量等于零,則告知用戶秒殺失敗.即便別的Web服務(wù)器還有電視機(jī)的剩余配額.
3.ZooKeeper層,ZooKeeper變更庫(kù)存信息
? ? 假設(shè)活動(dòng)期間,需要修改庫(kù)存信息。
? ? 兩種可能,
? ? 第一種,該商品已經(jīng)賣了500件,電商不想繼續(xù)賣了.
? ? 第二種,從倉(cāng)庫(kù)中又找到了一些積壓庫(kù)存..
? ? 兩種情況,都直接修改ZooKeeper中相應(yīng)商品的配額.
? ? Web服務(wù)器會(huì)監(jiān)聽變化,并重新初始化全局容器.
4.消息隊(duì)列層,多消費(fèi)者處理
? ? 消費(fèi)者主要是從隊(duì)列獲取購(gòu)買請(qǐng)求,發(fā)送至數(shù)據(jù)庫(kù)
? ? 扣減數(shù)據(jù)庫(kù)庫(kù)存
? ? 寫訂單明細(xì)記錄
5.數(shù)據(jù)庫(kù)層,使用存儲(chǔ)過程代替JDBC調(diào)用
? ? 由于使用了多消費(fèi)者處理同一隊(duì)列,增加吞吐量,避免隊(duì)列堆積過大.
? ? 但是多消費(fèi)者,必然導(dǎo)致數(shù)據(jù)庫(kù)出現(xiàn)單行更新問題.
? ? 單行更新問題就是多個(gè)線程,并發(fā)修改同一條記錄,導(dǎo)致事務(wù)相互阻塞.浪費(fèi)了數(shù)據(jù)庫(kù)寶貴的處理能力.
? ? 考查下圖.
????假設(shè)消費(fèi)者到數(shù)據(jù)庫(kù)的網(wǎng)絡(luò)是1毫秒
? ? 那么相對(duì)于存儲(chǔ)過程,使用JDBC的方式,每個(gè)事務(wù)將至少多持有行鎖2毫秒.
? ? 所以進(jìn)一步優(yōu)化,可以考慮用存儲(chǔ)過程代替JDBC
6.數(shù)據(jù)庫(kù)層,庫(kù)存單行更新,增加多個(gè)槽位.
? ? 單行更新場(chǎng)景
? ? 增加槽位的表結(jié)構(gòu)
? ?
????使用槽位分散行鎖
? ? 每種商品的庫(kù)存,由4個(gè)槽位組成.
? ? 事務(wù)開始,首先找到剩余數(shù)量最多的那個(gè)商品槽位.
? ? 然后扣減該槽位的庫(kù)存.
? ? 這樣一個(gè)行鎖,可以變?yōu)?個(gè)行鎖,系統(tǒng)吞吐量增加了4倍.
? ? (其實(shí)如果update的影響行數(shù)為0,表示該槽位已經(jīng)沒有庫(kù)存.可以重復(fù)執(zhí)行這個(gè)過程,再另選一個(gè)槽位)
commit;
7.數(shù)據(jù)庫(kù)層,冷熱商品分開.
? ? 某些熱點(diǎn)商品,可以單獨(dú)放置在一個(gè)數(shù)據(jù)庫(kù)處理
? ? 比如蘋果手機(jī)新品,特賣打折 10w部
? ? 這種注定會(huì)熱的商品,應(yīng)該使用單獨(dú)的數(shù)據(jù)庫(kù)處理
? ? 避免和普通商品競(jìng)爭(zhēng),堵塞本次活動(dòng)其他商品的處理.
參考:
http://blog.itpub.net/29254281/viewspace-1783043/
? ??
http://jiagou.baijia.baidu.com/article/108134?qq-pf-to=pcqq.group
http://www.infoq.com/cn/presentations/seckill-solution-based-sql
轉(zhuǎn)載于:https://www.cnblogs.com/yanwei-wang/p/5957137.html
總結(jié)
以上是生活随笔為你收集整理的实现秒杀的几个想法(续)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【小白成长撸】--二分查找
- 下一篇: web.xml中的那些标签和意义