溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

發(fā)布時間:2020-06-25 17:38:28 來源:網(wǎng)絡(luò) 閱讀:1528 作者:中間件小哥 欄目:云計算

Codis介紹

Codis 是一種Redis集群的實現(xiàn)方案,與Redis社區(qū)的Redis cluster類似,基于slot的分片機制構(gòu)建一個更大的Redis節(jié)點集群,對于連接到codis的Redis客戶端來說, 除了部分不支持的命令外,與連接開源的 Redis Server 沒有明顯的區(qū)別, 客戶端代碼基本需要進行修改,Codis-proxy會根據(jù)訪問的key進行slot的計算,然后轉(zhuǎn)發(fā)請求到對應(yīng)的Redis-server,對于客戶端來說,中間的codis-proxy是不可見的,因此根據(jù)客戶業(yè)務(wù)的需要,可以使用codis構(gòu)建大規(guī)模的Redis 服務(wù),或者僅僅是用于把請求分擔多個Redis-server提高系統(tǒng)的吞吐量。

 

與業(yè)界著名的twproxy相比,除了支持Redis的轉(zhuǎn)發(fā),coids還支持不停機的數(shù)據(jù)遷移,使用戶可以在容量或者吞吐量要求有變化時,輕松進行節(jié)點的增減,本文主要對codis的遷移原理進行分析,并提出一個可行的優(yōu)化點。

 

本文是基于codis3.0版本。

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

(圖片來自網(wǎng)絡(luò))

 

Codis遷移實現(xiàn)原理

Codis-dashboard在啟動時,運行了4個后臺線程(goroutine),包括后臺redis狀態(tài)同步、proxy狀態(tài)同步、slot事件處理、sync事件處理,并提供了slot相關(guān)的RestFUL API進行slot與Redis-group歸屬關(guān)系的定義、遷移的定義和觸發(fā)。

 

如下結(jié)構(gòu)定義一個slot與Redis-group的歸屬關(guān)系和遷移關(guān)系,GroupId表示索引為Id的slot所屬的redis-group,而Action用于表示一次遷移,Action.TargetId表示該slot要遷移的目標redis-group的Id,Action.State表示遷移的狀態(tài),主要有Pending、Preparing、Prepared、Migrating、Finished幾種狀態(tài)。

type SlotMapping struct {

                Id      int `json:"id"`

                GroupId int `json:"group_id"`

 

                Action struct {

                                Index    int    `json:"index,omitempty"`

                                State    string `json:"state,omitempty"`

                                TargetId int    `json:"target_id,omitempty"`

        UpdatedAt int64 `json:"updated_at,omitempty"`

                } `json:"action"`

}

 

手動進行一次遷移過程,可以用如下命令來觸發(fā):

codis-admin --dashboard=ADDR -slot-action --create --sid=ID --gid=ID,比如把slot 10遷移到group 5,則可以執(zhí)行” codis-admin --dashboard=ADDR -slot-action --create --sid=10 --gid=5”

如果是把多個slot遷移到同一個server,則可以使用如下命令,一次性來定義若干個遷移操作,codis-admin --slot-action    --create-range --beg=ID --end=ID --gid=ID,比如把slot 10~15遷移到group 5,則可以執(zhí)行” codis-admin --dashboard=ADDR -slot-action –create--range --beg=10 –end=15 --gid=5”。

 

一次遷移的執(zhí)行過程中,slot的Action的狀態(tài)會發(fā)生變化,過程為:

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

也可以觸發(fā)codis進行rebalance,命令為:codis-admin --dashboard=ADDR –rebalance        --confirm,codis會自動把slot往一些新加入的節(jié)點進行遷移,使各個節(jié)點負責的slot均衡。

 

Codis遷移的測試

經(jīng)測試,對于一個64G規(guī)模的集群(由8個節(jié)點組成,每個節(jié)點8G),使用redis-benchmark寫滿數(shù)據(jù),每個key的value長度為32字節(jié),總共寫入341446298(3.4億)條數(shù)據(jù),擴容到128G,即對其中的512個slot進行遷移。

 

測試結(jié)果如下:

 

