Codis 3.0.1 安裝使用文件(官方)

五柳-先生發表於2016-04-19

Codis 使用文件

Codis 是一個分散式 Redis 解決方案, 對於上層的應用來說, 連線到 Codis Proxy 和連線原生的 Redis Server 沒有顯著區別 (不支援的命令列表), 上層應用可以像使用單機的 Redis 一樣使用, Codis 底層會處理請求的轉發, 不停機的資料遷移等工作, 所有後邊的一切事情, 對於前面的客戶端來說是透明的, 可以簡單的認為後邊連線的是一個記憶體無限大的 Redis 服務。

Codis 3.x 由以下元件組成:

  • Codis Server:基於 redis-2.8.21 分支開發。增加了額外的資料結構,以支援 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 列表,配置檔案可自動更新。
  • Codis HA:為叢集提供高可用。

    • 依賴 codis-dashboard 例項,自動抓取叢集各個元件的狀態;
    • 會根據當前叢集狀態自動生成主從切換策略,並在需要時通過 codis-dashboard 完成主從切換。
  • Storage:為叢集狀態提供外部儲存。

    • 提供 Namespace 概念,不同叢集的會按照不同 product name 進行組織;
    • 目前僅提供了 Zookeeper 和 Etcd 兩種實現,但是提供了抽象的 interface 可自行擴充套件。

0. 下載與編譯

1. 安裝 Go 執行環境 參考這裡

安裝完成後可以執行下列命令進行檢測:

$ go version
go version go1.5.2 linux/amd64

2. 設定編譯環境

注意 $GOPATH 是本機所有第三方庫 go 專案所在目錄,Codis 僅是其中之一。

新增 $GOPATH/bin 到 $PATH,例如:PATH=$PATH:$GOPATH/bin,並安裝 godep 工具。

$ go env GOPATH
/home/codis/gopath

$ go get -u github.com/tools/godep && which godep
/home/codis/gopath/bin/godep

3. 下載 Codis 原始碼

下載完成後,Codis 原始碼會出現在 $GOPATH/src/github.com/wandoulabs/codis 路徑下:

$ go get -u -d github.com/wandoulabs/codis

4. 編譯 Codis 原始碼

  • Codis 編譯過程使用了 godep,請確定編譯之前 godep 能正常工作。
  • 直接通過 make 進行編譯,會看到如下輸出:
$ cd $GOPATH/src/github.com/wandoulabs/codis
$ make
make -j -C extern/redis-2.8.21/
... ...
    >>>> godep: Checking dependency ... ...
    >>>> godep: Checking dependency ... ...
... ...
godep go build -i -o bin/codis-dashboard ./cmd/dashboard
godep go build -i -o bin/codis-proxy ./cmd/proxy
godep go build -i -o bin/codis-admin ./cmd/admin
godep go build -i -o bin/codis-ha ./cmd/ha
godep go build -i -o bin/codis-fe ./cmd/fe

$ ls bin/
total 69124
drwxr-xr-x 4 codis codis     4096 Jan  4 14:55 assets
-rwxr-xr-x 1 codis codis 17600752 Jan  4 14:55 codis-admin
-rwxr-xr-x 1 codis codis 18416320 Jan  4 14:55 codis-dashboard
-rwxr-xr-x 1 codis codis  9498040 Jan  4 14:55 codis-fe
-rwxr-xr-x 1 codis codis  9956328 Jan  4 14:55 codis-ha
-rwxr-xr-x 1 codis codis 11057280 Jan  4 14:55 codis-proxy
-rwxr-xr-x 1 codis codis  4234432 Jan  4 14:55 codis-server
-rw-r--r-- 1 codis codis      148 Jan  4 14:55 version

$ cat bin/version
version = 2016-01-03 14:53:22 +0800 @51f06ae3b58a256a58f857f590430977638846a3
compile = 2016-01-04 15:00:17 +0800 by go version go1.5.2 linux/amd64

網路訪問受限

  1. 在有網路環境的機器上,Codis 原始碼目錄中執行命令 make godep
    • 該操作會將 Codis 編譯所依賴的第三方原始碼下載到 Godeps/_workspace 目錄下;
  2. 在目標環境中,按照之前步驟配置好編譯環境;
    • 離線安裝 go 以及 godep 工具;
  3. 將處理過的 Codis 目錄完整複製到訪問受限的伺服器的正確的路徑下,執行 make 進行原始碼編譯。

