如下內容是翻譯的官網文檔RedLock和分區部分,能夠簡單瞭解分佈式鎖在redis如何實現及其方式java
redis分區的方法node
##redis實現的分佈式鎖RedLock算法,分佈式鎖,即在多個master上獲取同一個鎖redis
1.in order to get the lock,the client get the current ms time算法
2.順序對n個實例獲取鎖權限(n個都是master),嘗試鎖時,設置鏈接超時時間,防止因爲實例掛了,致使長時間沒法執行操做數據庫
3.計算爲了獲取鎖消耗的時間,有且僅有,client獲取了超過半數個機器的鎖,且獲取鎖消耗的時間小於鎖的有效期,就被認爲client獲取了鎖緩存
4.鎖被獲取後,其合法的持續時間爲:初始設置的有效時間-爲了獲取鎖消耗的時間異步
5.若是client因爲某些緣由沒有成功獲取鎖,它會解鎖全部master實例(即便有的實例它不可能鎖成功)分佈式
###算法是異步的嗎url
算法的前提是:多個進程或機器不會同步時鐘,致使時間波動,沒法計算出準確的獲取鎖消耗時間,或不一樣的計算機,時間流逝的速度浮動範圍很小.net
##redis分區:
###分區的優勢
1.造成一個更大的數據庫
2.計算能力加強,運用更多的核心數
基本的分區方式
1.範圍分區,用一個路由表記錄1-1000放哪一個實例,1001-2000放哪一個實例,缺點也很明顯,須要路由表,key的類型不少的時候,須要給不一樣類型的key作不一樣的路由
2.hash分區,crc32(key),獲取一個很大的數字,用這個數字和redis實例數取模,找到對應實例
3.一致性hash分區
###不一樣的實現
1.client端分區:client直接選取正確的redis
2.代理輔助分區:client請求proxy,proxy forward正確的redis,並返回結果給client
3.查詢路由;client隨機發給一個redis,redis forward query to right node,也有redis查詢路由後,返回正確的redis地址,客戶端再去正確的redis取,可是這樣會多請求一次redis
###分區的不足
1.不提供同時操做多個key
2.redis事務直接不可用
3.分區的粒度是key,若是一個key存了很大的數據量,分區也迫不得已
4.數據處理變得複雜,若是你想備份,須要聚合多個實例
5.擴容或縮容變得複雜,redis集羣支持透明的重平衡數據,可是client分區,代理分區卻不能透明的支持這個特性(預分區技術能解決)
存儲數據?緩存?
若是redis做爲數據存儲,那麼一個key老是須要對應到同一個redis
分佈式鎖 1.互斥 setNX 2.死鎖 timeout 3.可重入 setNx(xx,xx,1) -> setNx(xx,xx,2) 4.訂閱subscrible 頻道,鎖釋放時publish消息,redis server和client會創建長鏈接,訂閱時,java須要開發一個listener來處理消息,實現onMessage方法
https://www.jianshu.com/p/de5a69622e49
##redis爲何快
redis快的緣由,基於內存,不會再操做時進行磁盤I/O,key,val採用dict,相似HashMap,時間複雜度爲1,key多爲string,沒有hash衝突 單線程避免了無謂的cpu上下文切換,無鎖 非阻塞IO,epoll多路複用 epoll 是隻輪詢那些真正發出了事件的流),而且只依次順序的處理就緒的流,這種作法就避免了大量的無用操做,只有一個線程來處理這些I/O,key
確實沒法利用多cpu的優點,可是通常狀況下,cpu不是redis的瓶頸,可是能夠用單機啓用多個redis來彌補
減小耗時的命令,大對象,大對象還可能致使頻繁查詢打滿帶寬