1. 程式人生 > >使用 Redis 搭建電商秒殺系統

使用 Redis 搭建電商秒殺系統

背景

秒殺活動是絕大部分電商選擇的低價促銷、推廣品牌的方式。不僅可以給平臺帶來使用者量,還可以提高平臺知名度。一個好的秒殺系統,可以提高平臺系統的穩定性和公平性,獲得更好的使用者體驗,提升平臺的口碑,從而提升秒殺活動的最大價值。

本文討論雲資料庫 Redis 版快取設計高併發的秒殺系統。

秒殺的特徵

秒殺活動對稀缺或者特價的商品進行定時定量售賣,吸引成大量的消費者進行搶購,但又只有少部分消費者可以下單成功。因此,秒殺活動將在較短時間內產生比平時大數十倍,上百倍的頁面訪問流量和下單請求流量。

秒殺活動可以分為3個階段:

  • 秒殺前:使用者不斷重新整理商品詳情頁,頁面請求達到瞬時峰值。

  • 秒殺開始:使用者點選秒殺按鈕,下單請求達到瞬時峰值。

  • 秒殺後:一部分成功下單的使用者不斷重新整理訂單或者產生退單操作,大部分使用者繼續重新整理商品詳情頁等待退單機會。

消費者提交訂單,一般做法是利用資料庫的行級鎖,只有搶到鎖的請求可以進行庫存查詢和下單操作。但是在高併發的情況下,資料庫無法承擔如此大的請求,往往會使整個服務 blocked,在消費者看來就是伺服器宕機。

秒殺系統

系統架構圖

秒殺系統的流量雖然很高,但是實際有效流量是十分有限的。利用系統的層次結構,在每個階段提前校驗,攔截無效流量,可以減少大量無效的流量湧入資料庫。

利用瀏覽器快取和 CDN 抗壓靜態頁面流量

秒殺前,使用者不斷重新整理商品詳情頁,造成大量的頁面請求。所以,我們需要把秒殺商品詳情頁與普通的商品詳情頁分開。對於秒殺商品詳情頁儘量將能靜態化的元素靜態化處理,除了秒殺按鈕需要服務端進行動態判斷,其他的靜態資料可以快取在瀏覽器和 CDN 上。這樣,秒殺前重新整理頁面導致的流量進入服務端的流量只有很小的一部分。

利用讀寫分離 Redis 快取攔截流量

CDN 是第一級流量攔截,第二級流量攔截我們使用支援讀寫分離的 Redis。在這一階段我們主要讀取資料,讀寫分離 Redis 能支援高大60萬以上 qps 的,完全可以支援需求。

首先通過資料控制模組,提前將秒殺商品快取到讀寫分離 Redis,並設定秒殺開始標記如下:

  1. "goodsId_count":100//總數
  2. "goodsId_start":0//開始標記
  3. "goodsId_access":0//接受下單數
  1. 秒殺開始前,服務叢集讀取 goodsId_Start 為 0,直接返回未開始。

  2. 資料控制模組將 goodsId_start 改為1,標誌秒殺開始。

  3. 服務叢集快取開始標記位並開始接受請求,並記錄到 redis 中 goodsId_access,商品剩餘數量為(goodsId_count - goodsId_access)。

  4. 當接受下單數達到 goodsId_count 後,繼續攔截所有請求,商品剩餘數量為 0。

可以看出,最後成功參與下單的請求只有少部分可以被接受。在高併發的情況下,允許稍微多的流量進入。因此可以控制接受下單數的比例。

利用主從版 Redis 快取加速庫存扣量

成功參與下單後,進入下層服務,開始進行訂單資訊校驗,庫存扣量。為了避免直接訪問資料庫,我們使用主從版 Redis 來進行庫存扣量,主從版 Redis 提供10萬級別的 QPS。使用 Redis 來優化庫存查詢,提前攔截秒殺失敗的請求,將大大提高系統的整體吞吐量。

通過資料控制模組提前將庫存存入 Redis,將每個秒殺商品在 Redis 中用一個 hash 結構表示。

  1. "goodsId":{
  2. "Total":100
  3. "Booked":100
  4. }

扣量時,伺服器通過請求 Redis 獲取下單資格,通過以下 lua 指令碼實現,由於 Redis 是單執行緒模型,lua 可以保證多個命令的原子性。

  1. local n = tonumber(ARGV[1])
  2. ifnot n or n ==0then
  3. return0
  4. end
  5. local vals = redis.call("HMGET", KEYS[1],"Total","Booked");
  6. local total = tonumber(vals[1])
  7. local blocked = tonumber(vals[2])
  8. ifnot total ornot blocked then
  9. return0
  10. end
  11. if blocked + n <= total then
  12. redis.call("HINCRBY", KEYS[1],"Booked", n)
  13. return n;
  14. end
  15. return0

