codis-3.2.8集羣部署詳解

codis-3.2.8集羣部署詳解

一、概要

Codis 是一個分佈式 Redis 解決方案, 對於上層的應用來說, 連接到 Codis Proxy 和連接原生的 Redis Server 沒有明顯的區別 (不支持的命令列表https://github.com/CodisLabs/codis/blob/release3.1/doc/unsupported_cmds.md), 上層應用可以像使用單機的 Redis 一樣使用, Codis 底層會處理請求的轉發, 不停機的數據遷移等工作, 所有後邊的一切事情, 對於前面的客戶端來說是透明的, 可以簡單的認爲後邊連接的是一個內存無限大的 Redis 服務:
Codis是豌豆莢的開源方案,目前在redis集羣實現方式對比,codis集羣比較穩定的方案,並且客戶端不需要做任何修改,相對redis cluster兼容性更強,可節約大量開發成本並減少大量後期維護成本,豌豆莢gitlab地址https://github.com/pingcap,豌豆莢codis項目官方github地址https://github.com/CodisLabs/codis,codis 主要由以下特點:

可以無縫遷移到codis,自帶遷移工具,並且案例較多
可以動態擴容和縮容
多業務完全透明,業務不知道運行的是codis
支持多核心CPU,twemproxy只能單核
codis是中心基於proxy的設計,是客戶端像連接單機一樣操作proxy
有部分命令不能支持,比如keys *等
支持group劃分,組內可以設置一個主多個從,通過sentinel 監控redis主從,當主down了自動將從切換爲主
設置的進程要最大等於CPU的核心,不能超過CPU的核心數
其依賴於zookeeper,裏面保存的是key保存的redis主機位置,因此zookeeper要做高可用
監控可以使用接口和dashboard


二、架構

wKiom1mKuX-i9xxfAAFJCi-ksb8698.png

三、角色分配

zookeeper集羣:
192.168.10.45
192.168.10.46
192.168.10.47
codis-config、codis-dashboard:
192.168.10.45 :18087
192.168.10.45:8090
codis-proxy:
192.168.10.45 :19000
192.168.10.46 :19000
192.168.10.47:19000
codis-server:
192.168.10.45:6379、192.168.10.46:6380(主、從)
192.168.10.46 :6379、192.168.10.47:6380(主、從)
192.168.10.47:6379、192.168.10.45:6380(主、從)


四、部署

4.1、安裝zookeeper、jdk(45、46、47執行)

[root@kvm-yw ~]# tar zxvf zookeeper-3.4.8.tar.gz
[root@kvm-yw ~]# mv zookeeper-3.4.8 /data/servers/
[root@kvm-yw ~]# tar zxf jdk-8u131-linux-x64.gz
[root@kvm-yw ~]# mv jdk1.8.0_131 /data/servers/

配置java環境在/etc/profile最下面添加:

[root@kvm-yw ~]# tail -n 3 /etc/profile
export JAVA_HOME=/data/servers/jdk1.8.0_131
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
[root@kvm-yw ~]# java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

配置zookeeper,新建zoo.cfg:

[root@kvm-yw ~]# vim /data/servers/zookeeper-3.4.8/conf/zoo.cfg 
maxClientCnxns=50
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper/
clientPort=2181
server.1=192.168.10.45:2888:3888
server.2=192.168.10.46:2888:3888
server.3=192.168.10.47:2888:3888

[root@kvm-yw ~]# mkdir /data/zookeeper/ ##創建zk的datadir目錄
[root@kvm-yw ~]# echo "1" >/data/zookeeper/myid  ##生成ID,這裏需要注意, myid對應的zoo.cfg的server.ID,比如192.168.10.45對應的myid應該1
[root@kvm-yw ~]# /usr/lib/zookeeper/bin/zkServer.sh start  ## 服務啓動
[root@kvm-yw ~]# ss -tlnp | grep 218*          #查看端口是否啓動
LISTEN     0      50    *:2181                     *:*      users:(("java",2481,22))
[root@kvm-yw ~]# /data/servers/zookeeper-3.4.8/bin/zkServer.sh status  #查看狀態
ZooKeeper JMX enabled by default
Using config: /data/servers/zookeeper-3.4.8/bin/../conf/zoo.cfg
Mode: follower

參數說明:

詳細解釋:
tickTime:這個時間是作爲 Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。

dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認情況下,Zookeeper 將寫數據的日誌文件也保存在這個目錄裏。

clientPort:這個端口就是客戶端連接 Zookeeper 服務器的端口,Zookeeper 會監聽這個端口,接受客戶端的訪問請求。

initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這裏所說的客戶端不是用戶連接 Zookeeper 服務器的客戶端,而是 Zookeeper 服務器集羣中連接到 Leader 的 Follower 服務器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 5個心跳的時間(也就是 tickTime)長度後 Zookeeper 服務器還沒有收到客戶端的返回信息,那麼表明這個客戶端連接失敗。總的時間長度就是 10*6000=60 秒

syncLimit:這個配置項標識 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 5*6000=30 秒

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


4.2、go安裝(codis是go語言寫的,45、46、47執行安裝)

[root@kvm-yw ~]# wget 
[root@kvm-yw ~]# tar -zxvf go1.4.1.linux-amd64.tar.gz
[root@kvm-yw ~]# mv go /usr/local/
[root@kvm-yw ~]# cd /usr/local/go/src/
[root@kvm-yw ~]# bash all.bash
[root@kvm-yw ~]# cat >> ~/.bashrc << _bashrc_export
export GOROOT=/usr/local/go
export PATH=\$PATH:\$GOROOT/bin
export GOARCH=amd64
export GOOS=linux
_bashrc_export
[root@kvm-yw ~]# source ~/.bashrc


4.3、下載並編譯codis(codis-config、codis-proxy、codis-server所在的機器)

[root@kvm-yw ~]# mkdir -p //data/go/src/github.com/CodisLabs
[root@kvm-yw ~]# cd /data/go/src/github.com/CodisLabs
[root@kvm-yw CodisLabs]# git clone https://github.com/CodisLabs/codis.git -b release3.2
[root@kvm-yw CodisLabs]# cd codis
[root@kvm-yw codis]# pwd
/data/go/src/github.com/CodisLabs/codis
[root@kvm-yw codis]# yum install autoconf automake libtool -y  #安裝依賴
[root@kvm-yw codis]# make
make -j4 -C extern/redis-3.2.8/
make[1]: Entering directory `/usr/local/go/work/src/github.com/CodisLabs/codis/extern/redis-3.2.8'
cd src && make all
make[2]: Entering directory `/usr/local/go/work/src/github.com/CodisLabs/codis/extern/redis-3.2.8/src'
...
lazy_lock : 0
tls : 1
cache-oblivious : 1
===============================================================================
go build -i -o bin/codis-dashboard ./cmd/dashboard
go build -i -tags "cgo_jemalloc" -o bin/codis-proxy ./cmd/proxy
go build -i -o bin/codis-admin ./cmd/admin
go build -i -o bin/codis-fe ./cmd/fe

執行測試:

[root@kvm-yw codis]# make gotest
go test ./cmd/... ./pkg/...? github.com/CodisLabs/codis/cmd/admin    [no test files]
? github.com/CodisLabs/codis/cmd/dashboard    [no test files]
? github.com/CodisLabs/codis/cmd/fe    [no test files]
? github.com/CodisLabs/codis/cmd/proxy    [no test files]
? github.com/CodisLabs/codis/pkg/models    [no test files]
? github.com/CodisLabs/codis/pkg/models/etcd    [no test files]
? github.com/CodisLabs/codis/pkg/models/fs    [no test files]
? github.com/CodisLabs/codis/pkg/models/zk    [no test files]
ok github.com/CodisLabs/codis/pkg/proxy    2.525s
ok github.com/CodisLabs/codis/pkg/proxy/redis    0.530s
ok github.com/CodisLabs/codis/pkg/topom    6.560s
ok github.com/CodisLabs/codis/pkg/utils    0.009s
? github.com/CodisLabs/codis/pkg/utils/assert    [no test files]
ok github.com/CodisLabs/codis/pkg/utils/bufio2    0.006s
ok github.com/CodisLabs/codis/pkg/utils/bytesize    0.004s
? github.com/CodisLabs/codis/pkg/utils/errors    [no test files]
? github.com/CodisLabs/codis/pkg/utils/log    [no test files]
ok github.com/CodisLabs/codis/pkg/utils/math2    0.002s
? github.com/CodisLabs/codis/pkg/utils/redis    [no test files]
? github.com/CodisLabs/codis/pkg/utils/rpc    [no test files]
? github.com/CodisLabs/codis/pkg/utils/sync2    [no test files]
? github.com/CodisLabs/codis/pkg/utils/sync2/atomic2    [no test files]
ok github.com/CodisLabs/codis/pkg/utils/timesize    0.009s
? github.com/CodisLabs/codis/pkg/utils/trace    [no test files]
ok github.com/CodisLabs/codis/pkg/utils/unsafe2    0.003s

執行全部指令後,會在 bin 文件夾內生成 codis-proxy、codis-server三個可執行文件。另外, bin/assets 文件夾是 dashboard http 服務需要的前端資源)

