首頁  >  文章  >  資料庫  >  redis專案的知識點有哪些

redis專案的知識點有哪些

WBOY
WBOY轉載
2023-05-27 19:55:251548瀏覽

專案的亮點:

1.使用分散式Seesion,可以實現讓多台伺服器同時可以回應。

2.使用redis做快取提高存取速度和並發量,減少資料庫壓力,利用記憶體標記減少redis的存取。

3.使用頁面靜態化,加快使用者存取速度,提高QPS,快取頁面至瀏覽器,前後端分離降低伺服器壓力。

4.使用訊息佇列完成非同步下單,提升使用者體驗,削峰和降流。

5. 安全性最佳化:雙重md5密碼校驗,秒殺介面位址的隱藏,介面限流防刷,數學公式驗證碼。

主要知識點:

分散式Seesion

我們的秒殺服務,實際的應用可能不只部署在一個伺服器上,而是分散式的多台伺服器,這時候假如使用者登入是在第一個伺服器,第一個請求到了第一台伺服器,但是第二個請求到了第二個伺服器,那麼使用者的session資訊就遺失了。

解決:session同步,無論存取那一台伺服器,session都可以取得到,利用redis快取的方法,另外使用一個redis伺服器專門用來存放使用者的session資訊。這樣就不會出現用戶session遺失的情況。 (每次需要session,從快取中取即可)

redis緩解資料庫壓力

本專案大量的利用了快取技術,包括使用者資訊快取(分散式session),商品訊息的緩存,商品庫存緩存,訂單的緩存,頁面緩存,物件緩存減少了對資料庫伺服器的存取。

通用快取key封裝

一個問題在於如何區分不同模組中的緩存,因為可能存在相同的key值

#解決:利用一個抽象類,定義BaseKey(前綴),在裡面定義快取key的前綴以及快取的過期時間從而實現將快取的key進行封裝。讓不同模組繼承它,這樣每次存入一個模組的快取的時候,加上這個快取特定的前綴,以及可以統一制定不同的過期時間。

頁面靜態化(前後端分離)

頁面靜態化的主要目的是為了加快頁面的載入速度,將商品的詳情和訂單詳情頁面做成靜態HTML(純的HTML ),資料的載入只需要透過ajax來請求伺服器,並且做了靜態化HTML頁面可以快取在客戶端的瀏覽器。

訊息佇列完成非同步下單

使用訊息佇列完成非同步下單,提升使用者體驗,削峰與降流

想法:

1 .系統初始化,把商品庫存數量stock加載到Redis上面來。

2.後端收到秒殺請求,Redis預減庫存,如果庫存已經到達臨界值的時候,就不需要繼續請求下去,直接返回失敗,即後面的大量請求無需給系統帶來壓力。

3.判斷這個秒殺訂單形成沒有,判斷是否已經秒殺到了,避免一個帳戶秒殺多個商品,判斷是否重複秒殺。

4.庫存充足,且無重複秒殺,將秒殺請求封裝後訊息入隊,同時給前端返回一個code (0),即代表返回排隊中。 (回傳的並不是失敗或成功,此時還不能判斷)

5.前端接收到資料後,顯示排隊中,並根據商品id輪詢請求伺服器(考慮200ms輪詢一次)。

6.後端RabbitMQ監聽秒殺MIAOSHA_QUEUE的這名字的通道,如果有消息過來,獲取到傳入的信息,執行真正的秒殺之前,要判斷數據庫的庫存,判斷是否重複秒殺,然後執行秒殺事務(秒殺事務是一個原子操作:庫存減1,下訂單,寫入秒殺訂單)。

7.此時,前端根據商品id輪詢請求介面MiaoshaResult,查看是否產生了商品訂單,如果請求返回-1代表秒殺失敗,返回0代表排隊中,返回>0代表商品id說明秒殺成功。

安全性最佳化

雙重md5密碼校驗,秒殺介面位址的隱藏,介面限流防刷,數學公式驗證碼。

優雅的程式碼​​寫

介面的輸出結果做了一個Result封裝

對錯誤的程式碼做了一個CodeMsg的封裝

存取快取做了一個key的封裝

專案難點及問題解決:

1. 使用JMeter做壓測的時候開啟5000個線程,系統跑不起來,出現異常

#原因:修改設定檔中redis的設定項poolMaxTotal 將其設定成1000。

#redis設定項目

redis.poolMaxTotal=1000

redis.poolMaxldle=500

redis.poolMaxWait=500

2 .使用了大量緩存,那麼就存在緩存擊穿和緩存雪崩以及緩存一致性等問題?

快取穿透指的是對某個一定不存在的資料進行請求,該請求將會穿透快取到達資料庫。

解決方案:對這些不存在的資料快取一個空數據,對這類請求進行過濾。

快取雪崩指的是因為資料沒有載入到快取中,或是快取資料在同一時間大面積失效(過期),又或快取伺服器宕機,導致大量的請求都到達資料庫。

解決方案:

為了防止快取在同一時間大面積過期導致的快取雪崩,可以透過觀察使用者行為,合理地設定快取過期時間來實現;

為了防止快取伺服器宕機出現的快取雪崩,可以使用分散式緩存,分散式快取中每個節點只緩存部分的數據,當某個節點宕機時可以保證其它節點的快取仍然可用。

也可以進行快取預熱,避免在系統剛啟動不久由於還未將大量資料進行快取而導致快取雪崩。

例如:首先針對不同的快取設定不同的過期時間,例如session緩存,在userKey這個前綴中,設定是30分鐘過期,並且每次使用者回應的話更新快取時間。每次取得session都會延長30分鐘,因此快取過期的機率相對較低

