我國目前並未出台專門針對網路爬蟲技術的法律規範,但在司法實踐中,相關判決已屢見不鮮,K 哥特設了“K哥爬蟲普法”專欄,本欄目通過對真實案例的分析,旨在提高廣大爬蟲工程師的法律意識,知曉如何合法合規利用爬蟲技術,警鐘長鳴,做一個守法、護法、有原則的技術人員。 案情介紹 2018年10月,北京市公安局海 ...
把黑馬的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,那麼此時的鎖就不是同一吧了,而是這台伺服器認為他的這把鎖是唯一的,那台伺服器認為他的這把鎖是唯一的。這樣子就做不到唯一鎖。所以我們這裡需要使用分散式鎖。
但是分散式鎖也會遇到一些問題,比如說誤刪鎖問題,以及刪鎖時的原子性問題。