先使用SCRIPT LOAD將 lua 指令碼提前快取在 Redis,然後呼叫EVALSHA呼叫指令碼,比直接呼叫EVAL節省網路頻寬:

  1. redis 127.0.0.1:6379>SCRIPT LOAD "lua code"
  2. "438dd755f3fe0d32771753eb57f075b18fed7716"
  3. redis 127.0.0.1:6379>EVAL 438dd755f3fe0d32771753eb57f075b18fed77161 goodsId 1

秒殺服務通過判斷 Redis 是否返回搶購個數 n,即可知道此次請求是否扣量成功。

使用主從版 Redis 實現簡單的訊息佇列非同步下單入庫

扣量完成後,需要進行訂單入庫。如果商品數量較少的時候,直接操作資料庫即可。如果秒殺的商品是1萬,甚至10萬級別,那資料庫鎖衝突將帶來很大的效能瓶頸。因此,利用訊息佇列元件,當秒殺服務將訂單資訊寫入訊息佇列後,即可認為下單完成,避免直接操作資料庫。

  1. 訊息佇列元件依然可以使用 Redis 實現,在 R2 中用 list 資料結構表示。

    1. orderList {
    2. [0]={訂單內容}
    3. [1]={訂單內容}
    4. [2]={訂單內容}
    5. ...
    6. }
  2. 將訂單內容寫入 Redis:

    1. LPUSH orderList {訂單內容}
  3. 非同步下單模組從 Redis 中順序獲取訂單資訊,並將訂單寫入資料庫。

    1. BRPOP orderList 0

通過使用 Redis 作為訊息佇列,非同步處理訂單入庫,有效的提高了使用者的下單完成速度。

資料控制模組管理秒殺資料同步

最開始,利用讀寫分離 Redis 進行流量限制,只讓部分流量進入下單。對於下單檢驗失敗和退單等情況,需要讓更多的流量進來。因此,資料控制模組需要定時將資料庫中的資料進行一定的計算,同步到主從版 Redis,同時再同步到讀寫分離的 Redis,讓更多的流量進來。

相關推薦

使用 Redis 搭建系統

背景 秒殺活動是絕大部分電商選擇的低價促銷、推廣品牌的方式。不僅可以給平臺帶來使用者量,還可以提高平臺知名度。一個好的秒殺系統,可以提高平臺系統的穩定性和公平性,獲得更好的使用者體驗,提升平臺的口碑,從而提升秒殺活動的最大價值。 本文討論雲資料庫 Redis 版快取設計高併發的秒殺系統。 秒殺的特徵

阿里雲Redis讀寫分離典型場景:如何輕鬆搭建系統

背景 秒殺活動是絕大部分電商選擇的低價促銷,推廣品牌的方式。不僅可以給平臺帶來使用者量,還可以提高平臺知名度。一個好的秒殺系統,可以提高平臺系統的穩定性和公平性,獲得更好的使用者體驗,提升平臺的口碑,從而提升秒殺活動的最大價值。 本次主要討論阿里云云資料庫Redis

解密 Redis 助力雙十一背後系統

秒殺活動是絕大部分電商選擇的低價促銷、推廣品牌的方式。不僅可以給平臺帶來使用者量,還可以提高平臺知名度。一個好的秒殺系統,可以提高平臺系統的穩定性和公平性,獲得更好的使用者體驗,提升平臺的口碑,從而提升秒殺活動的最大價值。 本文討論如何利用 Redis 快取設計高併發的秒殺系統。 秒殺的特徵 秒殺活動對

php+redis實現功能

str 數組 ash 參數設置 *** this 百萬 對數 現在 這一次總結和分享用Redis實現分布式鎖來完成電商的秒殺功能。先扯點個人觀點,之前我看了一篇博文說博客園的文章大部分都是分享代碼,博文裏強調說分享思路比分享代碼更重要(貌似大概是這個意思,若有誤請諒解),

淘寶雙十一系統架構設計

前言 最近在部門內部分享了原來在電商業務做秒殺活動的整體思路,大家對這次分享反饋還不錯,所以我就簡單整理了一下,分享給大家參考參考 業務介紹 什麼是秒殺?通俗一點講就是網路商家為促銷等目的組織的網上限時搶購活動 比如說京東秒殺,就是一種定時定量秒殺,在規定的時間內

【問底】徐漢彬:Web系統大規模並發——與搶購

應對 安全 參加 出現 早期 上下文切換 方法 真實用戶 機會 摘要:電商的秒殺和搶購,從技術的角度來說,會對Web系統產生巨大的考驗。本期《問底》,徐漢彬將帶大家關註秒殺和搶購的技術實現和優化,同時,從技術層面揭開,為什麽我們總是不容易搶到火車票的原因。 【導讀】徐漢彬曾

Spring Boot實戰 -- 1.基礎環境搭建

記錄學習總結 目標: 1.掌握Spring Boot環境搭建 2.掌握Lombok的整合使用 2.掌握Thymeleaf整合,Result結果封裝 3.掌握Mybatis+Druid整合 4.掌握Jedis整合+通用快取Key封裝 文章總體目錄 Sprin

Redis輕松實現系統

