redis簡介與分佈式鎖的實現方案

1. redis 簡介;

Redis採用的是基於內存的採用的是單進程單線程模型的KV數據庫,由C語言編寫。官方提供的數據是可以達到100000+的qps。這個數據不比採用單進程多線程的同樣基於內存的KV數據庫Memcached差。

Redis快的主要原因是:

  1. 完全基於內存
  2. 數據結構簡單,對數據操作也簡單
  3. 使用多路 I/O 複用模型

多路 I/O 複用模型是利用select、poll、epoll可以同時監察多個流的 I/O 事件的能力,在空閒的時候,會把當前線程阻塞掉,當有一個或多個流有I/O事件時,就從阻塞態中喚醒,於是程序就會輪詢一遍所有的流(epoll是隻輪詢那些真正發出了事件的流),並且只依次順序的處理就緒的流,這種做法就避免了大量的無用操作。這裏“多路”指的是多個網絡連接,“複用”指的是複用同一個線程。採用多路 I/O 複用技術可以讓單個線程高效的處理多個連接請求(儘量減少網絡IO的時間消耗),且Redis在內存中操作數據的速度非常快(內存內的操作不會成爲這裏的性能瓶頸),主要以上兩點造就了Redis具有很高的吞吐量。

和Memcached不同,Redis並沒有直接使用Libevent,而是自己完成了一個非常輕量級的對select、epoll、evport、kqueue這些通用的接口的實現。在不同的系統調用選用適合的接口,linux下默認是epoll。因爲Libevent比較重更通用代碼量也就很龐大,擁有很多Redis用不上的功能,Redis爲了追求“輕巧”並且去除依賴,就選擇自己去封裝了一套。

2 redis分佈式鎖實現方案;

redis實現分佈式鎖:
1)setnx(lockkey, 當前時間+過期超時時間) ,如果返回1,則獲取鎖成功;如果返回0則沒有獲取到鎖,轉向2。
2.)get(lockkey)獲取值oldExpireTime ,並將這個value值與當前的系統時間進行比較,如果小於當前系統時間,則認爲這個鎖已經超時,可以允許別的請求重新獲取,轉向3。
3.)計算newExpireTime=當前時間+過期超時時間,然後getset(lockkey, newExpireTime) 會返回當前lockkey的值currentExpireTime。
4.)判斷currentExpireTime與oldExpireTime 是否相等,如果相等,說明當前getset設置成功,獲取到了鎖。如果不相等,說明這個鎖又被別的請求獲取走了,那麼當前請求可以直接返回失敗,或者繼續重試。
5) 在獲取到鎖之後,當前線程可以開始做自增操作,當處理完畢後,比較自己的處理時間和對於鎖設置的超時時間,如果小於鎖設置的超時時間,則直接執行delete釋放鎖;如果大於鎖設置的超時時間,則不需要再鎖進行處理。

 

實現方法2(最新redis):

1.使用set lock_key  lock_uk_tag  NX  EX lockTimeout。其中lock_key是鎖標示,lock_uk_tag是獲取鎖的使用者的唯一標示,lockTimeout 鎖失效時間(NX 和EX 詳見最新的redis的set命令介紹)。
2.如果返回1則證明獲取到鎖,0則未獲取到鎖。
3.當獲取到鎖之後,進行業務操作完成之後。使用get lock_key獲取使用者,如果爲null證明鎖已經失效了則直接退出。如果有值就當前使用者對比,如果不等不處理鎖,如果相等就直接del lock_key 刪除鎖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章