1. 程式人生 > >CODIS3.x叢集 之 儲存叢集搭建全過程

CODIS3.x叢集 之 儲存叢集搭建全過程

作者:鄒祁峰
郵箱:[email protected]
部落格:http://blog.csdn.net/qifengzou
日期:2017.06.07
轉載請註明來自”祁峰”的CSDN部落格

Codis3.x有如下特點:

1.最新 release 版本為 codis-3.2,codis-server 基於 redis-3.2.8

2.支援 slot 同步遷移、非同步遷移和併發遷移,對 key 大小無任何限制,遷移效能大幅度提升

3.相比 2.0:重構了整個叢集元件通訊方式,codis-proxy 與 zookeeper 實現瞭解耦,廢棄了codis-config 等

4.元資料儲存支援 etcd/zookeeper/filesystem 等,可自行擴充套件支援新的儲存,叢集正常執行期間,即便元儲存故障也不再影響 codis 叢集,大大提升 codis-proxy 穩定性

5.對 codis-proxy 進行了大量效能優化,通過控制GC頻率、減少物件建立、記憶體預分配、引入 cgo、jemalloc 等,使其吞吐還是延遲,都已達到 codis 專案中最佳

6.proxy 實現 select 命令,支援多 DB

7.proxy 支援讀寫分離、優先讀同 IP/同 DC 下副本功能

8.基於 redis-sentinel 實現主備自動切換

9.實現動態 pipeline 快取區(減少記憶體分配以及所引起的 GC 問題)

10.proxy 支援通過 HTTP 請求實時獲取 runtime metrics,便於監控、運維

11.支援通過 influxdb 和 statsd 採集 proxy metrics

12.slot auto rebalance 演算法從 2.0 的基於 max memory policy 變更成基於 group 下 slot 數量

13.提供了更加友好的 dashboard 和 fe 介面,新增了很多按鈕、跳轉連結、錯誤狀態等,有利於快速發現、處理叢集故障

14.新增 SLOTSSCAN 指令,便於獲取叢集各個 slot 下的所有 key

15.codis-proxy 與 codis-dashbaord 支援 docker 部署

1 大體架構

1.1 總體架構

系統架構

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

1.Codis Server:基於 redis-3.2.8 分支開發。增加了額外的資料結構,以支援 slot 有關的操作以及資料遷移指令。具體的修改可以參考文件 redis 的修改。

2.Codis Proxy:客戶端連線的 Redis 代理服務, 實現了 Redis 協議。 除部分命令不支援以外(不支援的命令列表),表現的和原生的 Redis 沒有區別(就像 Twemproxy)。
- 對於同一個業務叢集而言,可以同時部署多個 codis-proxy 例項;
- 不同 codis-proxy 之間由 codis-dashboard 保證狀態同步。

3.Redis sentinel:Redis官方推薦的高可用性(HA)解決方案。它可以實現對Redis的監控、通知、自動故障轉移。如果Master不能工作,則會自動啟動故障轉移程序,將其中的一個Slave提升為Master,其他的Slave重新設定新的Master服務。

4.Codis Dashboard:叢集管理工具,支援 codis-proxy、codis-server 的新增、刪除,以及據遷移等操作。在叢集狀態發生改變時,codis-dashboard 維護叢集下所有 codis-proxy 的狀態的一致性。
- 對於同一個業務叢集而言,同一個時刻 codis-dashboard 只能有 0個或者1個;
- 所有對叢集的修改都必須通過 codis-dashboard 完成。

5.Codis Admin:叢集管理的命令列工具。
- 可用於控制 codis-proxy、codis-dashboard 狀態以及訪問外部儲存。

6.Codis FE:叢集管理介面。
- 多個叢集例項共享可以共享同一個前端展示頁面;
- 通過配置檔案管理後端codis-dashboard列表,配置檔案可自動更新。

7.Storage:為叢集狀態提供外部儲存。
- 提供namespace概念,不同叢集的會按照不同product name進行組織;
- 目前僅提供了zookeeper、etcd、filesystem三種實現,但是提供了抽象的 interface 可自行擴充套件。

1.2 部署規劃

當前本人擁有如下14臺機器,其相關資訊及部署規劃如下:[備註:實際部署過程中可以複用機器 降低成本]

