tft每日頭條

 > 生活

 > redis實現分布式鎖用哪些命令

redis實現分布式鎖用哪些命令

生活 更新时间:2024-09-04 16:26:37

redis實現分布式鎖用哪些命令(Redis常見的使用場景概括-進階篇)1

簡介

上一篇介紹了Redis基本的使用場景,今天介紹在高并發的場景中,常用到的一種技術手段,那就是鎖機制。

Redis分布式鎖

跟其他鎖一樣,Redis的鎖根據鎖機制的不同分為樂觀鎖和悲觀鎖,經常被用于防止出現雪崩效應。下面分别先簡單介紹一下。

樂觀鎖

通常基于版本記錄機制實現,不是我們今天要詳細介紹的,我們拿個例子簡單說明一下,假定有A和B兩個事務同時執行:

第一步:A讀取數據,記錄數據當前版本号n(相信沒有人會動我将要改的數據,真樂觀是不是,哈哈);

第二步:B修改數據,此時版本号變為n 1;

第三步:A要改數據了,看了下版本号,跟剛才對不上啊(事務失敗了);

過程說明:

redis實現分布式鎖用哪些命令(Redis常見的使用場景概括-進階篇)2

B事務

redis實現分布式鎖用哪些命令(Redis常見的使用場景概括-進階篇)3

A事務

結論:當如果監視的key在watch後發生過變化,則返回失敗。

這就是樂觀鎖,适合于讀多寫少并的場景。

悲觀鎖

這個很好理解,A每次修改數據之前都會加上鎖,防止被其他事務修改(真夠悲傷的)。今天重點介紹的就是這貨了。

例子

首頁某個頁面訪問量大,所以加了緩存,并設定緩存過期後刷新,如果隻是這樣處理,那麼會有什麼問題?問題是當請求并發量很大的時候,緩存過期的瞬間,大量請求會穿透緩存直達數據庫,造成雪崩效應,數據庫服務器直接宕機。如果有鎖機制,便可以控制隻有單個請求去更新緩存,更新未完成前,其他請求依舊讀取舊緩存。下面給出實現的過程:

先來看一段代碼實現:

redis實現分布式鎖用哪些命令(Redis常見的使用場景概括-進階篇)4

版本1

這邏輯很簡單,但是如果請求執行過程意外退出了,沒有删除鎖,那麼以後緩存都不會更新了。

嗯,很好,知道問題所在,我優化一下,給它個過期時間不就行了:

redis實現分布式鎖用哪些命令(Redis常見的使用場景概括-進階篇)5

版本2

那麼這樣就沒有問題了嗎,當然沒這麼簡單了,雖然我們保證隻有一個setnx成功,但是expire可以一直刷新啊,導緻鎖一直有效。

還好Redis的作者antirez很早就考慮到這問題了,從Redis 2.6.12版本起,set涵蓋了setnx的功能,并且set本身已經包含了設置過期時間的功能。那麼我們的實現變得簡單了:

redis實現分布式鎖用哪些命令(Redis常見的使用場景概括-進階篇)6

版本3

這樣就行了嗎?

也還不行,如果更新時間比鎖的有效期還長,如果不加以判斷直接删除鎖,那麼就會出現誤删其他鎖的情況,針對這種情況,我們再優化一下,變成:

redis實現分布式鎖用哪些命令(Redis常見的使用場景概括-進階篇)7

版本4

這下完美了嗎,依然沒有。試想一下,如果del鎖的請求到達過程中出現網絡延遲會依舊會誤删其他鎖。

也許你會問有沒有靠譜點的實現,答案是沒有。這個問題正是基于單Redis節點的分布式鎖的局限性所在,即便如此,隻要實現分布式鎖的時候加以注意,它依然相當有用。

後記

假如要實現多節點的分布式鎖,有沒有辦法呢?有的,因為Redis的作者antirez大神已經給出一個更好的實現 - Redlock算法。有興趣的讀者可以Redis官網上了解一番,當然了,前提是你已經理解了基于單Redis節點的分布式鎖是如何實現的。

ps:之後會有MySQL優化系列文章發表,敬請期待!

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved