應對大併發

volatile_logo

高併發是我們現在老生常談的內容了,這裏我們以秒殺爲例,來聊聊怎麼應對大併發。

一、秒殺帶來的問題

在高併發秒殺的情況下,一般會有以下問題:
1、高併發

比較火熱的秒殺在線人數都是10w起的,如此之高的在線人數對於網站架構從前到後都是一種考驗。

2、超賣

任何商品都會有數量上限,如何避免成功下訂單買到商品的人數不超過商品數量的上限,這是每個搶購活動都要面臨的難題。

二、解決辦法

每當我們提到高併發時總會想到這幾種解決方案:
①擴容
加機器,這是最簡單的方法,通過增加前端池的整體承載量來抗峯值。

②靜態化
將活動頁面上的所有可以靜態的元素全部靜態化,並儘量減少動態元素。通過CDN來抗峯值。

③限流
一般都會採用IP級別的限流,即針對某一個IP,限制單位時間內發起請求數量。或者活動入口的時候增加遊戲或者問題環節進行消峯操作

解決方案1:

將存庫從MySQL前移到Redis中,所有的寫操作放到內存中,由於Redis中不存在鎖故不會出現互相等待,並且由於Redis的寫性能和讀性能都遠高於MySQL,這就解決了高併發下的性能問題。然後通過隊列等異步手段,將變化的數據異步寫入到DB中。

優點:解決性能問題

缺點:沒有解決超賣問題,同時由於異步寫入DB,存在某一時刻DB和Redis中數據不一致的風險。

解決方案2:

引入隊列,然後將所有寫DB操作在單隊列中排隊,完全串行處理。當達到庫存閥值的時候就不在消費隊列,並關閉購買功能。這就解決了超賣問題。

優點:解決超賣問題,略微提升性能。

缺點:性能受限於隊列處理機處理性能和DB的寫入性能中最短的那個,另外多商品同時搶購的時候需要準備多條隊列。

解決方案3:

將寫操作前移到MC中,同時利用MC的輕量級的鎖機制CAS來實現減庫存操作。

優點:讀寫在內存中,操作性能快,引入輕量級鎖之後可以保證同一時刻只有一個寫入成功,解決減庫存問題。

缺點:沒有實測,基於CAS的特性不知道高併發下是否會出現大量更新失敗?不過加鎖之後肯定對併發性能會有影響。

解決方案4:

將提交操作變成兩段式,先申請後確認。然後利用Redis的原子自增操作(相比較MySQL的自增來說沒有空洞),同時利用Redis的事務特性來發號,保證拿到小於等於庫存閥值的號的人都可以成功提交訂單。然後數據異步更新到DB中。

優點:解決超賣問題,庫存讀寫都在內存中,故同時解決性能問題。

缺點:由於異步寫入DB,可能存在數據不一致。另可能存在少買,也就是如果拿到號的人不真正下訂單,可能庫存減爲0,但是訂單數並沒有達到庫存閥值。

參考文章


本文作者: catalinaLi
本文鏈接: http://catalinali.top/2019/solveConcurrency/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章