codis 是 go 语言编写的基于 redis 的一个分布式解决方案。这篇文章我们将在单台服务器上搭建一个分布式、高可用、无单点的 codis 集群。
版本说明
为了保证操作的一致性,我们对所使用的版本作如下说明:
系统版本:centos 7.4
codis 版本:codis 3.2
go 安装(略)
环境设置如下:
$ vim etc/profileexport GOROOT=/usr/local/goexport GOPATH=/var/goexport PATH=$PATH:$GOROOT/bin$ source /etc/profile
$ go versiongo version go1.12.9 linux/amd6$ go env GOPATH/var/go
codis 安装
下载源码到:$GOPATH/src/github.com/CodisLabs/codis
下载地址:https://github.com/CodisLabs/codis
$ cd $GOPATH/src/github.com/CodisLabs/codis$ make
将 codis 源码放到指定目录,然后直接 make 编译即可。
安装完成后,我们先来看看 codis 都有哪些组件?
$ ll bin/total 144356drwxr-xr-x 4 root root 4096 Jul 10 17:57 assets-rwxr-xr-x 1 root root 26141992 Jul 10 17:57 codis-admin-rwxr-xr-x 1 root root 27547656 Jul 10 17:57 codis-dashboard-rwxr-xr-x 1 root root 25051912 Jul 10 17:57 codis-fe-rwxr-xr-x 1 root root 29699808 Jul 10 17:57 codis-proxy-rwxr-xr-x 1 root root 5366496 Jul 10 17:57 codis-server-rwxr-xr-x 1 root root 2432704 Jul 10 17:57 redis-benchmark-rwxr-xr-x 1 root root 2586760 Jul 10 17:57 redis-cli-rwxr-xr-x 1 root root 5366496 Jul 10 17:57 redis-sentinel-rw-r--r-- 1 root root 97 Jul 10 17:57 version
codis-dashboard
集群管理工具,支持 codis-proxy、codis-server 的添加、删除,以及数据迁移等操作。
对于同一个业务集群而言,同一个时刻 codis-dashboard 只能有 0个或者1个;
所有对集群的修改都必须通过 codis-dashboard 完成。
codis-fe
集群管理界面。
多个集群可以共享同一个前端展示页面;
codis-proxy
客户端代理,实现了 redis 协议。
对于同一个业务集群而言,可以同时部署多个 codis-proxy 实例;
不同 codis-proxy 之间由 codis-dashboard 保证状态同步。
配置文件
$ ll config/total 64-rw-r--r-- 1 root root 1215 Jul 10 17:57 dashboard.toml-rw-r--r-- 1 root root 3903 Jul 10 17:57 proxy.toml-rw-r--r-- 1 root root 46711 Jul 10 17:57 redis.conf-rw-r--r-- 1 root root 7614 Jul 10 17:57 sentinel.conf
启动脚本文件
$ ll admin/total 16-rwxr-xr-x 1 root root 2282 Nov 4 2018 codis-dashboard-admin.sh-rwxr-xr-x 1 root root 1796 Nov 4 2018 codis-fe-admin.sh-rwxr-xr-x 1 root root 2102 Nov 4 2018 codis-proxy-admin.sh-rwxr-xr-x 1 root root 1722 Nov 4 2018 codis-server-admin.sh
下面,我们简单介绍一下相关配置:
dashboard 配置
################################################### ## Codis-Dashboard ## #################################################### Set Coordinator, only accept "zookeeper" & "etcd" & "filesystem".# for zookeeper/etcd, coorinator_auth accept "user:password"# Quick Startcoordinator_name = "filesystem"coordinator_addr = "/tmp/codis"#coordinator_name = "zookeeper"#coordinator_addr = "127.0.0.1:2181"#coordinator_auth = ""# 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/filesystem |
| coordinator_addr | 外部存储地址 |
| product_name | 集群名称,满足正则 \w[\w.-]* |
| product_auth | 集群密码 |
| admin_addr | RESTful API 端口 |
admin_addr:dashboard 监听端口,集群内部通过该端口与 dashboard 交互。
proxy 配置
################################################### ## Codis-Proxy ## #################################################### Set Codis Product Name/Auth.product_name = "codis-demo"product_auth = ""# Set auth for client session# 1. product_auth is used for auth validation among codis-dashboard,# codis-proxy and codis-server.# 2. session_auth is different from product_auth, it requires clients# to issue AUTH <PASSWORD> before processing any other commands.session_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"
| 参数 | 说明 |
| product_name | 集群名称 |
| product_auth | 集群密码 |
| admin_addr | RESTful API 端口 |
| proxy_addr | 代理端口 |
admin_addr:proxy 监听端口,集群内部通过该端口与 proxy 交互。
proxy_addr:proxy 监听端口,客户端通过该端口与服务端通信。
下面,我们开始搭建集群:
1. 启动 dashboard、fe
$ ./admin/codis-dashboard-admin.sh start$ ./admin/codis-fe-admin.sh start
这里,我们通过 codis 提供的启动脚本来启动程序。
此时,dashboard 的默认配置是:
coordinator_name = "filesystem"coordinator_addr = "/tmp/codis"product_name = "codis-demo"admin_addr = "0.0.0.0:18080"
集群名称:codis-demo,监听端口:18080,元数据存储使用 filesystem,保存路径为 /tmp/codis。
fe 是集群管理界面,默认配置写在 admin/codis-fe-admin.sh 文件中:
COORDINATOR_NAME="filesystem"COORDINATOR_ADDR="/tmp/codis"CODIS_FE_ADDR="0.0.0.0:9090"
假设我们有一个域名指向当前服务器:codis.xxx.com,那么访问 codis.xxx.com:9090 即可看到管理界面,此时,管理面板基本是空的。
2. 启动 codis-server
为了实现分布式、高可用的目的,我们启动 4 个进程,每个进程对应一个端口号,分别是:6379、6380、6381、6382。
2.1 首先,将配置文件复制四份:
$ ll config/redis*.conf-rw-r--r-- 1 root root 46711 Jul 10 18:10 config/redis-6379.conf-rw-r--r-- 1 root root 46711 Jul 10 18:10 config/redis-6380.conf-rw-r--r-- 1 root root 46711 Jul 10 18:10 config/redis-6381.conf-rw-r--r-- 1 root root 46711 Jul 10 18:10 config/redis-6382.conf-rw-r--r-- 1 root root 46711 Jul 10 17:57 config/redis.conf
修改配置文件中的端口号为对应的端口号。
2.2 然后,修改启动脚本:
CODIS_SERVER_PID_FILE=/tmp/redis-6379.pidCODIS_SERVER_LOG_FILE=/tmp/redis-6379.logCODIS_SERVER_CONF_FILE=$CODIS_CONF_DIR/redis-6379.conf
根据端口号做对应的修改。
2.3 最后,执行脚本。
$ ./admin/codis-server-admin.sh start
四个进程全部启动成功后,打开集群管理界面:codis.xxx.com:9090
新建两个 Group,每个 Group 分配两台服务器,点击绿色按钮同步状态,最终,界面如下图所示:

默认情况下,所有的 slot 都是 offline 状态:

点击下方的 Rebalance All Slots 按钮,codis 会自动把1024个 slot 分配给两个 group,如下图所示:

3. 启动 proxy
为了实现无单点设计,我们启动 3 个 proxy 进程。
3.1 首先,将配置文件复制三份:
$ ll config/proxy*.toml-rw-r--r-- 1 root root 3903 Jul 10 18:23 config/proxy-19000.toml-rw-r--r-- 1 root root 3903 Jul 10 18:23 config/proxy-19001.toml-rw-r--r-- 1 root root 3903 Jul 10 18:23 config/proxy-19002.toml-rw-r--r-- 1 root root 3903 Jul 10 17:57 config/proxy.toml
修改配置文件,admin_addr 对应的端口号分别是:11080、11081、11082,proxy_addr 对应的端口号分别是:19000、19001、19002
3.2 然后,修改启动脚本:
CODIS_PROXY_PID_FILE=$CODIS_BIN_DIR/codis-proxy-19000.pidCODIS_PROXY_LOG_FILE=$CODIS_LOG_DIR/codis-proxy-19000.logCODIS_PROXY_CONF_FILE=$CODIS_CONF_DIR/proxy-19000.toml
根据端口号做对应的修改。
3.3 最后,执行脚本。
$ ./admin/codis-proxy-admin.sh start
打开集群管理界面:codis.xxx.com:9090,界面如下图所示:

4. 启动 sentinel
为了实现高可用的目的,至少需要 3 个 sentinel 进程,端口号分别是:26379、26380、26381。
4.1 首先,将配置文件复制三份:
$ ll config/sentinel*.conf-rw-r--r-- 1 root root 7614 Jul 10 18:30 config/sentinel-26379.conf-rw-r--r-- 1 root root 7614 Jul 10 18:30 config/sentinel-26380.conf-rw-r--r-- 1 root root 7614 Jul 10 18:31 config/sentinel-26381.conf-rw-r--r-- 1 root root 7614 Jul 10 17:57 config/sentinel.conf
修改配置文件:
port 26379protected-mode no
修改配置文件中的端口号为对应的端口号。
4.2 然后,修改启动脚本(codis 默认没有提供启动脚本,复制一份):
$ cd admin$ cp codis-server-admin.sh codis-sentinel-admin.sh
CODIS_SERVER_BIN=$CODIS_BIN_DIR/redis-sentinelCODIS_SERVER_PID_FILE=/tmp/sentinel-26379.pidCODIS_SERVER_LOG_FILE=/tmp/sentinel-26379.logCODIS_SERVER_CONF_FILE=$CODIS_CONF_DIR/sentinel-26379.conf
根据端口号做对应的修改。
4.3 最后,执行脚本。
$ ./admin/codis-sentinel-admin.sh start
打开集群管理界面:codis.xxx.com:9090
将 3 个进程依次添加到集群管理面板中去,点击 SYNC 按钮同步状态,如下图所示:

对比之前的 codis-server 状态,可以看到,主节点新增了 [HA] 状态。

至此,codis 集群就搭建完成了。
下面,我们来验证一下:
1. 首先,写入两条数据:
$ cd bin/$ ./redis-cli -p 19000127.0.0.1:19000> set hello world$ ./redis-cli -p 19001127.0.0.1:19001> set foo bar$ ./redis-cli -p 19002127.0.0.1:19002> get hello127.0.0.1:19002> get foo
我们使用 3 个代理分别写入和读取数据,可见不存在单点问题,任何一个代理挂掉,都不影响我们读写数据。
2. 打开集群管理界面:codis.xxx.com:9090

可以看到,每一个主节点都有一条数据,刚才我们写入的两条数据,分布在两个主节点上,说明这是一个分布式集群。
3. 杀掉 6380 进程

可以看到,6382 进程从从节点自动变为主节点,说明这是一个高可用集群。
所以说,这是一个分布式、高可用、无单点的 codis 集群。
附:官方文档
https://github.com/CodisLabs/codis/blob/release3.2/doc/tutorial_zh.md




