用 Node.js + Redis 解決高併發秒殺問題

林鼎淵
Dean Lin
Published in
4 min readAug 18, 2021

--

商城在高併發環境下除了要考量到使用者體驗外,還要處理「超賣」的問題;Redis 是一種記憶體資料庫,它有高讀寫效率的特性、能承受高 qps,而這篇文章則是運用它獨特的「鎖」解決超賣問題。

大綱一、文章目標二、使用技術
➤ Redis
➤ Lua
三、程式架構
➤ 主程式:redisSecKill.js
➤ Lua腳本:secKill.lua
四、執行結果五、補充

一、文章目標

  1. 產生秒殺商品基礎資訊(商品名稱、庫存)
  2. 模擬秒殺情境,確認是否會超賣
  3. 確認有保存購買人資訊

二、使用技術

➤ Redis

  1. 如果完全沒有相關基礎,建議先參考這篇文章來安裝 Redis 以及他的 GUI 工具
  2. 本篇文章使用 Redis 的 Hash、List type 來儲存資訊

➤ Lua

  1. 為了避免超賣,這裡採用 Lua 腳本
  2. 在 Redis Server 執行 EVAL 指令時,在結果回傳前只會執行當下 Lua 腳本的邏輯,其他 Client 端的命令須等待直到 EVAL 執行完為止。

Lua 腳本的邏輯應盡量簡單以保證執行效率,否則會影響 Client 端的體驗

三、程式架構

➤ 主程式:redisSecKill.js

  1. 先啟用 Redis Client 端(如未安裝相關套件,請在專案資料夾下輸入 yarn add ioredis
  2. prepare 函式,以 Hash type 建立參加秒殺的產品庫存
  3. secKill 函式模擬使用者購買行為,緩存並執行 Lua 腳本

➤ Lua 腳本:secKill.lua

在 Lua 腳本執行「取得商品庫存」➜「如果庫存足夠就-1」➜「儲存購買者資訊(List type)」

四、執行結果

SETP 1:在專案資料夾下輸入 node redisSecKill.js 模擬秒殺

SETP 2:待執行完後,用 Redis GUI 程式確認商品沒有超賣

SETP 3:確認訂單都有對應的買家

五、補充

上面程式只是 MVP,現實狀況還有很多要討論的:

  1. 哪些商品被列為秒殺,如何紀錄
  2. 設定秒殺開始時間、結束時間
  3. 存在 Redis 的資料怎麼存入關連式資料庫中
如果你對 Redis 感興趣,筆者這邊也整理了很多相關資源:1. 一文讓你徹底瞭解 Redis(進階),史上最全,不看後悔!!!【建議收藏】2. 【总结】瞬时高并发(秒杀/活动)Redis 方案3. redis 之 sorted sets 类型及操作4. node.js 中对 redis 的安装和基本操作5. Node.js 中实践 Redis Lua 脚本6. 使用 Redis 搭建电商秒杀系统

筆者也是剛學習 Redis 的新人,如果描述有誤,或是有更好的解決方式,再麻煩大神們不吝賜教,感謝~

▶︎ 如果這篇文章有幫助到你1. 可以點擊下方「Follow」來追蹤我~
2. 可以對文章拍手讓我知道 👏🏻
你們的追蹤與鼓勵是我繼續寫作的動力 🙏🏼▶︎ 如果你對工程師的職涯感到迷茫1. 也許我在iT邦幫忙發表的系列文可以給你不一樣的觀點 💡
2. 也歡迎您到書局選購支持,透過豐富的案例來重新檢視自己的職涯

--

--

林鼎淵
Dean Lin

職涯中培育過多名工程師,🧰 目前在外商公司擔任 Software Specialist |✍️ 我專注寫 (1)最新技術 (2)團隊合作 (3)工程師職涯的文章,出版過 5 本專業書籍|👏🏻 如果對這些主題感興趣,歡迎點擊「Follow」來關注我~