序號 IP 主機名 部署程式
01 192.168.1.11 WebServer-11 codis-server:(6379&6380)
02 192.168.1.12 WebServer-12 codis-server:(6379&6380)
03 192.168.1.13 WebServer-13 codis-server:(6379&6380)
04 192.168.1.14 WebServer-14 codis-server:(6379&6380)
05 192.168.1.15 WebServer-15 codis-server:(6379&6380)
06 192.168.1.21 WebServer-21 codis-proxy:19000
07 192.168.1.22 WebServer-22 codis-proxy:19000
08 192.168.1.31 WebServer-31 codis-dashborad:18080、codis-fe:18090
09 192.168.1.41 WebServer-41 redis-sentinel:26379
10 192.168.1.42 WebServer-42 redis-sentinel:26379
11 192.168.1.43 WebServer-43 redis-sentinel:26379
12 192.168.1.51 WebServer-51 zookeeper:2181
13 192.168.1.52 WebServer-52 zookeeper:2181
14 192.168.1.53 WebServer-53 zookeeper:2181

2 部署流程

2.1 安裝ZK

作用:用於存放資料路由表。
描述:zookeeper簡稱zk。在生產環境中,zk部署越多,其可靠性越高。由於zk叢集是以宕機個數過半才會讓整個叢集宕機,因此,奇數個zk更佳。
部署:按照1.2中的部署規劃,將在如下幾臺機器上部署該程式。

序號 IP 主機名 部署程式
01 192.168.1.51 WebServer-51 zookeeper:2181
02 192.168.1.52 WebServer-52 zookeeper:2181
03 192.168.1.53 WebServer-53 zookeeper:2181

步驟
1. 下載原始碼
下載原始碼,並解壓至/usr/local/zookeeper目錄。

2. 安裝java包

#yum -y install java # 安裝java包

3. 配置程式
第一步:新增域名
編輯/etc/hosts檔案,並新增以下配置。[注:在192.168.1.51~53上都完全一樣]

#vim /etc/hosts #新增域名

192.168.1.51 zookeeper-node1
192.168.1.52 zookeeper-node2
192.168.1.53 zookeeper-node3

第二步:修改zk配置
編輯配置檔案,並新增以下配置:[注:在192.168.1.51~53上都完全一樣]

#cd /usr/local/zookeeper #安裝目錄
#vim ./conf/zoo.cfg #編輯配置

maxClientCnxns=50 #最大連線數設定. 注:可不配置.
tickTime=2000 #一個週期(tick)的時長(單位:毫秒). 注:可用預設值
initLimit=10 #初始化同步階段最多耗費tick個數. 注:可用預設值
syncLimit=5 #等待應答的最大間隔tick個數. 注:可用預設值
dataDir=/data/zookeeper/ #資料儲存目錄. 注:勿放在/tmp目錄
clientPort=2181 #幀聽埠. 注:可用預設值
server.1=zookeeper-node1:2888:3888
server.2=zookeeper-node2:2888:3888
server.3=zookeeper-node3:2888:3888

說明:server.A=B:C:D:其中 A 是一個數字,表示這個是第幾號伺服器;B 是這個伺服器的 ip 地址;C 表示的是這個伺服器與叢集中的 Leader 伺服器交換資訊的埠;D 表示的是萬一叢集中的 Leader 伺服器掛了,需要一個埠來重新進行選舉,選出一個新的 Leader,而這個埠就是用來執行選舉時伺服器相互通訊的埠。如果是偽叢集的配置方式,由於 B 都是一樣,所以不同的 Zookeeper 例項通訊埠號不能一樣,所以要給它們分配不同的埠號。

第三步:其他處理
建立第二步中的dataDir目錄,並設定當前zk的結點ID。[注:在192.168.1.51~53上ID值各不相同]

#mkdir -p /data/zookeeper #建立zk資料目錄(datadir)
#echo “1” > /data/zookeeper/myid #生成ID,這裡需要注意, myid對應的zoo.cfg的server.ID.比如zookeeper-node2對應的myid應該是2.
/usr/lib/zookeeper/bin/Server.sh start #服務啟動

4. 啟動程式
需要在192.168.1.51~53上依次執行以下命令。

#cd /usr/local/zookeeper/ #安裝目錄

#./bin/Server.sh start #服務啟動

2.2 編譯Codis

請在以下機器列表上按步驟[2.2.1~2.2.3]安裝codis環境:

序號 IP 主機名 部署程式
01 192.168.1.11 WebServer-11 codis-server:(6379&6380)
02 192.168.1.12 WebServer-12 codis-server:(6379&6380)
03 192.168.1.13 WebServer-13 codis-server:(6379&6380)
04 192.168.1.14 WebServer-14 codis-server:(6379&6380)
05 192.168.1.15 WebServer-15 codis-server:(6379&6380)
06 192.168.1.21 WebServer-21 codis-proxy:19000
07 192.168.1.22 WebServer-22 codis-proxy:19000
08 192.168.1.31 WebServer-31 codis-dashborad:18080、codis-fe:18090
09 192.168.1.41 WebServer-41 redis-sentinel:6379
10 192.168.1.42 WebServer-42 redis-sentinel:6379
11 192.168.1.43 WebServer-43 redis-sentinel:6379

步驟
1. 安裝go環境
先從官網(https://golang.org/dl/)下載golang安裝包,並將其解壓,再拷貝至/usr/local/go/中,最後配置如下環境變數。

#vim $HOME/.bashrc

export GOROOT=/usr/local/go # 安裝路徑
export GOPATH=$HOME/godir # 工作路徑
export PATH=$PATH:$GOPATH/bin:$GOROOT/bin # 命令搜尋路徑

2. 下載codis原始碼
需要在如下每臺機器上下載codis原始碼,原始碼下載命令為:

#go get github.com/CodisLabs/codis.git -b release3.2

3. 編譯codis原始碼

#cd $GOPATH/src/github.com/CodisLabs/ # 原始碼目錄

#make # 執行編譯

#ls ./bin/ # 檢視結果
codis-admin codis-dashboard codis-fe codis-ha codis-proxy codis-server redis-benchmark redis-cli

完成編譯後,將會在bin目錄中看到codis-admin、codis-dashboard、codis-fe、codis-ha、codis-proxy、codis-server六個可執行檔案。另外,bin/assert資料夾是codis-dashboard的http服務需要的前端資源,其需要和codis-dashboard放置在同一個資料夾中。
補充:在目錄./extern/redis-3.2.8/src/中可以找到redis-sentinel可執行檔案,其將會用於叢集主從的切換。

4. 拷貝codis程式

#sudo mkdir -p /usr/local/codis/bin

#cp -fr $GOPATH/github.com/CodisLabs/codis/bin/* /usr/local/codis/bin/
#cp -fr $GOPATH/github.com/CodisLabs/codis/conf/* /usr/local/codis/conf/

2.3 Codis-server

作用:基於 redis-3.2.8 分支開發。增加了額外的資料結構,以支援 slot 有關的操作以及資料遷移指令。具體的修改可以參考文件 redis 的修改。

部署:按照1.2中的部署規劃,將在如下機器上部署該程式。

序號 IP 主機名 部署程式
01 192.168.1.11 WebServer-11 codis-server:(6379&6380)
02 192.168.1.12 WebServer-12 codis-server:(6379&6380)
03 192.168.1.13 WebServer-13 codis-server:(6379&6380)
04 192.168.1.14 WebServer-14 codis-server:(6379&6380)
05 192.168.1.15 WebServer-15 codis-server:(6379&6380)

步驟:
1. 修改主配置

#cd /usr/local/codis/conf/

#cp redis.conf redis-6379.conf # 主配置

#vim redis-6379.conf # 修改配置

daemonize yes
pidfile /usr/loca/codis/proc/redis-6379.pid # 程序ID檔案路徑
port 6379 # 繫結埠
timeout 86400
tcp-keepalive 60
loglevel notice
logfile /usr/local/codis/log/redis-6379.log # 日誌檔案路徑
databases 16
save “”
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error no
rdbcompression yes
dbfilename dump-6379.rdb # dump檔案
dir /usr/local/codis/data/redis_data_6379 # dump路徑
masterauth "123456" # Master密碼(從主同步密碼)
slave-serve-stale-data yes
repl-disable-tcp-nodelay no
slave-priority 100
requirepass "123456" # 鑑權密碼(客戶端連線密碼)
maxmemory 10gb
maxmemory-policy allkeys-lru
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mblua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 0 0 0
client-output-buffer-limit pubsub 0 0 0
hz 10
aof-rewrite-incremental-fsync yes
repl-backlog-size 33554432

2. 修改從配置

#cd /usr/local/codis/conf/

#cp redis.conf redis-6380.conf # 主配置

#vim redis-6380.conf # 修改配置

daemonize yes
pidfile /usr/loca/codis/proc/redis-6380.pid # 程序ID檔案路徑
port 6380 # 繫結埠
timeout 86400
tcp-keepalive 60
loglevel notice
logfile /usr/local/codis/log/redis-6380.log # 日誌檔案路徑
databases 16
save “” # 如果不希望儲存到磁碟,則可以使用井號登出save配置行
save 900 1 # 如果不希望儲存到磁碟,則可以使用井號登出save配置行
save 300 10 # 如果不希望儲存到磁碟,則可以使用井號登出save配置行
save 60 10000 # 如果不希望儲存到磁碟,則可以使用井號登出save配置行
stop-writes-on-bgsave-error no
rdbcompression yes
dbfilename dump-6380.rdb # dump檔案
dir /usr/local/codis/data/redis_data_6380 # dump路徑
masterauth "123456" # Master密碼(適合主從叢集)
slave-serve-stale-data yes
repl-disable-tcp-nodelay no
slave-priority 100
requirepass "123456" # 鑑權密碼(客戶端連線密碼)
maxmemory 10gb
maxmemory-policy allkeys-lru
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mblua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 0 0 0
client-output-buffer-limit pubsub 0 0 0
hz 10
aof-rewrite-incremental-fsync yes
repl-backlog-size 33554432

3. 啟動程式

#cd /usr/local/codis/bin/
#./codis-server ../conf/redis-6379.conf & #啟動主程式
#./codis-server ../conf/redis-6380.conf & #啟動從程式

所有機器完成以上五個步驟後,便完成了對codis-server的啟動。

2.4 Codis-dashboard

作用:叢集管理工具,支援 codis-proxy、codis-server 的新增、刪除,以及據遷移等操作。在叢集狀態發生改變時,codis-dashboard 維護叢集下所有 codis-proxy 的狀態的一致性。

1.對於同一個業務叢集而言,同一個時刻 codis-dashboard 只能有 0個或者1個;
2.所有對叢集的修改都必須通過 codis-dashboard 完成。

部署:按照1.2中的部署規劃,將在如下機器上部署該程式。

序號 IP 主機名 部署程式
08 192.168.1.31 WebServer-31 codis-dashborad:18080、codis-fe:18090

步驟:
1. 修改配置

#cd /usr/local/codis/bin/
#./codis-dashboard - -default-conifg | tee ../conf/dashboard.conf #生成配置
#vim ../conf/dashboard.conf # 修改配置

coordinator_name = "zookeeper" # 外部儲存型別
coordinator_addr = "192.168.1.51:2181,192.168.1.52:2181,192.168.1.53:2181" # 外部儲存IP列表

product_name = "chatroom" # 專案名稱
product_auth = “123456” # 叢集密碼(注意:需要與redis配置中的requirepass保持一致)

admin_addr = "0.0.0.0:18080" # RESTful API 埠

為了防止出現dashboard監控頁面中OPS始終為0的現象,需要將各proxy的IP和主機名寫到hosts檔案中。

#vim /etc/hosts # 新增域名

192.168.1.21 WebSocket-21
192.168.1.22 WebSocket22

2. 啟動程式

#cd ./bin/
#nohup ./codis-dashboard - -ncpu=24 - -config=/usr/local/codis/conf/dashboard.conf - -log=/usr/local/codis/log/dashboard.log - -log-level=WARN & #啟動程式(注意:使用絕對路徑)

引數描述如下:

序號 引數 描述 備註
01 - -ncpu 最大使用CPU個數
02 - -config 指定配置路徑和檔案 使用絕對路徑
03 - -log 指定日誌輸出路徑和檔案 使用絕對路徑
02 - -log-level 指定日誌級別 取值:INFO、WARN、DEBUG、ERROR,推薦使用WRAN.

完成以上2個步驟後,便完成了對codis-config的安裝。
3. 關閉程式
如果想關閉dashboard服務,可執行:

#./codis-admin - -dashboard=192.168.1.31:18080 –auth=123456 - -shutdown

2.5 Codis-proxy

作用:客戶端連線的 Redis 代理服務, 實現了 Redis 協議。 除部分命令不支援以外(不支援的命令列表),表現的和原生的 Redis 沒有區別(就像 Twemproxy)。

1.對於同一個業務叢集而言,可以同時部署多個 codis-proxy 例項;
2.不同 codis-proxy 之間由 codis-dashboard 保證狀態同步。

部署:按照2.1中的用途規劃,將在如下幾臺機器上部署該程式。

序號 IP 主機名 部署程式
01 192.168.1.21 WebServer-21 codis-proxy
02 192.168.1.22 WebServer-22 codis-proxy

步驟:
1. 修改配置

#cd /usr/local/codis/bin/

#./codis-proxy - -default-config | tee ../conf/proxy.conf # 生成配置

#vim ../proxy.conf #修改配置

product_name = "chatroom" # 設定專案名
product_auth = "123456" # 設定登入dashboard的密碼(注意:與redis中requirepass一致

session_auth = "56789" # Redis客戶端的登入密碼(注意:與redis中requirepass不一致
# 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" #繫結埠(Redis客戶端連線此埠)
# 外部儲存
jodis_name = "zookeeper" # 外部儲存型別
jodis_addr = “192.168.1.51:2181,192.168.1.52:2181,192.168.1.53:2181” # 外部儲存列表
jodis_timeout = “20s”
#會話設定
session_recv_timeout = “0s” #如果不為0可能導致應用程式出現”write: broken pipe”的問題

備註:其他引數使用預設配置….

2.啟動程式

#nohup ./codis-proxy - -ncpu=24 - -config=../conf/proxy.conf - -log=../log/proxy.log - -log-level=WRAN &

程式codis-proxy啟動後,仍然處於waiting狀態,雖然偵聽了proxy_addr埠,但是不會accept連線請求。只有將codis-proxy加入到叢集並完成叢集狀態的同步,才能將狀態改為online。最終才能accept連線請求。

2.6 Redis-sentinel

作用:Redis官方推薦的高可用性(HA)解決方案。它可以實現對Redis的監控、通知、自動故障轉移。如果Master不能工作,則會自動啟動故障轉移程序,將其中的一個Slave提升為Master,其他的Slave重新設定新的Master服務。
部署:按照1.2中的部署規劃,將在如下機器上部署該程式。

序號 IP 主機名 部署程式
09 192.168.1.41 WebServer-41 redis-sentinel:26379
10 192.168.1.42 WebServer-42 redis-sentinel:26379
11 192.168.1.43 WebServer-43 redis-sentinel:26379

步驟
1. 拷貝程式

#cp -fr $GOPATH/github.com/CodisLabs/codis/extern/redis-3.2.8/src/redis-sentinel /usr/local/codis/bin/

2. 拷貝配置

#cp -fr $GOPATH/github.com/CodisLabs/codis/extern/redis-3.2.8/sentinel.conf /usr/local/codis/conf/

3. 修改配置

#cd /usr/local/codis/
#vim ./conf/sentinel.conf

bind 0.0.0.0
protected-mode no
port 26379
dir “/usr/local/codis/data/

備註:其他結點的配置與此一致。

4. 啟動程式

cd /usr/local/codis/bin/
nohup ./redis-sentinel ../conf/sentinel.conf &

2.7 Codis-fe

作用:叢集管理介面。

1.多個叢集例項共享可以共享同一個前端展示頁面;
2.通過配置檔案管理後端codis-dashboard列表,配置檔案可自動更新。

部署:按照2.1中的用途規劃,將在如下機器上部署該程式。

序號 IP 主機名 部署程式
01 192.168.1.31 WebServer-31 codis-config:18080、codis-fe:18090

安裝
1. 生成配置

#./codis-amdin - -dashboard-list - -zookeeper=192.168.1.51:2181 | tee ../conf/codis.json

[
{
“name”:”chatroom”,
“dashboard”:192.168.1.31:18087”
}
]

2. 啟動程式

#nohup ./codis-fe - -ncpu=4 - -log=../log/fe.log - -log-level=WARN - -dashboard-list=../conf/codis.josn –listen=0.0.0.0:18090 &

開啟瀏覽器,輸入192.168.1.31:18090便可看到codis叢集的監控介面。如下圖所示:
這裡寫圖片描述

2.8 加入叢集

步驟
1. Codis-proxy
在proxy欄的輸入框中輸入相應ip和埠可將proxy新增到叢集中,如下圖所示:
這裡寫圖片描述

2. Codis-server
這裡寫圖片描述

3. 配置Slots
這裡寫圖片描述

4. Sentinel
這裡寫圖片描述

至此,codis叢集的搭建已經完成。可通過redis-cli操作codis叢集存取資料。

3 注意事項

1.密碼配置
為了提高儲存叢集的安全性,就需要為叢集配置資料存取密碼和叢集管理密碼。

序號 密碼型別 描述
01 資料存取密碼 可通過修改proxy配置中session_auth調整資料存取密碼。當使用redis-cli存取資料時,auth密碼需要與session_auth一致。
02 叢集管理密碼 在proxy配置中的product_auth、codis-dashbroad配置中的product_auth需要與codis-server配置中的requirepass保持一致。