回覆列表
  • 1 # 一個存在感小透明

    和大家分享我的經驗,如何用redis提供的一個簡單介面,輕鬆實現redis分散式鎖。

    在開始之前,我先簡單介紹下redis的效能。

    高效的Redis

    Redis本身是單執行緒的,這樣帶來的好處是能夠提高讀寫效率。多執行緒通常來說會有上下文切換帶來的時間損耗,而redis透過繫結單個CPU到某塊記憶體,實現了上下文切換的最小開銷,因此這種場景反而比多執行緒還要高效。

    不安全的Redis

    但是,如果有不同的節點同時要對Redis中的同一個資料進行操作,由於是來自不同Redis伺服器,就會發生執行緒不安全的情況。

    舉例有兩個功能函式X和Y(也可以看做是兩個伺服器節點),二者功能相同,都要執行讀取Redis中變數P,並且對其加一的操作。如果是執行緒安全的,那麼X和Y分別執行完之後,P的值應該比原來增加2,但是由於函式XY互相獨立,那就可能發生下面這種情況:

    1 X讀取P

    2 Y讀取P

    3 X將P+1寫回Redis

    4 Y將P+1寫回Redis

    執行結束後,P的值卻變成了P+1,而不是P+2。

    這就是執行緒不安全導致的結果。

    redis的分散式鎖

    那麼如何用Redis來避免上面的情況呢。

    Redis對外開放了一個非常厲害的api,目前經常被大家用來做分散式鎖,是絕對的執行緒安全,這個函式就是SET key field value加上NX引數。這個NX引數可是了不得,通常來說,set函式是不管field欄位是否存在,只要寫入成功就會返回1,但是如果增加了NX引數,那麼如果field值在redis中已經存在,就會返回nil,否則才返回1。因此可以透過這個函式來執行加鎖操作,如果返回值不為nil,則加鎖成功,否則代表有其他執行緒在操作資料,當前請求需要等待。

    不僅如此,為了避免死鎖,SET還有一個引數為EX,即EX毫秒後,field會自動清空。

    此外,還有PX,XX引數,具體含義見如下文件。

  • 中秋節和大豐收的關聯?
  • AG超玩會對線GK時試水魯班中單,老帥穩到成“慫王”,如何評價這局比賽?