tar 幫助 說過 腳本 .net 所有 paxos 你會 用戶 秒殺系統的架構設計 秒殺系統,是典型的短時大量突發訪問類問題。對這類問題,有三種優化性能的思路: 寫入內存而不是寫入硬盤 異步處理而不是同步處理 分布式處理 用上這三招,不論秒殺時負載多大,都能輕松應對。

redis 8 做個系統

###秒殺的要點 對流量進行控制,逐步減少流量,使得最終到介面的流量是較小的。(流量控制不是說不要使用者訪問,而是對流量進行引導,保證有效請求的最大化) 儘量不要用鎖,鎖就意味著資源的內耗 整個過程可以分秒殺前,秒殺時,秒殺後三個步驟來思考,每一步都解耦出來。

Redis分散式鎖 實現系統 SET命令實現

基於Redis命令:SET key valueNX EX max-lock-time   可適用於redis單機和redis叢集模式 1.SET命令是原子性操作,NX指令保證只要當key不存在時才會設定value 2.設定的value要有唯一性,來確保鎖不會被誤刪(

5w每的高併發優化:與搶購

一、大規模併發帶來的挑戰 在過去的工作中,我曾經面對過5w每秒的高併發秒殺功能,在這個過程中,整個Web系統遇到了很多的問題和挑戰。如果Web系統不做針對性的優化,會輕而易舉地陷入到異常狀態。我們現在一起來討論下,優化的思路和方法哈。1. 請求介面的合理設計 一個秒殺或者搶購頁面,通常分為2個部分,一個是

談談高併發的處理

眾所周知現在連市場賣菜的大媽都快知道高併發了,哈哈,那麼我們生活中是否接觸過高併發呢。當然了哈哈,比如你給你女朋友搶秒殺的化妝品什麼的了。秒殺最棘手的問題就是解決併發帶來的問題。下面我們一起聊聊嘍。 首先我們來說下問題:秒殺高併發帶來的最大問題,就是庫存超賣。(如果你沒看過

小程式自學系列(零基礎學小程式002)---小程式實現倒計時效果

基本實現功能 1,小程式仿電商網站秒殺倒計時 2,顯示格式為:例如 1天11時11分11秒11 3,秒殺時間結束後提示 秒殺結束 先看效果圖 其實實現挺簡單 <!--index.wx

架構 各個具體場景及對應的解決方案

 電商的秒殺和搶購,對我們來說,都不是一個陌生的東西。然而,從技術的角度來說,這對於Web系統是一個巨大的考驗。當一個Web系統,在一秒鐘內收到數以萬計甚至更多請求時,系統的優化和穩定至關重要。這次我們會關注秒殺和搶購的技術實現和優化,同時,從技術層面揭開,為什麼我們總

庫存問題

先來就庫存超賣的問題作描述:一般電子商務網站都會遇到如團購、秒殺、特價之類的活動,而這樣的活動有一個共同的特點就是訪問量激增、上千甚至上萬人搶購一個商品。然而,作為活動商品,庫存肯定是很有限的,如何控制庫存不讓出現超買,以防止造成不必要的損失是眾多電子商務網站程式設計師

活動的技術分析

秒殺活動是絕大部分電商選擇的低價促銷、推廣品牌的方式。不僅可以給平臺帶來使用者量,還可以提高平臺知名度。一個好的秒殺系統,可以提高平臺系統的穩定性和公平性,獲得更好的使用者體驗,提升平臺的口碑,從而提升秒殺活動的最大價值。 這裡使用redis來處理秒殺活動。 秒殺的特徵:

大型車禍現場,超賣,這個鍋到底有誰來背?

背景 小明在一家線上購物商城工作,最近來了一個新需求,需要他負責開發一個商品秒殺模組,而且需求很緊急,老闆要求必須儘快上線。 方案 小明一開始是這麼做的,直接用資料庫鎖進行控制,獲取秒殺商品數量並加鎖,如果數量大於零則成功,否則秒殺失敗。 @Override @Transactional

 系統 設計思路和實現方法

1 秒殺業務分析 正常電子商務流程 (1)查詢商品;(2)建立訂單;(3)扣減庫存;(4)更新訂單;(5)付款;(6)賣家發貨 秒殺業務的特性 (1)低廉價格;(2)大幅推廣;(3)瞬時售空;(4)一般是定時上架;(5)時間短、瞬時併發量高; 2

redis樂觀鎖(適用於系統

修改 導致 代碼 -a 通知 解決 redis服務器 font 變化 redis事務中的WATCH命令和基於CAS的樂觀鎖 在Redis的事務中,WATCH命令可用於提供CAS(check-and-set)功能。假設我們通過WATCH命令在事務執行之前監控了多個Keys,

Python Django 集成Redis Sentinel(哨兵)集群開發系統

django nginx redis集群 sentinel集群 gunicorn django 我們知道秒殺系統最大特點是瞬時高並發、高訪問量的系統。我們還要保證它的高可用性。這裏我們采用Python Django 集成Redis Sentinel(哨兵)集群開發秒殺系統。 Redis S