天天看點

談談Redis的SETNX

比如說:某個查詢資料庫的接口,因為調用量比較大,是以加了緩存,并設定緩存過期後重新整理,問題是當并發量比較大的時候,如果沒有鎖機制,那麼緩存過期的瞬間,大量并發請求會穿透緩存直接查詢資料庫,造成雪崩效應,如果有鎖機制,那麼就可以控制隻有一個請求去更新緩存,其它的請求視情況要麼等待,要麼使用過期的緩存。

緩存過期時,通過 SetNX  擷取鎖,如果成功了,那麼更新緩存,然後删除鎖。看上去邏輯非常簡單,可惜有問題:如果請求執行因為某些原因意外退出了,導緻建立了鎖但是沒有删除鎖,那麼這個鎖将一直存在,以至于以後緩存再也得不到更新。于是乎我們需要給鎖加一個過期時間以防不測:

如上代碼是完美的嗎?答案是還差一點!設想一下,如果一個請求更新緩存的時間比較長,甚至比鎖的有效期還要長,導緻在緩存更新過程中,鎖就失效了,此時另一個請求會擷取鎖,但前一個請求在緩存更新完畢的時候,如果不加以判斷直接删除鎖,就會出現誤删除其它請求建立的鎖的情況,是以我們在建立鎖的時候需要引入一個随機值:

http://huoding.com/2015/09/14/463