<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
秒殺業務特點:限時限量,業務系統要處理瞬時高並行請求,Redis是必需品。
秒殺可分成秒殺前、秒殺中和秒殺後三階段,每個階段的請求處理需求不同,Redis具體在秒殺場景的哪個環節起到作用呢?
秒殺商品的庫存量<<購買該商品的使用者數,且會限定使用者只能在一定時間段內購買。
這給秒殺系統帶來兩個明顯負載特徵:
一般DB每秒只能支撐k級並行,而Redis並行能達到w級。所以,當大量並行請求湧入秒殺系統時,要使用Redis先攔截大部分請求,避免大量請求直接發給DB
讀還是簡單的查詢操作。秒殺下,使用者需先查驗商品是否還有庫存(即根據商品ID查詢該庫存量),只有庫存有餘量時,秒殺系統才能進行庫存扣減、下單。可本地快取儲存庫存是否為 0 的標識,避免再請求 redis。
庫存查驗操作是典型KV查詢,Redis正滿足。但秒殺只有小部分使用者能成功下單,所以:
商品庫存查詢操作(讀操作)>>庫存扣減、下單操作(寫操作)
一般把秒殺活動分成三個階段:
使用者不斷重新整理商品詳情頁,導致詳情頁瞬時請求量猛增。
一般儘量靜態化商品詳情頁的頁面元素,然後使用CDN或瀏覽器快取這些靜態化元素。
秒殺前的大量請求可直接由CDN或瀏覽器快取服務,不會到達伺服器端。
大量使用者點選商品詳情頁上的秒殺按鈕,會產生大量的並行請求查詢庫存。一旦某個請求查詢到有庫存,緊接著系統就會進行庫存扣減。然後,系統會生成實際訂單,並進行後續處理,例如訂單支付和物流服務。如果請求查不到庫存,就會返回。使用者通常會繼續點選秒殺按鈕,繼續查詢庫存。
該階段主要操作:
每個秒殺請求都會查詢庫存,而請求只有查到有庫存餘量,後續的庫存扣減和訂單處理才會被執行。所以,該階段最大並行壓力在庫存查驗。就需使用Redis儲存庫存量,請求直接從Redis讀庫存並查驗。
庫存扣減和訂單處理是否都可交給後端DB執行?
訂單處理可在DB執行,但庫存扣減操作,不能交給DB。
為何非在DB處理訂單呢?
訂單處理涉及支付、商品出庫、物流等多個關聯操作,這些操作本身涉及DB中的多張表,要保證事務性,需在DB完成。
訂單處理時,請求壓力已不大,DB完全可支撐。
為啥庫存扣減操作不能在DB執行
一旦請求查到有庫存,即傳送該請求的使用者獲得商品購買資格,使用者就會下單了。同時,商品庫存餘量也需-1。
若把庫存扣減的操作放到DB,會帶來風險:
額外開銷
Redis儲存庫存量,而庫存量最新值又是DB在維護,所以DB更新後,還要和Redis進行同步,這增加額外操作邏輯
下單量>實際庫存量,超賣!
由於DB處理效能較慢,無法及時更新庫存餘量,可能導致大量庫存查驗請求讀到舊庫存值,並下單。就會出現下單數量>實際庫存量,導致超賣
所以,要在Redis進行庫存扣減:
秒殺中需要Redis參與的兩個環節:
該階段,可能還有部分使用者重新整理商品詳情頁,嘗試等待有其他使用者退單。而已成功下單的使用者會重新整理訂單詳情,跟蹤訂單進度。
不過,此階段的使用者請求量已下降很多,伺服器端一般都能支撐。
Redis先天支援。且若有多個秒殺商品,也可使用切片叢集,用不同範例儲存不同商品的庫存,避免使用單範例導致所有秒殺請求都集中在一個範例。
使用切片叢集時,先CRC計算不同秒殺商品K對應Slot,然後在分配Slot和範例對應關係時,才能把不同秒殺商品對應的Slot分配到不同範例儲存。
使用Redis的原子操作或分散式鎖。
秒殺中的一個商品的庫存對應兩個資訊:
這種資料模型正好一個key(商品ID)對應兩個屬性(總庫存量和已秒殺量),可用Hash儲存:
key: itemID value: {total: N, ordered: M}
itemID 商品編號total,總庫存量ordered,已秒殺量
因為庫存查驗、庫存扣減這兩個操作要保證一起執行,一個直接的方法就是使用Redis的原子操作。
庫存查驗、庫存扣減是兩個操作,需Lua指令碼保證原子執行:
#獲取商品庫存資訊 local counts = redis.call("HMGET", KEYS[1], "total", "ordered"); #將總庫存轉換為數值 local total = tonumber(counts[1]) #將已被秒殺的庫存轉換為數值 local ordered = tonumber(counts[2]) #如果當前請求的庫存量加上已被秒殺的庫存量仍然小於總庫存量,就可以更新庫存 if ordered + k <= total then #更新已秒殺的庫存量 redis.call("HINCRBY",KEYS[1],"ordered",k) return k; end return 0
然後就能在Redis使用者端,使用EVAL命令執行指令碼。使用者端根據指令碼返回值,確定秒殺是否成功:
讓使用者端向Redis申請分散式鎖,拿到鎖的使用者端才能執行庫存查驗、庫存扣減。
這樣大量秒殺請求就會在爭奪分散式鎖時被過濾掉。
庫存查驗、扣減也不用原子操作了,因為多個並行使用者端只有一個使用者端能夠拿到鎖,已保證使用者端並行存取的互斥性。
// 使用商品ID作為key key = itemID // 使用使用者端唯一標識作為value val = clientUniqueID //申請分散式鎖,Timeout是超時時間 lock =acquireLock(key, val, Timeout) //當拿到鎖後,才能進行庫存查驗和扣減 if(lock == True) { //庫存查驗和扣減 availStock = DECR(key, k) //庫存已經扣減完了,釋放鎖,返回秒殺失敗 if (availStock < 0) { releaseLock(key, val) return error } //庫存扣減成功,釋放鎖 else{ releaseLock(key, val) //訂單處理 } } //沒有拿到鎖,直接返回 else return
使用分散式鎖時,使用者端要先向Redis請求鎖,只有請求到鎖,才能進行庫存查驗等操作,這樣使用者端在爭搶分散式鎖時,大部分秒殺請求本身就會因為搶不到鎖而被攔截。
推薦使用切片叢集中的不同範例來分別儲存分散式鎖和商品庫存資訊。秒殺請求會先存取儲存分散式鎖的範例。若使用者端沒拿到鎖,這些使用者端就不會查詢商品庫存,減輕儲存庫存資訊的範例的壓力。
秒殺系統是個系統性工程,Redis實現對庫存查驗、扣減環節的支撐。
此外,還有環節需要處理:
前端靜態頁面的設計
秒殺頁面上能靜態化處理的頁面元素,要儘量靜態化,充分利用CDN或瀏覽器快取服務秒殺開始前的請求
請求攔截和流控
在秒殺系統的接入層,對惡意請求進行攔截,避免對系統的惡意攻擊,例如使用黑名單禁止惡意IP進行存取。如果Redis範例的存取壓力過大,為了避免範例崩潰,我們也需要在接入層進行限流,控制進入秒殺系統的請求數量。
庫存資訊過期時間處理
Redis中儲存的庫存資訊其實是資料庫的快取,為了避免快取擊穿問題,不要給庫存資訊設定過期時間。
資料庫訂單例外處理。如果資料庫沒能成功處理訂單,可以增加訂單重試功能,保證訂單最終能被成功處理。
資源隔離
秒殺活動帶來的請求流量巨大,我們需要把秒殺商品的庫存資訊用單獨的範例儲存,而不要和日常業務系統的資料儲存在同一個範例上,這樣可以避免干擾業務系統的正常執行。
到此這篇關於淺談Redis在秒殺場景的作用的文章就介紹到這了,更多相關Redis 秒殺內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45