從測試結(jié)果來看,遷移速度非常慢,每遷移一個slot需要花費基本1個小時,因此使用codis時,需要監(jiān)控數(shù)據(jù)量,當數(shù)據(jù)不夠時,需要進行及時的擴容,否則當空間不夠時的故障處理和恢復時間可能影響線上業(yè)務(wù)。

 

Codis遷移代碼分析及瓶頸分析

從測試結(jié)果來看,遷移速度確實非常慢,極端情況下可能會影響線上業(yè)務(wù),因此對遷移過程進行分析和優(yōu)化就很有必要,下邊對關(guān)鍵的實現(xiàn)代碼handleSlotRebalance 、StartDaemonRoutines、ProcessSlotAction進行解讀,并分析優(yōu)化改進的地方。

01

handleSlotRebalance實現(xiàn)分析

這個函數(shù)的主要邏輯分為三部分:

1)找到需要遷移的slot;

2)為每個新節(jié)點分配slot;

3)生成遷移操作;

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

 

上面的代碼的邏輯是:

1)根據(jù)節(jié)點個數(shù)和slot槽數(shù)(固定的1024),計算每個節(jié)點上應(yīng)該負責的slot槽數(shù),表示為bound;

2)對每個redis-group,找到需要遷移出去的slot,表示為pending;

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

 

生成遷移計劃:

1)遍歷所有的redis-group,對于已有的slot小于應(yīng)該負責的slot槽數(shù)的,就要遷移一些槽進來;

2)所有的redis-group,決定需要遷移進來的slot列表,表示為plans;

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

 

遍歷遷移計劃,使用create actionRange生成一系列的slot action,并保存到etcd,下一步就需要由后臺線程去etcd中取出slot操作進行分別處理。

 

02

StartDaemonRoutines

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

這個代碼是在dashboard啟動時就啟動的后臺任務(wù),每隔5秒鐘觸發(fā)一次slot操作,且只會運行一個slot操作任務(wù)。

 

03

ProcessSlotAction實現(xiàn)分析

分為兩步Topom.SlotActionPrepare和Topom.processSlotAction。

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

 

從上面代碼可以看出:

下邊再分析processSlotAction的實現(xiàn):

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

 

可以看出:

 

04

瓶頸分析

從上面的分析可以得出:

這個設(shè)計的好處是,遷移過程對客戶業(yè)務(wù)的影響很小,但是也有一些明顯的缺點:

 

由于擴容一般會有一定的提前量,且會選在業(yè)務(wù)低峰期進行,因此可以對該遷移方案進行優(yōu)化,可以在不對業(yè)務(wù)訪問造成太大的影響的前提下提高遷移效率。

 

Codis代碼優(yōu)化

根據(jù)上面對遷移實現(xiàn)的分析,優(yōu)化的思路為:

 

1、Slot遷移并行化

從代碼實現(xiàn)的分析,有2個點可以選擇:

 最終處理代碼簡單化的考慮,選擇了方案2,同時考慮到如下幾點:

如下優(yōu)化代碼,啟動至多10個線程進行slot事件的處理。

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

 

同時修改SlotActionPrepare,選擇一個狀態(tài)為Pending且沒有歸屬于同一個redis-server的slot,進行處理。

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

 

2、Multikey遷移

修改redis-server的遷移指令,支持一次遷移多個key,為了靈活性,把遷移的個數(shù)從外部傳入,代碼比較顯而易見,參考如下:

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

Redis實踐系列丨Codis數(shù)據(jù)遷移原理與優(yōu)化

 

Codis遷移優(yōu)化測試結(jié)果

經(jīng)過驗證,對于一個64G規(guī)模的集群,使用redis-benchmark寫滿數(shù)據(jù),每個key的value長度為32字節(jié),總共寫入341446298(3.4億)條數(shù)據(jù),擴容到128G,即對其中的512個slot進行遷移。最終測試結(jié)果為:

因此,經(jīng)過優(yōu)化后遷移性能有極大的提升。當然當前的配置也是考慮到了盡量不影響客戶的業(yè)務(wù)訪問,一次遷移的數(shù)據(jù)量并不是最大化的,在某些情況下,可以修改配置,一次遷移更多的key,可以更加快速的完成遷移。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI