把黑馬的redis實戰看了將近一半,自己也做了挺多思考,現在對于Redis的使用,以及業務方面的思考,有了更深刻的理解,
- 使用快取能夠加快資料的查詢速度,提高用戶的使用感受,對于經常需要訪問的資料,都可以放到快取中,這樣也能給資料庫減少壓力,
但是,使用快取之后,就有許多問題需要解決,包括業務場景的考慮,
1. 快取和資料庫一致性的問題
- 這個問題是確保用戶能夠從快取中訪問到最新的資料,
-- 一般需要考慮的場景就是:更新了資料庫,那么我們的快取也要更新,否則用戶去查資料走快取,那么拿到的資料就可能是假的, - 如何去更新也是有技巧,能夠確保不做過多的無效操作,也要確保用戶能拿到最新資料,
- 根據學習,我理解的就是采用:先更新資料庫,再洗掉快取這么一個策略
-- 相較于每次更新完資料庫都去更新快取,這個策略就能避免很多無效的寫操作,也能確保快取是最新的(這其中就涉及到一些并發的業務邏輯),
2. 快取擊穿問題
- 這個問題就是熱點key失效了,而重構這個key又需要比較久的時間,
-- 而在這個重構的時間段里面,如果并發訪問資料,那么就又會給資料庫造成很大壓力, - 如何去解決這個問題,我理解的就是加鎖,
-- 如果用戶進來查詢資料,后臺發現未命中快取,那么就去嘗試獲取鎖,而這個鎖,是redis中的一個分布式鎖,setnx這個命令,拿到了鎖,那么就去執行快取重建邏輯,
-- 而如果這時候,其他用戶也進來查資料,此時肯定拿不到鎖,那么就會休眠一會,然后嘗試重新去查詢資料, - 這就是1一個解決方案,這個方案能避免給資料庫造成很大壓力,但是也可能會影響用戶體驗,因為需要進行等待,
- 還有一個解決方案就是邏輯超時,也就是不給key設定過期時間,但是給他設定一個邏輯超時時間,這個方案的話就是給k-v的v中存盤一個key的有效期,這個方式的話,在快取重建之前,用戶會拿到臟資料,
- 還得根據具體業務去選擇
3. 快取穿透問題
- 這個問題就是客戶端發來了很多請求,但是這些請求需要的資料在快取、資料庫都沒有,給資料庫造成了很大的壓力,
- 解決方案:1.快取空資料 2.布隆過濾器(對這個不是很了解,沒用過)
4. 快取雪崩問題
- 這個問題是redis宕機,或者說大量的key失效
- 解決方案:搭建redis集群
分析一個具體的業務場景
用戶搶優惠券,要滿足條件:一人一單
要考慮并發時出現的問題,
1.首先要查該用戶是否有券,如果沒有就能讓它去搶,否則就不允許
2.如果該用戶沒券,就去執行搶券邏輯
在查券的時候,如果同一個用戶發來了很多請求,這是一個并發問題,
如果說執行緒1判斷無券,那么就去執行搶券邏輯,如果這時候執行緒2進來了,也會判斷無券,又會執行它的搶券邏輯,
所以需要加一個鎖,即使同一個用戶發來多次請求,此時也是串行的,只有等他執行完搶券邏輯,才會釋放鎖,那么如果該用戶的其他的搶券請求進來,也不會去執行搶券,
同時,搶券邏輯也在這個鎖的鎖定范圍內,也避免了超賣的問題,
這里的鎖需要使用分布式鎖,比如redis的setnx(),
分析:我們采用的鎖物件是,user.getId(),在單體專案之下,對于一個用戶的多個請求進來,該鎖物件確實是唯一的,
但是如果將該專案做成集群的形式,由于每個Tomcat都有自己的JVM,那么此時的鎖就不是同一吧了,而是這臺服務器認為他的這把鎖是唯一的,那臺服務器認為他的這把鎖是唯一的,這樣子就做不到唯一鎖,所以我們這里需要使用分布式鎖,
但是分布式鎖也會遇到一些問題,比如說誤刪鎖問題,以及刪鎖時的原子性問題,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/520601.html
標籤:其他
