阿里秒杀系统架构优化思路
秒殺業(yè)務(wù)為什么難做
- im系統(tǒng),例如qq或者微博,每個人都讀自己的數(shù)據(jù)(好友列表、群列表、個人信息)
- 微博系統(tǒng),每個人讀你關(guān)注的人的數(shù)據(jù),一個人讀多個人的數(shù)據(jù)
- 秒殺系統(tǒng),庫存只有一份,所有人會在集中的時間讀和寫這些數(shù)據(jù),多個人讀一個數(shù)據(jù)
例如:小米手機(jī)每周二的秒殺,可能手機(jī)只有1萬部,但瞬時進(jìn)入的流量可能是幾百幾千萬。
又例如:12306搶票,票是有限的,庫存一份,瞬時流量非常多,都讀相同的庫存。讀寫沖突,鎖非常嚴(yán)重,這是秒殺業(yè)務(wù)難的地方。那我們怎么優(yōu)化秒殺業(yè)務(wù)的架構(gòu)呢?
優(yōu)化方向
優(yōu)化方向有兩個(今天就講這兩個點(diǎn)):
(1)將請求盡量攔截在系統(tǒng)上游(不要讓鎖沖突落到數(shù)據(jù)庫上去)。傳統(tǒng)秒殺系統(tǒng)之所以掛,請求都壓倒了后端數(shù)據(jù)層,數(shù)據(jù)讀寫鎖沖突嚴(yán)重,并發(fā)高響應(yīng)慢,幾乎所有請求都超時,流量雖大,下單成功的有效流量甚小。以12306為例,一趟火車其實只有2000張票,200w個人來買,基本沒有人能買成功,請求有效率為0。
(2)充分利用緩存,秒殺買票,這是一個典型的讀多些少的應(yīng)用場景,大部分請求是車次查詢,票查詢,下單和支付才是寫請求。一趟火車其實只有2000張票,200w個人來買,最多2000個人下單成功,其他人都是查詢庫存,寫比例只有0.1%,讀比例占99.9%,非常適合使用緩存來優(yōu)化。好,后續(xù)講講怎么個“將請求盡量攔截在系統(tǒng)上游”法,以及怎么個“緩存”法,講講細(xì)節(jié)。
常見秒殺架構(gòu)
常見的站點(diǎn)架構(gòu)基本是這樣的(絕對不畫忽悠類的架構(gòu)圖)
這個圖雖然簡單,但能形象的說明大流量高并發(fā)的秒殺業(yè)務(wù)架構(gòu),大家要記得這一張圖。
后面細(xì)細(xì)解析各個層級怎么優(yōu)化。
各層次優(yōu)化細(xì)節(jié)
第一層,客戶端怎么優(yōu)化(瀏覽器層,APP層)
問大家一個問題,大家都玩過微信的搖一搖搶紅包對吧,每次搖一搖,就會往后端發(fā)送請求么?回顧我們下單搶票的場景,點(diǎn)擊了“查詢”按鈕之后,系統(tǒng)那個卡呀,進(jìn)度條漲的慢呀,作為用戶,我會不自覺的再去點(diǎn)擊“查詢”,對么?繼續(xù)點(diǎn),繼續(xù)點(diǎn),點(diǎn)點(diǎn)點(diǎn)。。。有用么?平白無故的增加了系統(tǒng)負(fù)載,一個用戶點(diǎn)5次,80%的請求是這么多出來的,怎么整?
(a)產(chǎn)品層面,用戶點(diǎn)擊“查詢”或者“購票”后,按鈕置灰,禁止用戶重復(fù)提交請求;
(b)JS層面,限制用戶在x秒之內(nèi)只能提交一次請求;
APP層面,可以做類似的事情,雖然你瘋狂的在搖微信,其實x秒才向后端發(fā)起一次請求。這就是所謂的“將請求盡量攔截在系統(tǒng)上游”,越上游越好,瀏覽器層,APP層就給攔住,這樣就能擋住80%+的請求,這種辦法只能攔住普通用戶(但99%的用戶是普通用戶)對于群內(nèi)的高端程序員是攔不住的。firebug一抓包,http長啥樣都知道,js是萬萬攔不住程序員寫for循環(huán),調(diào)用http接口的,這部分請求怎么處理?
第二層,站點(diǎn)層面的請求攔截
怎么攔截?怎么防止程序員寫for循環(huán)調(diào)用,有去重依據(jù)么?ip?cookie-id?…想復(fù)雜了,這類業(yè)務(wù)都需要登錄,用uid即可。在站點(diǎn)層面,對uid進(jìn)行請求計數(shù)和去重,甚至不需要統(tǒng)一存儲計數(shù),直接站點(diǎn)層內(nèi)存存儲(這樣計數(shù)會不準(zhǔn),但最簡單)。一個uid,5秒只準(zhǔn)透過1個請求,這樣又能攔住99%的for循環(huán)請求。
5s只透過一個請求,其余的請求怎么辦?緩存,頁面緩存,同一個uid,限制訪問頻度,做頁面緩存,x秒內(nèi)到達(dá)站點(diǎn)層的請求,均返回同一頁面。同一個item的查詢,例如車次,做頁面緩存,x秒內(nèi)到達(dá)站點(diǎn)層的請求,均返回同一頁面。如此限流,既能保證用戶有良好的用戶體驗(沒有返回404)又能保證系統(tǒng)的健壯性(利用頁面緩存,把請求攔截在站點(diǎn)層了)。
頁面緩存不一定要保證所有站點(diǎn)返回一致的頁面,直接放在每個站點(diǎn)的內(nèi)存也是可以的。優(yōu)點(diǎn)是簡單,壞處是http請求落到不同的站點(diǎn),返回的車票數(shù)據(jù)可能不一樣,這是站點(diǎn)層的請求攔截與緩存優(yōu)化。
好,這個方式攔住了寫for循環(huán)發(fā)http請求的程序員,有些高端程序員(黑客)控制了10w個肉雞,手里有10w個uid,同時發(fā)請求(先不考慮實名制的問題,小米搶手機(jī)不需要實名制),這下怎么辦,站點(diǎn)層按照uid限流攔不住了。
第三層 服務(wù)層來攔截(反正就是不要讓請求落到數(shù)據(jù)庫上去)
服務(wù)層怎么攔截?大哥,我是服務(wù)層,我清楚的知道小米只有1萬部手機(jī),我清楚的知道一列火車只有2000張車票,我透10w個請求去數(shù)據(jù)庫有什么意義呢?沒錯,請求隊列!
對于寫請求,做請求隊列,每次只透有限的寫請求去數(shù)據(jù)層(下訂單,支付這樣的寫業(yè)務(wù))
1w部手機(jī),只透1w個下單請求去db
3k張火車票,只透3k個下單請求去db
如果均成功再放下一批,如果庫存不夠則隊列里的寫請求全部返回“已售完”。
對于讀請求,怎么優(yōu)化?cache抗,不管是memcached還是redis,單機(jī)抗個每秒10w應(yīng)該都是沒什么問題的。如此限流,只有非常少的寫請求,和非常少的讀緩存mis的請求會透到數(shù)據(jù)層去,又有99.9%的請求被攔住了。
當(dāng)然,還有業(yè)務(wù)規(guī)則上的一些優(yōu)化。回想12306所做的,分時分段售票,原來統(tǒng)一10點(diǎn)賣票,現(xiàn)在8點(diǎn),8點(diǎn)半,9點(diǎn),...每隔半個小時放出一批:將流量攤勻。
其次,數(shù)據(jù)粒度的優(yōu)化:你去購票,對于余票查詢這個業(yè)務(wù),票剩了58張,還是26張,你真的關(guān)注么,其實我們只關(guān)心有票和無票?流量大的時候,做一個粗粒度的“有票”“無票”緩存即可。
第三,一些業(yè)務(wù)邏輯的異步:例如下單業(yè)務(wù)與 支付業(yè)務(wù)的分離。這些優(yōu)化都是結(jié)合 業(yè)務(wù) 來的,我之前分享過一個觀點(diǎn)“一切脫離業(yè)務(wù)的架構(gòu)設(shè)計都是耍流氓”架構(gòu)的優(yōu)化也要針對業(yè)務(wù)。
好了,最后是數(shù)據(jù)庫層
瀏覽器攔截了80%,站點(diǎn)層攔截了99.9%并做了頁面緩存,服務(wù)層又做了寫請求隊列與數(shù)據(jù)緩存,每次透到數(shù)據(jù)庫層的請求都是可控的。db基本就沒什么壓力了,閑庭信步,單機(jī)也能扛得住,還是那句話,庫存是有限的,小米的產(chǎn)能有限,透這么多請求來數(shù)據(jù)庫沒有意義。
全部透到數(shù)據(jù)庫,100w個下單,0個成功,請求有效率0%。透3k個到數(shù)據(jù),全部成功,請求有效率100%。
總結(jié)
對于秒殺系統(tǒng),我個人經(jīng)驗有兩個架構(gòu)優(yōu)化思路:
(1)盡量將請求攔截在系統(tǒng)上游(越上游越好);
(2)讀多寫少的常用多使用緩存(緩存抗讀壓力);
瀏覽器和APP:做限速
站點(diǎn)層:按照uid做限速,做頁面緩存
服務(wù)層:按照業(yè)務(wù)做寫請求隊列控制流量,做數(shù)據(jù)緩存
數(shù)據(jù)層:閑庭信步
并且:結(jié)合業(yè)務(wù)做優(yōu)化
那如何學(xué)習(xí)才能快速入門并精通呢?
當(dāng)真正開始學(xué)習(xí)的時候難免不知道從哪入手,導(dǎo)致效率低下影響繼續(xù)學(xué)習(xí)的信心。
但最重要的是不知道哪些技術(shù)需要重點(diǎn)掌握,學(xué)習(xí)時頻繁踩坑,最終浪費(fèi)大量時間,所以有一套實用的視頻課程用來跟著學(xué)習(xí)是非常有必要的。
為了讓學(xué)習(xí)變得輕松、高效,今天給大家免費(fèi)分享一套阿里的Java架構(gòu)師傳授的一套教學(xué)資源。幫助大家在成為架構(gòu)師的道路上披荊斬棘。
這套視頻課程,詳細(xì)講解了像(Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化、分布式架構(gòu))等這些成為架構(gòu)師必備的內(nèi)容!
而且還把框架需要用到的各種程序進(jìn)行了打包,根據(jù)基礎(chǔ)視頻可以讓你輕松搭建分布式框架環(huán)境,像在企業(yè)生產(chǎn)環(huán)境一樣進(jìn)行學(xué)習(xí)和實踐。在此我向大家推薦一個Java架構(gòu)交流群:687107762
最后,做一個愛思考,懂思考,會思考的程序員。
來源:https://blog.csdn.net/qq_41314702/article/details/80515221
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的阿里秒杀系统架构优化思路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样清理厨房顽固油污
- 下一篇: 到底多大才算高并发?