Redis+分散式+秒殺

来源:https://www.cnblogs.com/kuangsun125/archive/2023/05/29/17441451.html
-Advertisement-
Play Games

## 聊一下MySQL 關於mysql關係型資料庫的一些分析: 1、從性能上:如果我們碰到需要執行耗時特別久,並且執行結果不是很頻繁變動的SQL語句,我們就沒有必要每次都去查詢資料庫,因為每次操作資料庫都很耗時。 2、從併發上:在大併發的情況下(比如618秒殺活動,你敢讓千萬級的請求直接打到資料庫上 ...


聊一下MySQL

關於mysql關係型資料庫的一些分析:

1、從性能上:如果我們碰到需要執行耗時特別久,並且執行結果不是很頻繁變動的SQL語句,我們就沒有必要每次都去查詢資料庫,因為每次操作資料庫都很耗時。

2、從併發上:在大併發的情況下(比如618秒殺活動,你敢讓千萬級的請求直接打到資料庫上嗎?)所有的請求直接訪問資料庫,資料庫就由可能造成宕機。

Redis

針對第一種情況,可以將不那麼頻繁變換的結果放入基於緩存的資料庫中,每次查詢就去緩存中讀數據,這樣就提升了查詢效率,也減輕了資料庫的壓力。

針對第二種情況,可以讓這些高併發的請求從資料庫中分離出來,不去直接訪問資料庫,另外找一個適合高併發的來處理請求。

那就是Redis!!!

是什麼?

  • 基於記憶體的K/V存儲中間件(關於K/V你還能想到誰?)
  • NoSQL(非關係型)資料庫

幹啥用?

  • 緩存

(將熱點數據放到記憶體中,設置記憶體的最大使用量以及淘汰策略來保證緩存的命中率)

  • 設置定時過期數據
  • 分散式鎖

(在分散式場景下,無法使用單機環境下的鎖來對多個節點上的進程進行同步。可以使用 Redis 自帶的 SETNX 命令實現分散式鎖)

  • 抽獎功能
  • 實現排行榜
  • .......

面試題:1、redis常見的數據結構有哪些?

2、Redis持久化瞭解麽?

秒殺場景

618預熱早已開啟,其中必不可少的秒殺是一個非常典型的活動場景。比如,在雙 11、618 等電商促銷活動中,都會有秒殺場景。秒殺場景的業務特點是限時限量,業務系統要處理瞬時的大量高併發請求。在秒殺活動中,大量用戶在同一時間視窗內搶購限量商品,這往往會給系統帶來極高的併發壓力。使用傳統的關係型資料庫來處理併發請求往往會導致性能瓶頸和系統崩潰。而Redis作為一種高性能的記憶體資料庫,能夠快速處理大量的讀寫請求,非常適合用於秒殺場景。

秒殺的特征一:瞬時併發訪問量非常高。一般資料庫只能支撐千級別的併發請求,而redis的併發處理能力能達到萬級別,甚至更高。在秒殺時,我們需要使用redis攔截大部分請求,避免大量請求直接發送給資料庫,造成資料庫宕機。

秒殺的特征二:讀多寫少,都是簡單的查詢操作。對於簡單的查詢操作並且結果相對固定我們可以先將其查詢出來放入redis中,減輕資料庫的壓力。秒殺活動中只有少部分用戶能成功下單,所以,商品庫存查詢操作(讀操作)要遠多於庫存扣減和下單操作(寫操作)。

秒殺的特征三:實時性和響應時間要求。 秒殺活動通常是實時進行的,用戶希望儘快得知搶購結果。系統需要具備高性能和低延遲,及時響應用戶的請求。

三個階段

秒殺前

秒殺前,用戶會不斷的刷新商品詳情頁,那麼就會導致對詳情頁的請求量急劇增加。這個階段的應對方案,一般是儘量把商品詳情頁的頁面元素靜態化,然後使用 CDN 或是瀏覽器把這些靜態化的元素緩存起來。這樣一來,秒殺前的大量請求可以直接由 CDN 或是瀏覽器緩存服務,不會到達伺服器端了。

秒殺時

