redis分布式鎖java實現解決快取雪崩

2021-08-09 21:10:54 字數 2218 閱讀 5045

快取雪崩:因為快取失效(key生存時間到期)導致所有請求都去查詢資料庫,導致資料庫cpu和記憶體負載過高導致宕機。

快取雪崩原因及解決方案:

使用快取主要解決資料同步,並減少對資料庫訪問次數。因此,通常解決方案往往是使用互斥鎖,讓乙個執行緒訪問資料庫,並將資料更新到快取中,其他執行緒訪問快取中資料。如果是基於jvm鎖機制的話,只能解決單機問題,也就是只讓本機乙個執行緒訪問快取,但是分布式條件下是不能使用的。所以,要基於快取的分布式鎖來實現。

以redis為例解釋下實現分布式鎖的原理:

獲取鎖:

所有執行緒操作乙個共同的key比如:lock,如果redis中不存在key為lock的值,那麼當前執行緒獲取鎖並為lock設定乙個隨機值。

如果lock已經存在了,說明已經有執行緒獲取鎖,該執行緒不能再獲取了。

釋放鎖:

獲取鎖的執行緒操作執行完畢後,清除lock的值,這樣鎖就釋放了。所以,對鎖的操作就是通過對同乙個key值的新增和刪除操作。

**:

@service

public class redislock implements lock

return false;

} /**

* 解鎖

*/@override

public void unlock() catch (ioexception e)

jedis jedis = (jedis)factory.getconnection().getnativeconnection();

listkeys=new arraylist();

keys.add(lock);

listargs=new arraylist();

args.add(local.get());

//如果redis中的 lock值和當前執行緒的uuid值相等,刪除key值

jedis.eval(script, keys, args);

}}

刪除鍵值是執行的指令碼unlock.c:

if redis.call("get",keys[1])==argv[1] then

return redis.call("del",keys[1])

else

return 0

end

操作快取的具體流程:

1.當執行緒查詢某一值時先檢視快取是否存在該值。

2.如果存在直接返回主快取中的資料。

3.1如果不存在,只有乙個執行緒獲取鎖並去資料庫讀取資料,讀取後更新主快取和備份快取。

3.2 其他執行緒取備份快取中的資料。.

**實現:初始時,主快取和備份快取為空,此時可能會有執行緒獲取的值為空,但是並不影響使用者體驗,使用者可以再重新整理一次。在要求比較高的場景裡面,可以考慮先把資料寫入快取中,可以搭配定時重新整理快取的機制。

public listquerycountbyleimu() 

if(lock.trylock())else

}

資料同步問題:主快取中key的過期時間比較短,這樣保證盡可能獲取新資料。

bean.xml中快取失效時間設定:

測試方法模擬高併發情景:

@autowired

leimuservice leimuservice;

private static final int threadnum=13;

//倒計數器(發令槍) 用於製造執行緒併發執行

private static countdownlatch cdl=new countdownlatch(threadnum);

/*** 模擬高併發條件下,資料庫查詢耗時比較長

* @throws interruptedexception

*/@test

public void test04() throws interruptedexception}}

缺點:1.非阻塞,短時間不能保證資料一致性

2.鎖失效時間難把握,一般為單執行緒處理時長的兩到三倍

3.可能出現鎖失效情況

4******不能在redis集群環境中使用(集群中可用redlock)

建議使用基於zookeeper的分布式鎖實現方式!!.

java 基於redis實現分布式鎖

前幾天,被問到併發操作如何解決一條資料被請求多次處理事件的技術解決方案,當時只有一點印象,利用鎖機制,但是讀寫鎖對於分布式部署的專案來說是無法實現的。事後去檢視博友們提供的技術方案。決定基於redis自己嘗試寫乙個分布式鎖來實現多執行緒操作。類似乙個秒殺功能吧,這裡有個問題就是其實並不是執行緒搶到了...

分布式鎖 使用Redis實現分布式鎖

關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs...

redis實現分布式鎖

隨便 系統越來越大,各功能模組除了垂直切割以外,同時也得做集群處理,那麼問題來了,在多執行緒情況下對於資源的競爭就需要乙個統一的訪問限制。以選課系統為例子,集群中各節點對課程可選數量同時操作,這裡就需要同步了,否則會導致最後選到的數量比可選的數量大,這裡我們的分布式鎖就派上用場了。利用redis來實...