基於Codis的Redis分布式緩存實現
Codis 是一個分布式 Redis 解決方案, 對於上層的應用來說, 連接到 Codis Proxy 和連接原生的 Redis Server 沒有顯著區別 , 上層應用可以像使用單機的 Redis 一樣使用, Codis 底層會處理請求的轉發, 不停機的數據遷移等工作, 所有後邊的一切事情, 對於前麵的客戶端來說是透明的, 可以簡單的認為後邊連接的是一個內存無限大的 Redis 服務。
Codis不支持的命令
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
這些命令是“半支持”。CODIS係統不支持跨節點的操作,所以你必須使用Hash tag,如果所有的key在一個請求顯示到同一個槽然後可以使用這些命令。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Codis版本
codis 1.9
● codis-server 基於 redis-2.8.13
● codis-proxy 對 pipeline 支持不友好
● codis-proxy 對 zk 強依賴
● 同步遷移性能差,不支持大 key 遷移
codis 2.0
● codis-server 基於 redis-2.8.21
● 重構了codis-proxy,性能大幅提升,對 pipeline 支持比較好
● codis-proxy 對 zk 強依賴
● 同步遷移性能差,不支持大key遷移
codis 3.x
● 最新 release 版本為 codis-3.2,codis-server 基於 redis-3.2.8
● 支持 slot 同步遷移、異步遷移和並發遷移,對 key 大小無任何限製,遷移性能大幅度提升
● 相比 2.0:重構了整個集群組件通信方式,codis-proxy 與 zookeeper 實現了解耦,廢棄了codis-config 等
● 元數據存儲支持 etcd/zookeeper/filesystem 等,可自行擴展支持新的存儲,集群正常運行期間,即便元存儲故障也不再影響 codis 集群,大大提升 codis-proxy 穩定性
● 對 codis-proxy 進行了大量性能優化,通過控製GC頻率、減少對象創建、內存預分配、引入 cgo、jemalloc 等,使其吞吐還是延遲,都已達到 codis 項目中最佳
● proxy 實現 select 命令,支持多 DB
● proxy 支持讀寫分離、優先讀同 IP/同 DC 下副本功能
● 基於 redis-sentinel 實現主備自動切換
● 實現動態 pipeline 緩存區(減少內存分配以及所引起的 GC 問題)
● proxy 支持通過 HTTP 請求實時獲取 runtime metrics,便於監控、運維
● 支持通過 influxdb 和 statsd 采集 proxy metrics
● slot auto rebalance 算法從 2.0 的基於 max memory policy 變更成基於 group 下 slot 數量
● 提供了更加友好的 dashboard 和 fe 界麵,新增了很多按鈕、跳轉鏈接、錯誤狀態等,有利於快速發現、處理集群故障
● 新增 SLOTSSCAN 指令,便於獲取集群各個 slot 下的所有 key
● codis-proxy 與 codis-dashbaord 支持 docker 部
Codis 3.x 由以下組件組成:
● Codis Server:基於 redis-3.2.8 分支開發。增加了額外的數據結構,以支持 slot 有關的操作以及數據遷移指令。具體的修改可以參考文檔 redis 的修改。
● Codis Proxy:客戶端連接的 Redis 代理服務, 實現了 Redis 協議。 除部分命令不支持以外(不支持的命令列表),表現的和原生的 Redis 沒有區別(就像 Twemproxy)。
○ 對於同一個業務集群而言,可以同時部署多個 codis-proxy 實例;
○ 不同 codis-proxy 之間由 codis-dashboard 保證狀態同步。
● Codis Dashboard:集群管理工具,支持 codis-proxy、codis-server 的添加、刪除,以及據遷移等操作。在集群狀態發生改變時,codis-dashboard 維護集群下所有 codis-proxy 的狀態的一致性。
○ 對於同一個業務集群而言,同一個時刻 codis-dashboard 隻能有 0個或者1個;
○ 所有對集群的修改都必須通過 codis-dashboard 完成。
● Codis Admin:集群管理的命令行工具。
○ 可用於控製 codis-proxy、codis-dashboard 狀態以及訪問外部存儲。
● Codis FE:集群管理界麵。
○ 多個集群實例共享可以共享同一個前端展示頁麵;
○ 通過配置文件管理後端 codis-dashboard 列表,配置文件可自動更新。
● Storage:為集群狀態提供外部存儲。
○ 提供 Namespace 概念,不同集群的會按照不同 product name 進行組織;
○ 目前僅提供了 Zookeeper、Etcd、Fs 三種實現,但是提供了抽象的 interface 可自行擴展。
下載與編譯
下載release binary文件安裝
如果是重要的生產環境使用,盡量不要選擇alpha、rc版本。 根據自己的部署平台,選擇相應的文件下載即可。
編譯源碼安裝
1、安裝 Go 運行環境 參考這裏
安裝完成後可以運行下列命令進行檢測:
- 1
- 2
2、 設置編譯環境
注意 $GOPATH 是本機所有第三方庫 go 項目所在目錄,Codis 僅是其中之一。
添加 $GOPATH/bin 到 $PATH,例如:
- 1
- 2
- 3
3、下載 Codis 源代碼
Codis 源代碼需要下載到
- 1
- 2
- 3
4、編譯 Codis 源代碼
● 直接通過 make 進行編譯,會看到如下輸出:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
快速啟動
2分鍾快速構建一個單機版測試 codis 集群,無任何外部組件依賴.
源碼中 admin 文件夾提供了一係列腳本以便快速啟動、停止各個組件,提高運維效率。
啟動codis-dashboard
使用 codis-dashboard-admin.sh 腳本啟動 dashboard,並查看 dashboard 日誌確認啟動是否有異常。
- 1
- 2
- 3
- 4
- 5
- 6
快速啟動集群元數據存儲使用 filesystem,默認數據路徑保存在 /tmp/codis,若啟動失敗,請檢查當前用戶是否對該路徑擁有讀寫權限。
啟動codis-proxy
使用 codis-proxy-admin.sh 腳本啟動 codis-proxy,並查看 proxy 日誌確認啟動是否有異常。
- 1
- 2
- 3
- 4
- 5
- 6
啟動codis-server
使用 codis-server-admin.sh 腳本啟動 codis-server,並查看 redis 日誌確認啟動是否有異常。
- 1
- 2
- 3
- 4
- 5
redis.conf 配置中 pidfile、logfile 默認保存在 /tmp 目錄,若啟動失敗,請檢查當前用戶是否有該目錄的讀寫權限。
啟動codis-fe
使用 codis-fe-admin.sh 腳本啟動 codis-fe,並查看 fe 日誌確認啟動是否有異常。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
通過fe添加group
通過web瀏覽器訪問集群管理頁麵(fe地址:127.0.0.1:9090) 選擇我們剛搭建的集群 codis-demo,在 Proxy 欄可看到我們已經啟動的 Proxy, 但是 Group 欄為空,因為我們啟動的 codis-server 並未加入到集群 添加 NEW GROUP,NEW GROUP 行輸入 1,再點擊 NEW GROUP 即可 添加 Codis Server,Add Server 行輸入我們剛剛啟動的 codis-server 地址,添加到我們剛新建的 Group,然後再點擊 Add Server 按鈕即可,如下圖所示
通過fe初始化slot
新增的集群 slot 狀態是 offline,因此我們需要對它進行初始化(將 1024 個 slot 分配到各個 group),而初始化最快的方法可通過 fe 提供的 rebalance all slots 按鈕來做,如下圖所示,點擊此按鈕,我們即快速完成了一個集群的搭建。
通過 ansible 快速部署集群
使用 ansible 可快速在單機、多機部署多套 codis 集群。 ansible 文件夾包含了部署 codis 集群的 playbook,根據自己部署環境修改 groups_var/all 文件裏參數,修改 hosts 文件添加部署的環境 IP 即可。 ansible 安裝也及其簡單,各部署機器無需安裝任何額外的 agent,彼此之間通過 ssh 通信。
- 1
- 2
- 3
- 4
- 5
啟動參數
注意:請按照順序逐步完成操作。生產環境建議修改dashboard coordinator_name配置,使用 zookeeper 或etctd作為外部存儲。
注意:Codis 3.x 支持 AUTH,但是要求所有組件使用的 AUTH 必須完全相同。
Codis Dashboard
1、啟動命令
- 1
- 2
默認配置文件 dashboard.toml 可由 codis-dashboard 生成。
2、詳細說明
● 啟動參數說明:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
● 默認配置文件:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
1、啟動命令
- 1
- 2
默認配置文件 proxy.toml 可由 codis-proxy 生成。
codis-proxy 啟動後,處於 waiting 狀態,監聽 proxy_addr 地址,但是不會 accept 連接,添加到集群並完成集群狀態的同步,才能改變狀態為 online。添加的方法有以下兩種:
● 通過 codis-fe 添加:通過 Add Proxy 按鈕,將 admin_addr 加入到集群中;
● 通過 codis-admin 命令行工具添加,方法如下:
$ ./bin/codis-admin –dashboard=127.0.0.1:18080 –create-proxy -x 127.0.0.1:11080
其中 127.0.0.1:18080 以及 127.0.0.1:11080 分別為 dashboard 和 proxy 的 admin_addr 地址;
添加過程中,dashboard 會完成如下一係列動作:
● 獲取 proxy 信息,對集群 name 以及 auth 進行驗證,並將其信息寫入到外部存儲中;
● 同步 slots 狀態;
● 標記 proxy 狀態為 online,此後 proxy 開始 accept 連接並開始提供服務;
2、詳細說明
● 啟動參數說明:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
● 默認配置文件:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
參數說明product_name集群名稱,參考 dashboard 參數說明product_auth集群密碼,默認為空admin_addrRESTful API 端口proto_typeRedis 端口類型,接受 tcp/tcp4/tcp6/unix/unixpacketproxy_addrRedis 端口地址或者路徑jodis_addrJodis 注冊 zookeeper 地址jodis_timeoutJodis 注冊 session timeout 時間,單位 secondjodis_compatibleJodis 注冊 zookeeper 的路徑backend_ping_period與 codis-server 探活周期,單位 second,0 表示禁止session_max_timeout與 client 連接最大讀超時,單位 second,0 表示禁止session_max_bufsize與 client 連接讀寫緩衝區大小,單位 bytesession_max_pipeline與 client 連接最大的 pipeline 大小session_keepalive_period與 client 的 tcp keepalive 周期,僅 tcp 有效,0 表示禁止
注:Codis3 會將 jodis 節點注冊在 /jodis/{PRODUCT_NAME} 下,這點與 Codis2 不太兼容,所以為了兼容性,可以考慮將 jodis_compatible 設置成 true。
Codis Server
● 啟動 ./bin/codis-server,與啟動普通 redis 的方法一致。
● 啟動完成後,可以通過 codis-fe 提供的界麵或者 codis-admin 命令行工具添加到集群中
Codis FE(可選組件)
1、啟動命令
- 1
- 2
2、詳細說明
● 啟動參數說明:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
配置文件 codis.json 可以手動編輯,也可以通過 codis-admin 從外部存儲中拉取,例如:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
Codis Admin(命令行工具)
注意:使用 codis-admin 是十分危險的。
1、codis-dashboard 異常退出的修複
當 codis-dashboard 啟動時,會在外部存儲上存放一條數據,用於存儲 dashboard 信息,同時作為 LOCK 存在。當 codis-dashboard 安全退出時,會主動刪除該數據。當 codis-dashboard 異常退出時,由於之前 LOCK 未安全刪除,重啟往往會失敗。因此 codis-admin 提供了強製刪除工具:
1. 確認 codis-dashboard 進程已經退出(很重要);
2. 運行 codis-admin 刪除 LOCK:
- 1
2、codis-proxy 異常退出的修複
通常 codis-proxy 都是通過 codis-dashboard 進行移除,移除過程中 codis-dashboard 為了安全會向 codis-proxy 發送 offline指令,成功後才會將 proxy 信息從外部存儲中移除。如果 codis-proxy 異常退出,該操作會失敗。此時可以使用 codis-admin 工具進行移除:
1. 確認 codis-proxy 進程已經退出(很重要);
2. 運行 codis-admin 刪除 proxy:
- 1
選項 –force 表示,無論 offline 操作是否成功,都從外部存儲中將該節點刪除。所以操作前,一定要確認該 codis-proxy 進程已經退出。
Jodis 與 HA
因為 codis-proxy 是無狀態的,可以比較容易的搭多個實例,達到高可用性和橫向擴展。
對 Java 用戶來說,可以使用基於 Jedis 的實現 Jodis ,來實現 proxy 層的 HA:
● 它會通過監控 zookeeper 上的注冊信息來實時獲得當前可用的 proxy 列表,既可以保證高可用性;
● 也可以通過輪流請求所有的proxy實現負載均衡。
如果需要異步請求,可以使用我們基於Netty開發的 Nedis。
對下層的 redis 實例來說,當一個 group 的 master 掛掉的時候,應該讓管理員清楚,並手動的操作,因為這涉及到了數據一致性等問題(redis的主從同步是最終一致性的)。因此 codis 不會自動的將某個 slave 升級成 master。關於外部 codis-ha 工具(具體可以參考之前的章節),這是一個通過 codis-dashboard 開放的 RESTful API 實現自動切換主從的工具。該工具會在檢測到 master 掛掉的時候主動應用主從切換策略,提升單個 slave 成為新的 master。
需要注意,codis 將其中一個 slave 升級為 master 時,該組內其他 slave 實例是不會自動改變狀態的,這些 slave 仍將試圖從舊的 master 上同步數據,因而會導致組內新的 master 和其他 slave 之間的數據不一致。因此當出現主從切換時,需要管理員手動創建新的 sync action 來完成新 master 與 slave 之間的數據同步(codis-ha 不提供自動操作的工具,因為這樣太不安全了)。
Docker 部署
Codis 3.x 起,開始正式支持 Docker 部署。這就需要 codis-dashboard 以及 codis-proxy 能夠外部的 listen 地址暴露出來並保存在外部存儲中。
● codis-proxy 增加了 –host-admin 以及 –host-proxy 參數;
● codis-dashboard 增加了 –host-admin 參數;
以 codis-proxy 的 Docker 為例:
- 1
- 2
codis-proxy 在啟動後,會使用 –host-admin 和 –host-proxy 參數所指定的實際地址替換 Docker 內監聽的地址,向 codis-dashboard 注冊。這樣,例如使用 Jodis 的過程中,客戶端就能夠通過 100.0.1.100:29000 來訪問 proxy 實例。
codis-dashboard 也是相同的道理,會使用 –host-admin 地址向外部存儲注冊,這樣 codis-fe 也能通過該地址正確的對 codis-dashboard 進行操作。
具體樣例可以參考 scripts/docker.sh。
從Codis 2.x 升級
Codis 3.x 修改了 codis-dashboard 與 codis-proxy 之間的通信方式,因此 Codis 2.x 並不兼容。但是我們提供了手動升級方案。
注意1:升級時,需要保證所有 slot 都處在 online 狀態。即沒有任何數據遷移操作正在進行。
注意2:升級完成後,需要手動關閉 Codis 2.x 的所有 proxy 和 config 組件。
step 1. 導出配置文件
- 1
該命令會從 zookeeper 上拉取 /zk/codis/db_codis_v2.0 下全部的文件,並組織成 json 格式並輸出。
選項 -1 表示配置文件是 Codis 1.x 版本,缺省是 Codis 3.x 版本。
step 2. 轉換配置文件
- 1
該命令會將 Codis 1.x 版本的配置文件中有效信息提取出來,並轉成 Codis 3.x 版本的配置文件並輸出。
step 3. 更新配置文件
注意:更新配置文件時,請確保 Codis 3.x 中該集群不存在,否則可能導致更新失敗或者集群狀態異常。
- 1
該命令會將 Codis 3.x 版本的配置文件提交到 /codis3/codis_v3.0 目錄下。
選項 –confirm 選項表示確認提交,缺省時該命令僅僅打印配置文件作為調試。
step 4. 啟動 Codis 3.x dashboard 以及 proxy
過程參考之前章節。因為集群信息已經存在,所以可以安全啟動 codis-dashboard,並逐一添加 codis-proxy 到集群中。
step 5. 關閉 Codis 2.x dashboard 以及 proxy
Codis 3.x 的組件兼容 Jodis 協議。
因為 Codis 2.x 與 Codis 3.x 在外部存儲中的組織結構不同,所以可以安全的 kill 掉全部 Codis 2.x 組件。
注意:關閉過程請不要使用 kill -9,因為舊組件在退出時會自動清理部分注冊信息。





閩公網安備 35020302001891號