[root@kvm-yw codis]# ll bin
總用量 96236
drwxr-xr-x 4 root root     4096 8月   3 12:22 assets
-rwxr-xr-x 1 root root 15209294 8月   3 12:22 codis-admin
-rwxr-xr-x 1 root root 16782405 8月   3 12:22 codis-dashboard
-rwxr-xr-x 1 root root 14942227 8月   3 12:22 codis-fe
-rwxr-xr-x 1 root root 13330799 8月   3 12:22 codis-ha
-rwxr-xr-x 1 root root 18975773 8月   3 12:22 codis-proxy
-rwxr-xr-x 1 root root  7985163 8月   3 12:22 codis-server
-rwxr-xr-x 1 root root  5580671 8月   3 12:22 redis-benchmark
-rwxr-xr-x 1 root root  5712491 8月   3 12:22 redis-cli
-rw-r--r-- 1 root root      167 8月   3 12:22 version
[root@kvm-yw codis]# cat bin/version 
version = 2017-07-31 14:18:45 +0800 @9851f82515e4d050c9f3c9f0bbd297e5b96048ad @3.2.0-10-g9851f82
compile = 2017-08-03 12:22:18 +0800 by go version go1.8.3 linux/amd64

編譯codis3.2錯誤記錄:

make[2]: Leaving directory `/usr/local/go/work/src/github.com/CodisLabs/codis/extern/redis-3.2.8/src'
make[1]: Leaving directory `/usr/local/go/work/src/github.com/CodisLabs/codis/extern/redis-3.2.8'
autoconf
./autogen.sh: line 5: autoconf: command not found
Error 0 in autoconf
make[2]: *** [config] Error 1
make[1]: *** [build] Error 2
make: *** [codis-deps] Error 2

解決:
安裝依賴

[root@kvm-yw codis]# yum install autoconf automake libtool -y



4.4:默認啓動的會讀取config目錄的dashboard.toml文件,編輯如下:
dashboard 的配置文件:

coordinator_name = "zookeeper"
coordinator_addr = "192.168.10.45:2181,192.168.10.46:2181,192.168.10.47:2181"
product_name = "codis-***"

wKiom1mKrIbAqG22AAC3LXwdIhQ737.png

五、服務啓動及初始化集羣

5.1、啓動 dashboard(45上操作)

[root@kvm-yw codis]# nohup ./bin/codis-dashboard --ncpu=1 --config=config/dashboard.toml --log=dashboard.log --log-level=WARN >> /var/log/codis_dashboard.log &

# 默認配置文件生成方式:

[root@kvm-yw codis]# ./bin/codis-dashboard --default-config | tee dashboard.toml

啓動代理

[root@kvm-yw codis]# nohup ./bin/codis-proxy --ncpu=1 --config=config/proxy.toml --log=proxy.log --log-level=WARN >> /var/log/codis_proxy.log &

proxy.toml主要配置信息如下:

product_name = "codis-chinasoft"
product_auth = "123456"

jodis_name = "zookeeper"
jodis_addr = "192.168.10.45:2181,192.168.10.46:2181,192.168.10.47:2181"
jodis_timeout = "20s"
jodis_compatible = true

啓動codis-server,即創建redis實例(45、46、47每臺服務器我們創建2個redis實例,給予codis修改過的redis-3.2.8非原生redis)

[root@kvm-yw redis-3.2.8]# pwd
/data/go/src/github.com/CodisLabs/codis/extern/redis-3.2.8
[root@kvm-yw redis-3.2.8]# mkdir /data/redis
[root@kvm-yw redis-3.2.8]# cp redis.conf /data/redis/redis-6379.conf
[root@kvm-yw redis-3.2.8]# cp redis.conf /data/redis/redis-6380.conf
[root@kvm-yw redis-3.2.8]# cd /data/redis/

修改redis-6379.conf、redis-6380.conf,主要配置:

pidfile "/data/redis/redis_6379.pid"    #與各自的配置文件端口號對應
logfile "/data/redis/redis_6379.log"
port 6379                               #與配置配置文件名稱對應
dbfilename dump_6381.rdb
dir /var/lib/redis_6381
logfile "/tmp/redis_6381.log"
maxmemory 1g #一定要設置最大內存,否則後面的codis無法使用

通過codis-server指定redis.conf文件啓動redis服務,不能通過redis命令啓動redis服務,通過redis啓動的redis 服務加到codis集羣無法正常使用(45、46、47操作):