用戶點擊秒殺按鈕---->大量併發請求查詢庫存--->有庫存(下單){沒有則返回,可能會點擊其他秒殺按鈕,繼續查詢庫存}--->庫存扣減---->生成實際訂單---->後續處理(物流、訂單支付等)

這個階段的操作是:庫存查驗、庫存扣減、訂單處理。而最大的併發力都在庫存查驗操作上。這個階段為了支撐大量高併發的庫存查驗請求,我們需要在這個環節使用 Redis 保存庫存量,這樣一來,請求可以直接從 Redis 中讀取庫存併進行查驗。

為什麼訂單處理操作可以在資料庫中執行?而庫存扣減操作不能在資料庫中執行?

1、在資料庫中進行庫存扣減操作會帶來額外的開銷。我們已經事先在redis中保存好了庫存量,如果交給資料庫來處理扣減,那麼就需要資料庫將最新的值再同步到redis中,這樣反而繁瑣也帶來了額外的開銷。

2、可能會出現超售的情況。資料庫的處理速度很慢,而秒殺又是一個快速高併發的場景,可能資料庫更新完一個庫值,秒殺就結束了,可能會導致用戶查詢到舊的庫存值,再進行下單,出現超售的情況。

所以需要在redis中把庫存扣減和庫存查驗兩個操作一氣呵成,實現原子操作。

秒殺後

用戶量減少,伺服器完全可以獨立進行訂單處理等操作。

實現

我們可以使用Redis的原子操作和分散式鎖來支撐秒殺時的場景。(本文介紹分散式鎖)

簡單聊聊分散式

簡單理解:類比衛生間的隔間:

  1. 隔離性: 衛生間的隔間將每個使用者隔離開來,使每個人都能獨立使用空間,不會相互干擾。同樣,分散式系統中的各個節點也是相互隔離的,它們可以獨立運行,不會相互影響。
  2. 資源共用: 衛生間的隔間提供共用的基礎設施,如水源和排水管道等。類似地,分散式系統中的節點可以共用一些資源,如共用存儲、共用資料庫等。
  3. 容錯性: 如果一個衛生間隔間出現故障或需要維護,其他隔間仍然可以繼續使用。同樣,分散式系統中的節點之間可以具備容錯能力,如果某個節點發生故障,其他節點可以接替其工作。
  4. 擴展性: 如果需要更多的衛生間隔間,可以增加更多的隔間來滿足需求。同樣,分散式系統可以通過增加更多的節點來實現擴展性,以處理更大的負載和流量。

Redis分散式鎖(秒殺場景)

先讓客戶端向 Redis 申請分散式鎖,只有拿到鎖的客戶端才能執行庫存查驗和庫存扣減。這樣一來,大量的秒殺請求就會在爭奪分散式鎖時被過濾掉。而且,庫存查驗和扣減也不用使用原子操作了,因為多個併發客戶端只有一個客戶端能夠拿到鎖,已經保證了客戶端併發訪問的互斥性。大部分秒殺請求本身就會因為搶不到鎖而被攔截。

為啥要實現分散式鎖:

  • 在有限的資源情況下,控制同一時間(段)只有某些線程(用戶/伺服器)能訪問到資源。(比如秒殺時)
  • 單個鎖只對單個jvm有限(好比用廁所只能用專屬於自己的哪個)

關鍵:怎麼保證同一時間內只有一個伺服器搶到鎖。

核心思想是:先來的人先把數據改成自己的標識(ip)後來的人發現標識已存在,就搶鎖失敗,繼續等待,等先來的人執行方法結束,把標識清空,其他的人繼續搶鎖。(類比搶廁所/上廁所 )

註意事項:

  • 要註意解鎖(你不可能一直占著廁所吧!!!)。
  • 一定要註意加上過期時間(否則如果因為伺服器掛掉,鎖就會一直存在了)。

使用分散式鎖可能存在的問題

1、鎖提前過期:分散式鎖設置的時間提前過期,會導致其他方法加入一塊同時執行。(好比你拉*沒拉完,外面大哥把廁所門給撬開了)導致多個方法同時執行了。

2、還有可能導致連鎖效應(解鎖時不小心釋放掉別人的鎖)同樣導致多個方法同時執行。

