什麼,秒殺系統也有這麼多種!

TIGERB發表於2020-05-12

前言

本文結構很簡單:

5張圖送你5種秒殺系統,再加點騷操作,再順帶些點心裡話?‍♀️。

一個簡單的秒殺系統

實現原理: 通過redis原子操作減庫存

圖一

優點 缺點
簡單好用 考驗redis服務能力
是否公平
公平
先到先得

我們稱這類秒殺系統為:

簡單秒殺系統

如果剛開始QPS並不高,redis完全抗的下來的情況,完全可以依賴這個「簡單秒殺系統」。

一個夠用的秒殺系統

實現原理: 服務記憶體限流演算法 + redis原子操作減庫存

圖二

優點 缺點
簡單好用 -
是否公平
不是很公平
相對的先到先得

我們稱這類秒殺系統為:

夠用秒殺系統

效能再好點的秒殺系統

實現原理: 服務本地記憶體原子操作減庫存

服務本地記憶體的庫存怎麼來的?

活動開始前分配好每臺機器的庫存,推送到機器上。

圖三

優點 缺點
高效能 不支援動態伸縮容(活動進行期間),因為庫存是活動開始前分配好的
釋放redis壓力 -
是否公平
不是很公平
不是絕對的先到先得

我們稱這類秒殺系統為:

預備庫存秒殺系統

支援動態伸縮容的秒殺系統

實現原理: 服務本地協程Coroutine定時redis原子操作減部分庫存到本地記憶體 + 服務本地記憶體原子操作減庫存

圖四

優點 缺點
高效能 支援動態伸縮容(活動進行期間)
釋放redis壓力 -
具備通用性 -
是否公平
不是很公平,但是好了點
幾乎先到先得

我們稱這類秒殺系統為:

實時預備庫存秒殺系統

公平的秒殺系統

實現原理: 服務本地Goroutine定時同步是否售罄到本地記憶體 + 佇列 + 排隊成功輪訓(或主動Push)結果

圖五

優點 缺點
高效能 開發成本高(需主動通知或輪訓排隊結果)
真公平 -
具備通用性 -
是否公平
很公平
絕對的先到先得

我們稱這類秒殺系統為:

公平排隊秒殺系統

騷操作

上面的秒殺系統還不夠完美嗎?

答案:是的。

還有什麼優化的空間?

答案:靜態化獲取秒殺活動資訊的介面。

靜態化是什麼意思?

答案:比如獲取秒殺活動資訊是通過介面 https://seckill.skrshop.tech/v1/acticity/get 獲取的。現在呢,我們需要通過https://static-api.skrshop.tech/seckill/v1/acticity/get 這個介面獲取。有什麼區別呢?看下面:

服務名 介面 資料儲存位置
秒殺服務 https://seckill.skrshop.tech/... 秒殺服務記憶體或redis等
介面靜態化服務 https://static-api.skrshop.te... CDN、本地檔案

以前是這樣

變成了這樣

結果:可以通過介面https://static-api.skrshop.tech/seckill/v1/acticity/get就獲取到了秒殺活動資訊,流量都分攤到了cdn,秒殺服務自身沒了這部分的負載。

小聲點說:“秒殺結果我也敢推CDN???。”
備註:
之後我們會分享`如何用Golang設計一個好用的「介面靜態化服務」`。

總結

上面我們得到了如下幾類秒殺系統

秒殺系統
簡單秒殺系統
夠用秒殺系統
預備庫存秒殺系統
實時預備庫存秒殺系統
公平排隊秒殺系統

我想說的是裡面沒有最好的方案,也沒有最壞的方案,只有適合你的。

先到先得來說,一定要看你們的產品對外宣傳,切勿上來就追逐絕對的先到先得。其實你看所有的方案,相對而言都是“先到先得”,比如,活動開始一個小時了你再來搶,那相對於準時的使用者自然搶不過,對吧。

又如預備庫存秒殺系統,雖然不支援動態伸縮容。但是如果你的環境滿足如下任意條件,就完全夠用了。

  • 秒殺場景結束時間之快,通常幾秒就結束了,真實活動可能會發生如下情況:

    • 服務壓力大還沒掛:根本就來不及動態伸縮容
    • 服務壓力大已經掛了:可以先暫停活動,服務起來&擴容結束,用剩餘庫存重新推送
  • 運維自身不具備動態伸縮容的能力

所以:

合適好用就行,切勿過度設計。

最後

這次算是把老本都吐露出來了,真是慌得一匹。


SkrShop歷史分享:https://github.com/skr-shop/m...

3911642037-d2bb08d8702e7c91_articlex.jpg

相關文章