[root@kvm-yw redis]# cd /data/go/src/github.com/CodisLabs/codis/
[root@kvm-yw codis]# ./bin/codis-server /data/redis/redis-6379.conf 
[root@kvm-yw codis]# ./bin/codis-server /data/redis/redis-6380.conf

驗證通過codis啓動redis 服務成功:

[root@kvm-yw codis]# ss -tnlp|grep 63*
LISTEN 0 128 127.0.0.1:6379 *:* users:(("codis-server",pid=11726,fd=4))
LISTEN 0 128 127.0.0.1:6380 *:* users:(("codis-server",pid=11733,fd=4))

啓動codis-fe,Listen監聽端口不要爲8080,指定8090(在45上啓動):

[root@kvm-yw codis]# nohup ./bin/codis-fe --ncpu=1 --log=fe.log --log-level=WARN --zookeeper=192.168.10.45:2181 --listen=192.168.10.45:8090 &


通過網頁訪問:http://192.168.3.198:8090 可以看到codis的管理頁面:

wKiom1mKpwWA1sDJAADNJP5zAaI200.png

管理界面的配置實用:
1、通過fe添加group
通過web瀏覽器訪問集羣管理頁面(fe地址:192.168.10.45:8090) 選擇我們剛搭建的集羣 codis-***,在 Proxy 欄添加我們已經啓動的 Proxy,

wKioL1mKp4aytwC7AABdw_sQkyg378.png

但是 Group 欄爲空,因爲我們啓動的 codis-server 並未加入到集羣 添加 NEW GROUP,NEW GROUP 行輸入 1,再點擊 NEW GROUP 即可

wKioL1mKqAvhKJuGAAA_rylo3y0238.png


2、添加實例(即添加後端的redis服務器)
Add Server 行輸入我們剛剛啓動的 codis-server 地址,添加到我們剛新建的 Group,然後再點擊 Add Server 按鈕即可,如下圖所示
wKioL1mKqMjizIWLAAETZbfEeqM956.png


刪除實例

3、對slots進行分組

如下圖所示,輸入所要分組的slots的起和止的範圍,然後輸入組ID,點擊後面按鈕即可

wKioL1mKqT7T1oUxAAB4n6hlFig654.png


4、通過codis-proxy連接redis進行測試

[root@kvm-yw src]# pwd
/data/go/src/github.com/CodisLabs/codis/extern/redis-3.2.8/src
[root@kvm-yw src]# ./redis-cli -h 192.168.10.45 -p 19000
192.168.10.45:19000> info
# Server
redis_version:3.2.9
redis_git_sha1:9851f825
redis_git_dirty:0
redis_build_id:54896ac136841499
redis_mode:standalone
os:Linux 2.6.32-696.el6.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.7
process_id:23483
run_id:7b049be615a758989c696c143a9e1ffd23ac025d
tcp_port:6379
uptime_in_seconds:509652
uptime_in_days:5
hz:10
lru_clock:9087707
executable:/data/go/src/github.com/CodisLabs/codis/./bin/codis-server
config_file:/data/redis/redis-6379.conf

# Clients
connected_clients:49
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:4642472
used_memory_human:4.43M
used_memory_rss:16519168
used_memory_rss_human:15.75M
used_memory_peak:6444520
used_memory_peak_human:6.15M
total_system_memory:8129425408
total_system_memory_human:7.57G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:3.56
mem_allocator:jemalloc-4.0.3

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1501751549
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok

# Stats
total_connections_received:150
total_commands_processed:6412365
instantaneous_ops_per_sec:1
total_net_input_bytes:115627152
total_net_output_bytes:1227970244
instantaneous_input_kbps:0.06
instantaneous_output_kbps:1.43
rejected_connections:0
sync_full:1
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:1
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:793
migrate_cached_sockets:0

# Replication
role:master
connected_slaves:1
slave0:ip=192.168.10.45,port=6380,state=online,offset=711747,lag=1
master_repl_offset:711747
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:711746

# CPU
used_cpu_sys:270.09
used_cpu_user:171.60
used_cpu_sys_children:0.01
used_cpu_user_children:0.00

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=1,expires=0,avg_ttl=0
192.168.10.45:19000> set name jack
OK
192.168.10.45:19000> get name
"jack"
192.168.10.45:19000>

web界面驗證key是否添加完成,可以看到已經添加到了group2中:

wKioL1mKq5vC9AheAADoG4UEHXM711.png

連接zookeeper,可以看到codis的group,slots,proxy等信息都記錄在zook中
/usr/local/zookeeper/bin/zkCli.sh -server


至此codis集羣已經搭建成功,首次搭建過程中難免會出現很多問題,請大家耐心點。此文中若有錯誤之處請指教。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章