離線安裝 godep 方法:

  1. 執行 git clone https://github.com/tools/godep.git 下載 godep 原始碼;
  2. 將 godep 目錄移動到 $GOPATH/src/github.com/tools/godep,並進入該目錄;
  3. 執行命令 go install ./,該命令會將 godep 生成到 $GOPATH/bin 下。

1. 快速啟動

原始碼中提供了可供本地測試使用的指令碼 scripts/demo.sh,該指令碼會生成一個本地叢集。

注意:指令碼依賴 etcd 作為外部儲存,啟動時會建立一個佔用 2379 埠的 etcd 例項;如果本地已經存在該例項,會導致可能汙染該例項(寫入測試程式所需配置檔案)並最終啟動失敗。

  • 指令碼會輸出每一個程式的 PID,並將每個例項的日誌會輸出到 tmp 目錄下;
  • 啟動後,可以通過 http://127.0.0.1:8080 來訪問 codis-fe。
$ which etcd &>/dev/null || go get github.com/coreos/etcd
$ bash demo.sh
etcd.pid=81455
codis-server-16379.pid=81456
... ...
proxy-11080x19000.pid=81465
... ...
dashboard.pid=81473
fe.pid=81475
done
Mon Jan  4 15:10:44 CST 2016
Mon Jan  4 15:11:14 CST 2016
... ...

2. 啟動及引數

注意:請按照順序逐步完成操作。預設使用 zookeeper 作為外部儲存。

注意:Codis 3.x 支援 AUTH,但是要求所有元件使用的 AUTH 必須完全相同。

2.1 Codis Dashboard

2.1.1 啟動命令:
$ nohup ./bin/codis-dashboard --ncpu=4 --config=dashboard.toml \
    --log=dashboard.log --log-level=WARN &

預設配置檔案 dashboard.toml 可由 codis-dashboard 生成。

2.1.2 詳細說明:
  • 啟動引數說明:
$ ./bin/codis-dashboard -h
Usage:
    codis-dashboard [--ncpu=N] [--config=CONF] [--log=FILE] [--log-level=LEVEL] [--host-admin=ADDR]
    codis-dashboard  --default-config
    codis-dashboard  --version

Options:
    --ncpu=N                    最大使用 CPU 個數
    -c CONF, --config=CONF      指定啟動配置檔案
    -l FILE, --log=FILE         設定 log 輸出檔案
    --log-level=LEVEL           設定 log 輸出等級:INFO,WARN,DEBUG,ERROR;預設INFO,推薦WARN

引數 --host-admin 請參見與 Docker 有關章節。

  • 預設配置檔案:
$ ./bin/codis-dashboard --default-config | tee dashboard.toml
##################################################
#                                                #
#                  Codis-Dashboard               #
#                                                #
##################################################

# Set Coordinator, only accept "zookeeper" & "etcd"
coordinator_name = "zookeeper"
coordinator_addr = "127.0.0.1:2181"

# Set Codis Product {Name/Auth}.
product_name = "codis-demo"
product_auth = ""

# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:18080"
引數 說明
coordinator_name 外部儲存型別,接受 zookeeper/etcd
coordinator_addr 外部儲存地址
product_name 叢集名稱,滿足正則 \w[\w\.\-]*
product_auth 叢集密碼,預設為空
admin_addr RESTful API 埠

2.2 Codis Proxy

2.2.1 啟動命令:
$ nohup ./bin/codis-proxy --ncpu=4 --config=proxy.toml \
    --log=proxy.log --log-level=WARN &

預設配置檔案 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.2.2 詳細說明:
  • 啟動引數說明:
$ ./bin/codis-proxy -h
Usage:
    codis-proxy [--ncpu=N] [--config=CONF] [--log=FILE] [--log-level=LEVEL] [--host-admin=ADDR] [--host-proxy=ADDR] [--ulimit=NLIMIT]
    codis-proxy  --default-config
    codis-proxy  --version

Options:
    --ncpu=N                    最大使用 CPU 個數
    -c CONF, --config=CONF      指定啟動配置檔案
    -l FILE, --log=FILE         設定 log 輸出檔案
    --log-level=LEVEL           設定 log 輸出等級:INFO,WARN,DEBUG,ERROR;預設INFO,推薦WARN
    --ulimit=NLIMIT             檢查 ulimit -n 的結果,確保執行時最大檔案描述不少於 NLIMIT

引數 --host-proxy 以及 --host-admin 請參見與 Docker 有關章節。

  • 預設配置檔案:
$ ./bin/codis-proxy --default-config | tee proxy.toml
##################################################
#                                                #
#                  Codis-Proxy                   #
#                                                #
##################################################

# Set Codis Product {Name/Auth}.
product_name = "codis-demo"
product_auth = ""

# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:11080"

# Set bind address for proxy, proto_type can be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
proto_type = "tcp4"
proxy_addr = "0.0.0.0:19000"

# Set jodis address & session timeout.
jodis_addr = ""
jodis_timeout = 10

# Proxy will ping-pong backend redis periodly to keep-alive
backend_ping_period = 5

# If there is no request from client for a long time, the connection will be droped. Set 0 to disable.
session_max_timeout = 1800

# Buffer size for each client connection.
session_max_bufsize = 131072

# Number of buffered requests for each client connection.
# Make sure this is higher than the max number of requests for each pipeline request, or your client may be blocked.
session_max_pipeline = 1024

# Set period between keep alives. Set 0 to disable.
session_keepalive_period = 60
引數 說明
product_name 叢集名稱,參考 dashboard 引數說明
product_auth 叢集密碼,預設為空
admin_addr RESTful API 埠
proto_type Redis 埠型別,接受 tcp/tcp4/tcp6/unix/unixpacket
proxy_addr Redis 埠地址或者路徑
jodis_addr Jodis 註冊 zookeeper 地址
jodis_timeout Jodis 註冊 session timeout 時間,單位 second
backend_ping_period 與 codis-server 探活週期,單位 second,0 表示禁止
session_max_timeout 與 client 連線最大讀超時,單位 second,0 表示禁止
session_max_bufsize 與 client 連線讀寫緩衝區大小,單位 byte
session_max_pipeline 與 client 連線最大的 pipeline 大小
session_keepalive_period 與 client 的 tcp keepalive 週期,僅 tcp 有效,0 表示禁止

2.3 Codis Server

  • 啟動 ./bin/codis-server,與啟動普通 redis 的方法一致。

  • 啟動完成後,可以通過 codis-fe 提供的介面或者 codis-admin 命令列工具新增到叢集中。

2.4 Codis FE(可選元件)

2.4.1 啟動命令:
$ nohup ./bin/codis-fe --ncpu=4 --log=fe.log --log-level=WARN \
    --dashboard-list=codis.json --listen=127.0.0.1:8080 &
2.4.2 詳細說明:
  • 啟動引數說明:
$ ./bin/codis-fe -h
Usage:
    codis-fe [--ncpu=N] [--log=FILE] [--log-level=LEVEL] --dashboard-list=LIST --listen=ADDR
    codis-fe  --version

Options:
    --ncpu=N                        最大使用 CPU 個數
    -d LIST, --dashboard-list=LIST  配置檔案,能夠自動重新整理
    -l FILE, --log=FILE             設定 log 輸出檔案
    --log-level=LEVEL               設定 log 輸出等級:INFO,WARN,DEBUG,ERROR;預設INFO,推薦WARN
    --listen=ADDR                   HTTP 服務埠

配置檔案 codis.json 可以手動編輯,也可以通過 codis-admin 從外部儲存中拉取,例如:

$ ./bin/codis-admin --dashboard-list --zookeeper=127.0.0.1:2181 | tee codis.json
[
    {
        "name": "codis-demo",
        "dashboard": "127.0.0.1:18080"
    },
    {
        "name": "codis-demo2",
        "dashboard": "127.0.0.1:28080"
    }
]

2.5 Codis HA(可選元件)

2.5.1 啟動命令:
$ nohup ./bin/codis-fe --log=ha.log --log-level=WARN --dashboard=127.0.0.1:18080 &
2.5.2 詳細說明:
$ ./bin/codis-ha -h
Usage:
    codis-ha [--log=FILE] [--log-level=LEVEL] --dashboard=ADDR
    codis-ha  --version

Options:
    -l FILE, --log=FILE         設定 log 輸出檔案
    --log-level=LEVEL           設定 log 輸出等級:INFO,WARN,DEBUG,ERROR;預設INFO,推薦WARN
2.5.3 工作原理:

注意:Codis HA 工具僅僅是 Codis 叢集 HA 的一部分,單獨工作能力有限。

  • 以 5s 為週期,codis-ha 會從 codis-dashboard 中拉取叢集狀態,並根據叢集狀態生成主從切換策略;
  • 當叢集中 codis-server 出現故障時,codis-ha 會根據之前確定的替換策略,向 codis-dashboard 發出主從切換指令;

  • codis-ha 在以下狀態下會退出:

    1. 從 codis-dashboard 獲取叢集狀態失敗時;
    2. 向 codis-dashboard 傳送主從切換指令失敗時;
  • codis-ha 在以下狀態下無法為 group 生成替換策略:

    1. group 中沒有健康的 codis-server 時;
    2. group 中所有健康的 codis-server 都不滿足如下條件時:
      • slave.master == group.master && slave.master_status == up
  • codis-ha 在以下狀態下無法應用替換策略:

    1. 存在 proxy 狀態異常;
      • 因為主從切換需要全部 proxy 確認,因此如果 proxy 狀態異常必然導致主從切換失敗;
    2. 故障 codis-server 所在 group 沒有可靠替換策略時;