3、解鎖的時候,判斷好了是自己的鎖,但是當要執行解鎖的時候,就在這個時刻,自己的鎖過期了(不需要刪了)有其他的方法見縫插針進來了,導致A刪了B的鎖。(就像是你用完廁所,你自己的門鎖時間過期開了,你手裡還有把解鎖的“鑰匙”,結果你打開了旁邊大哥的門)這裡其實是破壞了原子性。(需要保證A的操作是原子性的,不能有其他操作打斷。(也就是說A的上鎖和解鎖中間不能有其他的鎖操作)跟操作系統的PV操作好像)。

4、鎖提前過期,任務還沒執行完,可以進行續期。(就像你上廁所,外面大哥等了你10min,結果你還沒完事,然後你跟大哥說再給我10min)進行續期。

關於redis在秒殺場景中的應用還有很多,這隻是一丟丟~

場景題

1、如何防止超賣問題?

2、如何保證訂單的順序和可靠性?

3、如何解決重覆下單的問題?

4、做了什麼限流削峰的措施?

5、如果緩存中的數據突然失效,導致請求全部打到了資料庫,怎麼辦?

6、秒殺系統面臨的問題有哪些?

........

博客參考

實踐篇(11)Redis支撐秒殺場景的關鍵技術

知識星球


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 技術架構師,將整間企業的IT開發流程至維運管理,視為一個大型系統進行規劃。並分為四個面向進行發展: - [開發平臺]:構建高度重用的共用模組和服務,並在多個專案項目和應用系統中使用,以提高開發效率並降低維護成本。 - [DevOps平臺]:建構連續集成、連續交付的工作環境,將開發與維運團隊更緊密地連 ...
  • 本文通過對貧血三層架構進行精煉,推導出適合我們落地的應用架構,並且將之實現為Maven Archetype以應用到實際開發,然而應用架構只是落地DDD的一個知識點,要完整落地DDD還必須體系化地掌握限界上下文、上下文映射、充血模型、實體、值對象、領域服務、Factory、Repository等知識點... ...
  • groovy 3.0.7 ## 代碼實現 ### 實現方式1 ```groovy import java.security.MessageDigest; public class MD5Utils { public final static String MD5(String s) { char[] ...
  • QCustomPlot 是開源項目,源碼編寫十分規範,想要理解它的可視化思路不算特別困難。我在這篇隨筆中總結一下常用的源碼修改技巧,下麵的每一個技巧都是獨立的,不同技巧中添加的代碼無任何依賴關係,相互之間也不會引發任何衝突,不會影響 QCustomPlot 原生的介面。示例中使用的 QCustomP... ...
  • HashMap是Java中常用的數據結構之一,它提供了高效的鍵值對存儲和檢索功能。下麵是HashMap底層的詳細原理介紹: 1. 數據結構:HashMap底層使用數組和鏈表(或紅黑樹)的組合實現。它通過哈希演算法將鍵轉換為數組索引,並將值存儲在對應索引位置上。 2. 哈希演算法:當我們向HashMap中 ...
  • # 常用的排序演算法 ## 一、冒泡排序 冒泡排序(Bubble Sort),是一種較簡單的排序演算法。 它重覆地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果順序(如從大到小、首字母從Z到A)錯誤就把他們交換過來。走訪元素的工作是重覆地進行直到沒有相鄰元素需要交換,也就是說該元素列已經排序完成。 ...
  • > 本文首發於公眾號:Hunter後端 > 原文鏈接:[Python連接es筆記二之查詢方式彙總](https://mp.weixin.qq.com/s/0Yn5c-U9pBWrSC5HrCgWog) 上一節除了介紹使用 Python 連接 es,還有最簡單的 query() 方法,這一節介紹一下幾 ...
  • Python3 支持int(整型數據)、float(浮點型數據)、bool(布爾類型) # 1.int(整型數據) 在Python 3里,**只有一種整數類型 int,表示為長整型**。像大多數語言一樣,數值類型的賦值和計算都是很直觀的。 ## 1.1數值運算 編寫程式如下所示 ![image](h ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...