快取一致性要求資料更新的同時快取資料也能夠即時更新。

解決方案:

在數據更新的同時立即去更新緩存,首先嘗試從緩存讀取,讀到數據則直接返回;如果讀不到,就讀數據庫,並將數據會寫到緩存,並返回。

在讀取快取之前先判斷快取是否是最新的,如果不是最新的先更新,需要更新資料時,先更新資料庫,然後把快取裡對應的資料失效掉(刪掉)。

3.大量的使用緩存,對於緩存伺服器,也有很大的壓力,思考如何減少redis的存取?

在redis預減庫存的時候,記憶體中維護一個isOvermap作為一個記憶體標記,當沒有庫存的時候,將其置為true。每次秒殺業務訪問redis之前,先查一下map標記,如果true說明沒有庫存,就直接回傳失敗,無需再去請求redis伺服器。

4.在高並發請求的業務場景,大量請求來不及處理,甚至出現請求堆積時候?

訊息佇列,用來非同步處理請求。每次請求過來,先不去處理請求,而是放入訊息佇列,然後在後台佈置一個監聽器,分別監聽不同業務的訊息佇列,有訊息來的時候,才進行秒殺業務邏輯。這樣防止多個請求同時操作的時候,資料庫連接過多的異常。

5.怎麼保證一個使用者不能重複下單?

解決:秒殺訂單表中建立一個唯一索引(所引是用戶Id與商品goodsId),使得第一個記錄可以插入,第二個則出錯,然後通過事務回滾,防止一個用戶同時發出多個請求的處理,秒殺到多個商品。

唯一索引,即是唯一的意思,在資料庫表結構中對字段添加唯一索引後進行數據庫進行存儲操作時數據庫會判斷庫中是否已經存在此數據,不存在此數據時才能進行插入操作。

這雖然是個小技能,但實際上在業務開發中是個很實用的技能,例如在高並發業務中,資料庫如何杜絕資料並發插入兩個相同的訂單號碼?增加一個唯一索引當然是最快捷的方法之一,當然要添加索引還是透過業務代碼去解決因公司業務而定

6.怎麼解決超賣現象?

超賣場景:不同使用者在讀取請求的時候,發現商品庫存足夠,然後同時發起請求,進行秒殺操作,減庫存,導致庫存減為負數。

最簡單的方法,更新資料庫減庫存的時候,進行庫存限制條件,在reduceStock(GoodsVo goodsvo)這個方法裡,sql要多加一個stock_count > 0 ,使用資料庫特性來確保超賣的問題,只有stock_count還大於0的時候才去讀stock_count然後減1操作

@Update("update miaosha_goods set stock_count=stock_count-1 where goods_id=#{goodsId} and stock_count>0")

public void reduceStock(MiaoshaGoods goods);  

7.頁面靜態化的過程及什麼是瀏覽器快取?

將HTML靜態頁面緩存在客戶端瀏覽器,只有數據透過ajax異步調用介面來獲取,僅交互的是部分數據,減少了頻寬,也加快用戶訪問的速度。

瀏覽器快取就是把一個已經要求過的Web資源(如html頁面,圖片,js,資料等)拷貝一份副本儲存在瀏覽器中。快取會根據進來的請求保存輸出內容的副本。當下一個請求來到的時候,如果是相同的URL,快取會根據快取機制決定是直接使用副本回應存取請求,還是向來源伺服器再次發送請求。比較常見的就是瀏覽器會快取造訪過網站的網頁,當再次造訪這個URL位址的時候,如果網頁沒有更新,就不會再下載網頁,而是直接使用本地快取的網頁。只有當網站明確標識資源已經更新,瀏覽器才會再次下載網頁。

8.秒殺架構設計概念?

限流:鑑於只有少數用戶能夠秒殺成功,所以要限制大部分流量,只允許少部分流量進入服務後端。

在進行秒殺活動時,搶購開始時會瞬間出現大量用戶湧入,導致高峰期。因此需要採取削峰措施。高峰值流量是壓垮系統很重要的原因,所以如何把瞬間的高流量變成一段時間平穩的流量也是設計秒殺系統很重要的想法。實現削峰的常用的方法有利用快取和訊息中間件等技術。

非同步處理:秒殺系統是一個高並發系統,採用非同步處理模式可以大幅提高系統並發量,其實非同步處理就是削峰的一種實現方式。

記憶體快取:秒殺系統最大的瓶頸一般都是資料庫讀寫,由於資料庫讀寫屬於磁碟IO,效能很低,如果能夠把部分資料或業務邏輯轉移到記憶體緩存,效率會有極大地提升。

可拓展:當然如果我們想支援更多用戶,更大的並發,最好就將系統設計成彈性可拓展的,如果流量來了,拓展機器就好了。像淘寶、京東等雙十一活動時會增加大量機器應對交易高峰。

9.秒殺系統架構設計想法?

將請求攔截在系統上游,降低下游壓力:秒殺系統特徵是並發量極大,但實際秒殺成功的請求數量卻很少,所以如果不在前端攔截很可能造成資料庫讀寫鎖定衝突,最終請求超時。

利用快取:利用快取可大幅提升系統讀寫速度。

訊息佇列:訊息佇列可以削峰,將攔截大量並發請求,這也是一個非同步處理過程,後台業務根據自己的處理能力,從訊息佇列中主動的拉取請求訊息進行業務處理。

10.假如減了庫存用戶沒有支付,庫存怎麼還原繼續參加搶購?

#設定一個最長付款時間,比如30分鐘,後台有個定時任務(使用定時器Timer),輪訓超過30分鐘的待付款訂單(資料庫裡面判定訂單狀態),然後關閉訂單,恢復庫存。

以上是redis專案的知識點有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除