注意:因此,應用 codis-ha 時還需要結合對 codis-proxy 和 codis-server 的可用性監控,否則 codis-ha 無法保證可靠性。

2.6 Codis Admin(命令列工具)

注意:使用 codis-admin 是十分危險的。

2.6.1 codis-dashboard 異常退出的修復

當 codis-dashboard 啟動時,會在外部儲存上存放一條資料,用於儲存 dashboard 資訊,同時作為 LOCK 存在。當 codis-dashboard 安全退出時,會主動刪除該資料。當 codis-dashboard 異常退出時,由於之前 LOCK 未安全刪除,重啟往往會失敗。因此 codis-admin 提供了強制刪除工具:

  1. 確認 codis-dashboard 程式已經退出(很重要);
  2. 執行 codis-admin 刪除 LOCK:
$ ./bin/codis-admin --remove-lock --product=codis-demo --zookeeper=127.0.0.1:2181
2.6.2 codis-proxy 異常退出的修復

通常 codis-proxy 都是通過 codis-dashboard 進行移除,移除過程中 codis-dashboard 為了安全會向 codis-proxy 傳送 offline 指令,成功後才會將 proxy 資訊從外部儲存中移除。如果 codis-proxy 異常退出,該操作會失敗。此時可以使用 codis-admin 工具進行移除:

  1. 確認 codis-proxy 進城已經退出(很重要);
  2. 執行 codis-admin 刪除 proxy:
$ ./bin/codis-admin --dashboard=127.0.0.1:18080 --remove-proxy --addr=127.0.0.1:11080 --force

選項 --force 表示,無論 offline 操作是否成功,都從外部儲存中將該節點刪除。所以操作前,一定要確認該 codis-proxy 程式已經退出。

3. 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 不提供自動操作的工具,因為這樣太不安全了)。

4. Docker 部署

Codis 3.x 起,開始正式支援 Docker 部署。這就需要 codis-dashboard 以及 codis-proxy 能夠外部的 listen 地址暴露出來並儲存在外部儲存中。

  • codis-proxy 增加了 --host-admin 以及 --host-proxy 引數;
  • codis-dashboard 增加了 --host-admin 引數;

以 codis-proxy 的 Docker 為例:

$ docker run --name "Codis-Proxy" -d -p 29000:19000 -p 21080:11080 codis-image \
    codis-proxy -c proxy.toml --host-admin 100.0.1.100:29000 --host-proxy 100.0.1.100:21080

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

5. 從Codis 2.x 升級

Codis 3.x 修改了 codis-dashboard 與 codis-proxy 之間的通訊方式,因此 Codis 2.x 並不相容。但是我們提供了手動升級方案。

注意1:升級時,需要保證所有 slot 都處在 online 狀態。即沒有任何資料遷移操作正在進行。

注意2:升級完成後,需要手動關閉 Codis 2.x 的所有 proxy 和 config 元件。

step 1. 匯出配置檔案

$ ./bin/codis-admin --config-dump --product=codis_v2.0 --zookeeper=127.0.0.1:2181 -1 | tee codis_v2.0.json

該命令會從 zookeeper 上拉取 /zk/codis/db_codis_v2.0 下全部的檔案,並組織成 json 格式並輸出。

選項 -1 表示配置檔案是 Codis 1.x 版本,預設是 Codis 3.x 版本。

step 2. 轉換配置檔案

$ ./bin/codis-admin --config-convert codis_v2.0.json | tee codis_v3.0.json

該命令會將 Codis 1.x 版本的配置檔案中有效資訊提取出來,並轉成 Codis 3.x 版本的配置檔案並輸出。

step 3. 更新配置檔案

注意:更新配置檔案時,請確保 Codis 3.x 中該叢集不存在,否則可能導致更新失敗或者叢集狀態異常。

$ ./bin/codis-admin --config-restore=codis_v3.0.json --product=codis_v3.0 --zookeeper=127.0.0.1:2181 --confirm

該命令會將 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,因為舊元件在退出時會自動清理部分註冊資訊。

原文地址:https://github.com/CodisLabs/codis

相關文章