codis學習


 

 

一.codis-proxy 結構

  • 1.Topology
  • 2.Slots
  • 3.ServerGroup
  • 4.Server
 

二.codis-proxy 啟動過程

 

1.初始化ProxyInfo

  • Id
  • Addr
  • productName
 

2.Proxy 把自己標記成offline狀態,將自己注冊到zk上

  • ProxyServer -> Topology -> Proxy -> CreateProxyInfo
  • zk上的地址 /zk/codis/db_{productName}/proxy
 

3.Proxy 從zk上獲取自己的狀態

  • 判斷zk上的狀態是online認為注冊成功,並且開始監控zk自己的變化
  • 如果還是offline狀態,3秒以后重試,重新獲取zk上的狀態
 

4.監控子節點的狀態

  • zk上的地址 /zk/codis/db_{productName}/actions
 

5.初始化slots

  • 每個codis-proxy有1024個slots
  • 在zk上逐個獲取slot
  • 某一個slots在zk上的狀態的path是/zk/codis/db_{productName}/slots/slot_{i}
  • slot的狀態,確保是online狀態
  • 在zk上逐個獲取這個slot所在的server group
  • 某一個server group在zk上的狀態的path是/zk/codis/db_{productName}/servers/group_{i}
  • 獲取server group zk下的子節點列表
  • 逐個在zk上獲取server group下的server,並創建server對象
  • 這樣一個slot就是由 zk 上的slot zk上的server group(由server組成是一個一主多從的結構)組成
  • 為了使用這個slot所以需要把server group中的那些servers中的主庫創建連接
  • 這里用slot的dst字段標示了slot所在主庫的位置
  • 同時在codis-proxy的redis連接池中添加這個主庫的連接
  • 這里需要說明一點的是,由於這個slot有可能處於migrate狀態,在創建的時候同時記錄了他是從哪個server group遷移過來的在migrateFrom字段,並且把遷移的主庫添加到codis-proxy的連接池
 

6.開始事件循環

  • 主要是處理之前監控的一些zk上的變更
 

7.監聽codis-proxy的端口

  • block
 

三.codis-proxy 的對外服務過程

  • 對一個redis key的操作先把這個key crc32到某一個slot上
  • 如果這個slot處於pre migrate需要阻塞對這個slot的操作
  • 判斷這個key是否處於migrate狀態,如果是的話,在slot的migrateFrom的redis上執行一個遷移命令,命令的參數的slot的dst的IP和端口還有KEY的名字
  • migrateFrom的這個redis會把key遷移到dst上並刪除自己的key,所以migrateFrom是遷移中的那個老的實例,dst是遷移中的新實例
  • 判斷遷移命令的返回值,成功的話認為遷移成功
  • 遷移成功以后,我們都是從dst這個新實例來讀或者寫這個key的內容返回給客戶端
  • 然后做的就是一個代理該做的事情了,寫目標讀寫,結果返回給客戶端
 

四.為什么codis要修改redis源碼來支持遷移

  • 一個原因是slot下的key set不好獲得
  • 一個原因就是redis的操作都是原子性的,如果在遷移的時候,是通過proxy的在老的上get,新的上set,這樣沒法保證其他proxy對這個key操作的原子性
 

一.codis-config 啟動過程

  • 解析productName zk地址
  • 利用zk創建一個分布式鎖 /zk/codis/db_{productName}/LOCK
  • 關於利用zk創建分布式鎖的方法有很多
  • lock的時候可以在一個root下創建一個自增的臨時節點,取root下的所有節點,自己是最小的認為獲得鎖,否則等待比自己小1的節點刪除
  • 因為zk保證里一致性,所以這個鎖和單機操作系統中的信號量一樣,取這個mutex的值,lock時候就減1,unlock時候加1
  • 具體ocdis-config是用的哪種實現因為是在另一個項目里,所以還沒看
  • 在zk中創建配置 /zk/codis/db_{productName}/living-codis-config
  • 一個defer 結束的時候刪除之前zk創建的path
  • 啟動了一個監聽在10086的HTTP管理后台
 

二.codis-config 命令

  • 如果命令是阻塞的,會先獲取之前的分布式鎖,執行完以后會釋放鎖,只不過是一個一級命令一個鎖
 

proxy命令

 

list命令,獲取所有codis-proxy的代理信息

  • 保存在zk的/zk/codis/db_{productName}/proxy 的子節點下
 

offline/online命令,將一個codis-proxy設置為下線和上線狀態

  • 先獲取/zk/codis/db_{productName}/proxy/{proxyName}的proxy信息
  • 如果是將proxy設置為上線狀態,檢查proxy下的所有slot是online狀態
  • 設置proxy狀態是上線狀態
  • 如果是將proxy設置為下線狀態,那么先設置proxy的狀態為標記下線,也即是mark_offline
  • 然后訂閱節點的變更,直到他的狀態為offline的時候認為下線成功
 

slot命令

 

migrate命令,遷移一個slot

  • 從zk中獲取所有slot的狀態
  • 檢查集群中是否有正在遷移的slot,保證集群中同時只能有一個slot在遷移
  • 遷移某個slot的時候先獲取分布式鎖,表示開始遷移某個slot,結束的時候釋放
  • 檢查遷移到的server gorup可用
  • 進入二階段的提交的第一階段,通知所有proxy 這個slot處於pre_migrate狀態
  • 等待所有proxy做出回復,修改slot狀態為migrate狀態,保存在zk上
  • 在老的redis主庫上執行slotsmgrtslot命令遷移slot到新的redis主庫,直到slot中所有的key遷移完成

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM