Codis 是一個分佈式 Redis 解決方案, 對於上層的應用來講, 鏈接到 Codis Proxy 和鏈接原生的 Redis Server 沒有明顯的區別 (不支持的命令列表), 上層應用能夠像使用單機的 Redis 同樣使用, Codis 底層會處理請求的轉發, 不停機的數據遷移等工做, 全部後邊的一切事情, 對於前面的客戶端來講是透明的, 能夠簡單的認爲後邊鏈接的是一個內存無限大的 Redis 服務.前端
Codis 由四部分組成:node
a) 在codisproxy1 上部署編譯環境linux
codis集羣nginx |
|
||
codisproxy1:19000 |
192.168.20.157github |
codisproxy1golang |
|
codisproxy2redis |
192.168.20.158sql |
codisproxy2vim |
|
redis1:6379 |
192.168.20.159 |
redis1 |
|
redis2:6379 |
192.168.20.160 |
redis2 |
|
redis3:6379 |
192.168.20.163 |
redis3 |
|
redis4:6379 |
192.168.20.164 |
redis4 |
[root@codisproxy1~]# wget https://storage.googleapis.com/golang/go1.6.2.linux-amd64.tar.gz
[root@codisproxy1~]# tar -zxvf go1.6.2.linux-amd64.tar.gz
[root@codisproxy1~]# mv go /usr/local/
[root@codisproxy1~]# vim /etc/profile
在/etc/profile 文件中加入go的環境變量
export GOROOT=/usr/local/go
export GOPATH=/data/gopath
export PATH=$GOROOT/bin:$PATH
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
[root@codisproxy1~]# source /etc/profile
[root@codisproxy1 ~]# go get -u -d github.com/CodisLabs/codis
[root@codisproxy1 ~]# go get github.com/tools/godep
切換到$GOPATH/src/github.com/CodisLabs/codis目錄執行make命令編譯代碼,並執行make gotest來跑測試
[root@codisproxy1~]# cd /data/gopath/src/github.com/CodisLabs/codis
[root@codisproxy1 codis]# ls
[root@codisproxy1~]# make
[root@codisproxy1~]# make gotest
[root@codisproxy1~]# cd bin
執行所有指令後,會在 bin 文件夾內生成 codis-config、codis-proxy、codis-server三個可執行文件。另外, bin/assets 文件夾是 codis-config
的 dashboard http 服務須要的前端資源, 須要和 codis-config 放置在同一文件夾下)
對codis.tar.gz 目錄進行打包,拷貝到其餘服務器上
[root@codisproxy1 CodisLabs]# tar -zcvf codis.tar.gz codis/
[root@codisproxy1 CodisLabs]# scp codis.tar.gz codis_config:/data/
[root@codisproxy1 CodisLabs]# scp codis.tar.gz codisproxy1:/data/
[root@codisproxy1 CodisLabs]# scp codis.tar.gz codisproxy1:/data/
[root@codisproxy1 CodisLabs]# scp codis.tar.gz redis1:/data/
[root@codisproxy1 CodisLabs]# scp codis.tar.gz redis2:/data/
[root@codisproxy1 CodisLabs]# scp codis.tar.gz redis3:/data/
[root@codisproxy1 CodisLabs]# scp codis.tar.gz redis4:/data/
配置啓動redis服務器192.168.20.15九、160、16三、164
b) [root@redis1 data]# tar -zxvf codis.tar.gz
[root@redis1 extern]# cd /data/codis/extern/redis-2.8.21
[root@redis1 redis-2.8.21]# make PREFIX=/data/redis install
[root@redis1 redis-2.8.21]# mkdir /etc/redis/
[root@redis1 redis-2.8.21]# cp redis.conf /etc/redis/
[root@redis1 redis-2.8.21]# cp utils/redis_init_script /etc/init.d/redis
[root@redis1 redis-2.8.21]# chmod +x /etc/init.d/redis
修改/etc/init.d/redis 文件
[root@redis1 redis-2.8.21]# mkdir /data/redis/run
[root@redis1 redis-2.8.21]# mkdir /data/redis/data/
[root@redis1 redis-2.8.21]# grep ^[a-z] /etc/redis/redis.conf
daemonize yes
pidfile /data/redis/run/redis.pid
maxmemory 2048mb 設置maxmeory能夠在管理頁面進行自動平衡。
port 6379
tcp-backlog 511
bind 0.0.0.0
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/data/redis/logs"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis/data
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
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
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
[root@redis1 redis-2.8.21]# /etc/init.d/redis start
c) condis_config服務配置,並啓動dashboard
[root@codis_config codis]# grep ^[a-z] config.ini
coordinator=zookeeper
zk=zookeeper1:2181,zookeeper2:2181,zookeeper3:2181
product=test
dashboard_addr=192.168.20.130:18087
password=
backend_ping_period=5
session_max_timeout=1800
session_max_bufsize=131072
session_max_pipeline=1024
zk_session_timeout=30000
proxy_id=proxy_1
啓動codis-config dashboard,
[root@codis_config bin]# ./codis-config -c ../config.ini dashboard
2015/12/11 16:49:10 dashboard.go:160: [INFO] dashboard listening on addr: :18087
2015/12/11 16:49:10 dashboard.go:234: [PANIC] create zk node failed
[error]: dashboard already exists: {"addr": "172.31.16.30:18087", "pid": 7762}
解決辦法:
這種問題是因爲使用了kill -9致使了dashboard服務異常終止,而退出服務的時候沒有在zk上清除自已的信息,因此就出現了這種問題。
因此咱們在中止codis集羣的任何服務的時候都不要輕易使用kill -9,可使用kill.
若是使用kill,那麼服務在終止的時候也會自動的到zk上清除自已的信息,下次再啓動的時候會馬上註冊。
臨時性的解決辦法就是:
登陸到zookeeper服務器上
[root@zookeeper1 ~]# /data/zookeeper/bin/zkCli.sh
[zk: localhost:2181(CONNECTED) 3] ls /
[zk, zookeeper]
# rmr /zk/codis/db_codis_proxy_test/dashboard
訪問地址爲:http://192.168.20.130:18087/admin/
初始化 slots,該命令會在zookeeper上建立slot相關信息
[root@codis_config bin]# ./codis-config -c ../config.ini slot init
添加redis server group
每個 Server Group 做爲一個 Redis 服務器組存在, 只容許有一個 master, 能夠有多個 slave, group id 僅支持大於等於1的整數
$ bin/codis-config -c ../config.ini server -h usage:
codis-config server list
codis-config server add <group_id> <redis_addr> <role>
codis-config server remove <group_id> <redis_addr>
codis-config server promote <group_id> <redis_addr>
codis-config server add-group <group_id>
codis-config server remove-group <group_id>
添加兩個 server group, 每一個 group 有兩個 redis 實例,group的id分別爲1和2, redis實例爲一主一從。
添加一個group,group的id爲1, 並添加一個redis master到該group
添加一個redis slave到該group
相似的,再添加group,group的id爲2
把192.168.20.159 redis1 添加到 組id爲1中,並設置爲master
[root@codis_config bin]# ./codis-config -c ../config.ini server add 1 192.168.20.158:6379 master
把192.168.20.153 redis3 添加到 組id爲1中,並設置爲slave
[root@codis_config bin]# ./codis-config -c ../config.ini server add 1 192.168.20.163:6379 slave
把192.168.20.160 redis2 添加到 組id爲2中,並設置爲master
[root@codis_config bin]# ./codis-config -c ../config.ini server add 2 192.168.20.160:6379 master
把192.168.20.164 redis4 添加到 組id爲2中,並設置爲slave
[root@codis_config bin]# ./codis-config -c ../config.ini server add 2 192.168.20.164:6379 slave
查看group爲1的內容
[root@codis_config bin]# ./codis-config -c ../config.ini server list
設置 server group 服務的 slot 範圍
Codis 採用 Pre-sharding 的技術來實現數據的分片, 默認分紅 1024 個 slots (0-1023), 對於每一個key來講, 經過如下公式肯定所屬的 Slot Id : SlotId = crc32(key) % 1024 每個 slot 都會有一個且必須有一個特定的 server group id 來表示這個 slot 的數據由哪一個 server group 來提供.
設置編號爲[0, 511]的 slot 由 server group 1 提供服務
[root@codis_config bin]# ./codis-config -c ../config.ini slot range-set 0 511 1 online
{
"msg": "OK",
"ret": 0
}
[root@codis_config bin]# ./codis-config -c config.ini slot range-set 512 1023 2 online
[root@codisproxy1 bin]# nohup ./codis-proxy -c ../config.ini --log-level=info -L ../log/proxy.log --cpu=4 --add=0.0.0.0:19000 --http-addr=0.0.0.0:11000 &
[root@codisproxy2 bin]# nohup ./codis-proxy -c ../config.ini --log-level=info -L ../log/proxy.log --cpu=4 --add=0.0.0.0:19000 --http-addr=0.0.0.0:11000 &
codisproxy1 proxy_id = proxy_1
codisproxy2 proxy_id = proxy_2
剛啓動的 codis-proxy 默認是處於 offline狀態的, 而後設置 proxy 爲 online 狀態, 只有處於 online 狀態的 proxy 纔會對外提供服務
在 codisproxy1 192.168.20.157服務器上讓proxy 啓動,注意每給proxy 的 proxy_id不一樣
[root@codisproxy1 bin]# ./codis-config -c ../config.ini proxy on proxy_1
[root@codisproxy1 bin]# ./codis-config -c ../config.ini proxy on proxy_2
查看使用的codis_proxy代理列表
[root@codis_config bin]# ./codis-config -c ../config.ini proxy list
數據遷移
安全和透明的數據遷移是 Codis 提供的一個重要的功能, 也是 Codis 區別於 Twemproxy 等靜態的分佈式 Redis 解決方案的地方。
數據遷移的最小單位是 key, 咱們在 codis redis 中添加了一些指令, 實現基於key的遷移, 如 SLOTSMGRT等 (命令列表), 每次會將特定 slot 一個隨機的 key 發送給另一個 codis redis 實例, 這個命令會確認對方已經接收, 同時刪除本地的這個 k-v 鍵值, 返回這個 slot 的剩餘 key 的數量, 整個操做是原子的.
在 codis-config 管理工具中, 每次遷移任務的最小單位是 slot
如: 將slot id 爲 [0-511] 的slot的數據, 遷移到 server group 2上, --delay 參數表示每遷移一個 key 後 sleep 的毫秒數, 默認是 0, 用於限速.
$ bin/codis-config slot migrate 0 511 2 --delay=10
遷移的過程對於上層業務來講是安全且透明的, 數據不會丟失, 上層不會停止服務.
注意, 遷移的過程當中打斷是能夠的, 可是若是中斷了一個正在遷移某個slot的任務, 下次須要先遷移掉正處於遷移狀態的 slot, 不然沒法繼續 (即遷移程序會檢查同一時刻只能有一個 slot 處於遷移狀態).
Auto Rebalance
Codis 支持動態的根據實例內存, 自動對slot進行遷移, 以均衡數據分佈.
$ bin/codis-config slot rebalance
要求:
HA
6、codis-server的HA
codis-ha實現codis-server的主從切換,codis-server主庫掛了會提高一個從庫爲主庫,從庫掛了會設置這個從庫從集羣下線
一、安裝
export GOPATH=/root/workspace
/go get github.com/ngaut/codis-ha cd /root/workspace/src/github.com/ngaut/codis-ha go build cp codis-ha /data/codis/bin/ 使用方法: codis-ha --codis-config=192.168.20.157:18087(dashboard地址:18087) --productName=test(集羣項目名稱)
二、使用supervisord管理codis-ha進程
yum -y install supervisord
/etc/supervisord.conf中添加以下內容: [program:codis-ha] autorestart = True stopwaitsecs = 10 startsecs = 1 stopsignal = QUIT command = /data/codis/bin/codis-ha --codis-config=192.168.20.157:18087 --productName=test user = root startretries = 3 autostart = True exitcodes = 0,2
三、啓動 supervisord服務
systemctl start supervisord.service
systemctl enable supervisord.service
此時,ps -ef |grep codis-ha 你回發現codis-ha進程已經啓動,這個時候你去停掉一個codis-server的master,看看slave會不會提高爲master呢