Prerequisition
安装Go
1 | $ echo "export GOPATH=/home/parallels/go" > .zshrc |
安装Java
安装Zookeeper
安装 autoconf
1 | $ sudo apt-get install autoconf |
手动编译
1 | $ sudo mkdir -p $GOPATH/src/github.com/CodisLabs |
Binary
1 | $ curl -OL https://github.com/CodisLabs/codis/releases/download/3.2.2/codis3.2.2-go1.8.5-linux.zip |
启动
启动 codis-dashboard
1 | $ # vim config/dashboard.toml |
启动
1 | $ nohup ./codis-dashboard --ncpu=4 --config=config/dashboard.toml --log=logs/dashboard.log --log-level=WARN & |
默认工作在18080端口。
1 | $ ./codis-dashboard -h |
默认配置文件
1 | $ ./codis-dashboard --default-config | tee dashboard.toml |
参数 | 说明 |
---|---|
coordinator_name | 外部存储类型,接受 zookeeper/etcd |
coordinator_addr | 外部存储地址 |
product_name | 集群名称,满足正则 \w[\w\.\-]* |
product_auth | 集群密码,默认为空 |
admin_addr | RESTful API 端口 |
启动 codis-proxy
codis-proxy 配置
1 | # vim config/proxy.toml |
1 | $ nohup ./codis-proxy --ncpu=4 --config=config/proxy.toml --log=logs/proxy.log --log-level=WARN & |
我们会发现proxy一直处于waiting online状态,这是因为没有将proxy 与 dashboard关联起来(而将proxy 与 dashboard关联需要我们显式地去操作)。
端口使用
一个codis-proxy 会使用两个端口,一个用于被 redis-cli直接连接(proxy_addr,默认为19000),一个用于管理这个proxy(admin_addr,默认为11080)
1 | $ redis-cli -h 192.168.2.204 -p 19000 |
1 | $ lsof -i -P | grep -i "listen" | grep "codis-proxy" |
帮助
1 | $ ./codis-proxy -h |
默认配置文件 proxy.toml
1 | $ ./codis-proxy --default-config | tee proxy.toml |
参数 | 说明 |
---|---|
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 |
jodis_compatible | Jodis 注册 zookeeper 的路径 |
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 表示禁止 |
添加 Proxy方法
codis-proxy 启动后,处于 waiting
状态,监听 proxy_addr
地址,但是不会 accept
连接,添加到集群并完成集群状态的同步,才能改变状态为 online
。添加的方法有以下两种:
- 通过 codis-fe 添加:通过
Add Proxy
按钮,将admin_addr
加入到集群中; - 通过 codis-admin 命令行工具添加,方法如下:
1 | $ ./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
地址;
在本Demo中,我们在Codis FE启动后,再对proxy进行处理。
启动 codis-server
codis-server 配置
1 | # vim config/redis.conf |
1 | $ cd /data |
- 启动 ./bin/codis-server,与启动普通 redis 的方法一致(这意味着)。
- 启动完成后,可以通过 codis-fe 提供的界面或者 codis-admin 命令行工具添加到集群中。
帮助
1 | $ ./codis-server -h |
启动 codis-fe
codis-fe 启动
1 | $ nohup ./codis-fe --ncpu=4 --log=logs/fe.log --log-level=WARN --zookeeper=127.0.0.1:2181 --listen=0.0.0.0:8081 & |
启动参数说明
1 | $ ./bin/codis-fe -h |
配置文件 codis.json 可以手动编辑,也可以通过 codis-admin 从外部存储中拉取,例如:
1 | $ ./bin/codis-admin --dashboard-list --zookeeper=127.0.0.1:2181 | tee codis.json |
访问 http://192.168.2.204:8081/ ,选择 codis-demo,即我们的 product name(这其实是因为一个 Codis FE 可以管理多个 Codis Dashboard )
添加 proxy
通过web浏览器访问集群管理页面(即 codis-fe,http://192.168.2.204:8081/ ),在 Proxy 栏我们并不能看到任何codis-proxy。
这其实是由于前面说的,即:
codis-proxy 启动后,处于
waiting
状态,监听proxy_addr
地址,但是不会accept
连接。只要添加到集群并完成集群状态的同步,才能改变状态为
online
。添加的方法有以下两种:
- 通过 codis-fe 添加:通过
Add Proxy
按钮,将admin_addr
加入到集群中;- 通过 codis-admin 命令行工具添加,方法如下:
1
2 > $ ./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
地址;
在添加完成后,就可以看到这个proxy的状态了:
同时,在codis-proxy的log中,也能看到对应的变化
1 | 2020/07/27 22:53:17 main.go:233: [WARN] [0xc4200a9340] proxy is working ... |
添加 codis-group (即codis-server)
Proxy已经设置成功了,但是 Group 栏为空,因为我们启动的 codis-server 并未加入到集群。
GROUP 输入 1,Add Server 输入我们刚刚启动的 codis-server 地址(127.0.0.1:6380),添加到我们刚新建的 Group,然后再点击 Add Server 按钮即可,如上图所示。
这样以后,整个cluster只有一个Group(即codis-group),即 Group 1。
当然,我们可以将更多个codis-server添加到cluster中,并将这些 codis-server 添加到不同的group中,这就是真正意义上的cluster了。
通过codis-fe初始化slot
新增的集群 slot 状态是 offline,因此我们需要对它进行初始化(将 1024 个 slot 分配到各个 group),而初始化最快的方法可通过 fe 提供的 Rebalance All Slots
按钮来做,如下图所示,点击此按钮,我们即快速完成了一个集群的搭建。
连接到codis-proxy
1 | $ redis-cli -h 192.168.2.204 -p 19000 |
当我们进行set 时,就能看到keys的变化:
扩展
添加codis-proxy
1 | $ cp config/proxy.toml config/proxy2.toml |
启动一个新的codis-proxy,添加其到当前 cluster中:
添加codis-server 作为一个已经存在的codis-group 中的slave节点
1 | $ ./codis-server --port 6381 |
添加该 codis-server 到 Group 1(这也是 codis-server 6380 位于的 Group)中:
点击 127.0.0.1:6381 那一行对应的小扳手,以将数据从 127.0.0.1:6380 复制到 127.0.0.1:6381,即127.0.0.1:6381 作为 127.0.0.1:6380 的 slave节点。
点击后,会有如下Log:
1 | 17816:S 28 Jul 21:15:47.703 * SLAVE OF 127.0.0.1:6380 enabled (user request from 'id=36 addr=127.0.0.1:53494 fd=40 name= age=0 idle=0 flags=x db=0 sub=0 psub=0 multi=4 qbuf=0 qbuf-free=32768 obl=50 oll=0 omem=0 events=r cmd=exec') |
可以看到,数据会被同步:
添加codis-server到一个新的codis-group
添加一个新的group,我们设为group 2:
1 | $ ./codis-server --port 6382 |
添加该 codis-server 到 Group 2中:
这时,所以的数据还只会被存储到 Group 1,因为我们目前还是把所有的slot(slot [0, 1023])分配给了 Group 1,点击”Rebalance All Slots”,以重新分配 slots:
我们随便插入一些数据以做测试:
1 | $ 192.168.2.204:19000> set 1 1 |
“Rebalance All Slots”可以帮我们很快的完成 cluster的横向扩展(当cluster的容量或者是CPU 成为 bottleneck时),即通过增加codis-group(每个codis-group中只包含一个 master codis-server),并将 slot 重分配到所有 Group 中(这个过程也称为”Rebalance”)。
Observation
codis-proxy 到codis-server 的connection
codis-proxy 会建立多条连接到codis-server,
1 | $ lsof -i -P | grep "codis-pr" |
而且,可以看到,每启动一个codis-proxy,这个proxy都会和当前active的所有的codis-server建立16个connection:
master codis-server 异常时
当master挂了的时候(这里master node是127.0.0.1:6380),slave在默认情况下并不会主动promote成为master(如果设置了sentinel,则会在出现故障时,自动将 Slave Redis node 转换为 Master Redis node)。
虽然我们可以在dashboard中看到error:
同样,通过proxy 来get 数据也会有error:
1 | 192.168.2.204:19000> get 1 |
master codis-server 增加后
当 master codis-server 增加后,如预期的,codis-proxy会自动和这个 master codis-server 建立连接,以下是在增加了 127.0.0.1:6382 节点之后,且在”rebalance”之后:
1 | $ lsof -i -P | grep "codis-pro" | grep 12955 | grep 6382 | wc -l |
错误
Codis异常关闭后启动出错
Situation
1 | 2020/07/27 21:25:06 main.go:171: [WARN] [0xc4202d1680] dashboard online failed [15] |
codis-dashboard 异常退出的修复
当 codis-dashboard 启动时,会在外部存储上存放一条数据,用于存储 dashboard 信息,同时作为 LOCK 存在。当 codis-dashboard 安全退出时,会主动删除该数据。当 codis-dashboard 异常退出时,由于之前 LOCK 未安全删除,重启往往会失败。因此 codis-admin 提供了强制删除工具:
- 确认 codis-dashboard 进程已经退出(很重要);
- 运行 codis-admin 删除 LOCK:
1 | $ ./codis-admin --remove-lock --product=<product name> --zookeeper=<zk address> |
codis-proxy 异常退出的修复
通常 codis-proxy 都是通过 codis-dashboard 进行移除,移除过程中 codis-dashboard 为了安全会向 codis-proxy 发送 offline
指令,成功后才会将 proxy 信息从外部存储中移除。如果 codis-proxy 异常退出,该操作会失败。此时可以使用 codis-admin 工具进行移除:
- 确认 codis-proxy 进程已经退出(很重要);
- 运行 codis-admin 删除 proxy:
1 | $ ./bin/codis-admin --dashboard=127.0.0.1:18080 --remove-proxy --addr=127.0.0.1:11080 --force |
选项 --force
表示,无论 offline
操作是否成功,都从外部存储中将该节点删除。所以操作前,一定要确认该 codis-proxy 进程已经退出。
操作
移除一个 group
1 | $ codis-admin --dashboard=codis-dashboard:18080 --group-del --gid=1 --addr=172.17.0.14:6379 |
当然也可以通过codis-fe来操作:
使所有slot是offline状态
要保证所有slot是offline状态,让所有slot offline命令如下:
1 | $ ./codis-admin --dashboard=0.0.0.0:18080 --slots-assign --beg=0 --end=1023 --offline --confirm |
总结
Codis 最大的优点,就是当cluster的容量或者是CPU 成为 bottleneck时,Codis可以帮我们很快的完成 cluster的横向扩展(通过 “Rebalance All Slots”),即通过增加codis-group(每个codis-group中只包含一个 master codis-server),并将 slot 重分配到所有 Group 中(这个过程也称为”Rebalance”)。
每个codis-group中只包含一个 master codis-server,当然可以包含0或多个 slave codis-server