1、介绍
Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有显著区别 (不支持的命令列表), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务。与Twemproxy 和 Redis Cluster 对比:
codis | Twemproxy | Redis Cluster | |
---|---|---|---|
resharding without restarting cluster | Yes | No | Yes |
pipeline | Yes | Yes | No |
hash tags for multi-key operations | Yes | Yes | Yes |
multi-key operations while resharding | Yes | – | No(details) |
Redis clients supporting | Any clients | Any clients | Clients have to support cluster protocol |
1.1环境:
1.2 codis组件说明
Codis Server:基于 redis-3.2.8 分支开发。增加了额外的数据结构,以支持 slot 有关的操作以及数据迁移指令。
Codis Proxy:客户端连接的 Redis 代理服务, 实现了 Redis 协议。 除部分命令不支持以外,表现的和原生的 Redis 没有区别(就像 Twemproxy)。
Codis Dashboard:集群管理工具,支持 codis-proxy、codis-server 的添加、删除,以及据迁移等操作。在集群状态发生改变时,codis-dashboard 维护集群下所有 codis-proxy 的状态的一致性。
Codis Admin:集群管理的命令行工具,可用于控制 codis-proxy、codis-dashboard 状态以及访问外部存储。
Codis FE:集群管理界面,多个集群实例共享可以共享同一个前端展示页面,通过配置文件管理后端 codis-dashboard 列表,配置文件可自动更新。 Storage:为集群状态提供外部存储,提供 Namespace 概念,不同集群的会按照不同 product name 进行组织,目前仅提供了 Zookeeper、Etcd、Fs 三种实现,但是提供了抽象的 interface 可自行扩展。
2、安装环境配置
2.1首先安装依赖环境,三台都要装
[root@c1 ~]# yum install -y autoconf automake libtool gcc glibc gcc-c++ make
2.2安装jdk,三台都要装
[root@c1 ~]# yum -y install java-11-openjdk[root@c1 ~]# java -versionopenjdk version "11.0.8" 2020-07-14 LTSOpenJDK Runtime Environment 18.9 (build 11.0.8+10-LTS)OpenJDK 64-Bit Server VM 18.9 (build 11.0.8+10-LTS, mixed mode, sharing)[root@c1 ~]#
2.3安装golang,三台都要装
go下载地址:https://golang.google.cn/dl/
下载后传到三台服务器
[root@c1 ~]# lsgo1.15.3.linux-amd64.tar.gz[root@c1 ~]# tar -C /usr/local/ -zxvf go1.15.3.linux-amd64.tar.gz[root@c1 go]# vim /etc/profile
在 /etc/profile文件末尾加入:
export GOROOT=/usr/local/go export GOPATH=/gowork export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
让刚才的加入的环境变量生效:
[root@c1 go]# source /etc/profile[root@c1 go]# go versiongo version go1.15.3 linux/amd64[root@c1 go]#
3、zookeeper集群安装
官网下载地址:https://zookeeper.apache.org/
下载后传到服务器,三台都要装。
[root@c1 ~]# lsapache-zookeeper-3.6.1-bin.tar.gz[root@c1 ~]#tar -zxvf apache-zookeeper-3.6.1-bin.tar.gz[root@c1 ~]# lsapache-zookeeper-3.6.1-bin apache-zookeeper-3.6.1-bin.tar.gz[root@c1 ~]# mv apache-zookeeper-3.6.1-bin zookeeper[root@c1 ~]# lsapache-zookeeper-3.6.1-bin.tar.gz zookeeper[root@c1 ~]# mv zookeeper/ /usr/local/
设置环境变量:
#在/etc/profile文件最后加入:[root@c1 ~]# vim /etc/profileexport ZOOKEEPER_HOME=/usr/local/zookeeperexport PATH=$PATH:$ZOOKEEPER_HOME/bin#加载配置生效:[root@c1 ~]# source /etc/profile
新建几个目录:
[root@c1 ~]# mkdir -p /data/zookeeper/data[root@c1 ~]# mkdir -p /data/zookeeper/log[root@c1 ~]# mkdir -p /data/zookeeper/conf
分别在三台服务器执行:
[root@c1 ~]# echo 1 > /data/zookeeper/data/myid //server1
[root@c2 ~]# echo 2 > /data/zookeeper/data/myid //server2
[root@c3 ~]# echo 3 > /data/zookeeper/data/myid //server3
修改zookeeper配置文件:
[root@c1 ~]# cp /usr/local/zookeeper/conf/zoo_sample.cfg /data/zookeeper/conf/zoo.cfg
[root@c1 ~]# ln -s /data/zookeeper/conf/zoo.cfg /usr/local/zookeeper/conf/
[root@c1 ~]# vim /data/zookeeper/conf/zoo.cfg
zoo.cfg文件主要配置如下:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper/data
dataLogdir=/data/zookeeper/log
clientPort=2181
server.1=192.168.6.31:2888:3888
server.2=192.168.6.32:2888:3888
server.3=192.168.6.33:2888:3888
保存退出,启动zookeeper:
[root@c1 ~]# zkServer.sh start
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@c1 ~]# netstat -tunlap | grep java
tcp6 0 0 192.168.6.31:3888 :::* LISTEN 3593/java
tcp6 0 0 :::8080 :::* LISTEN 3593/java
tcp6 0 0 :::2181 :::* LISTEN 3593/java
tcp6 0 0 :::36422 :::* LISTEN 3593/java
[root@c1 ~]# zkCli.sh -server 192.168.6.31:2181 //测试连接zookeeper节点
如果看到上述信息说明zookeeper配置正确。
4、安装codis
4.1下载并安装codis
codis下载地址:https://github.com/CodisLabs/codis
下载后传到三台服务器中
[root@c1 ~]# ls
codis-release3.2.zip
[root@c1 ~]# unzip codis-release3.2.zip
[root@c1 ~]# ls
codis-release3.2 codis-release3.2.zip
[root@c1 ~]# mv codis-release3.2 codis
[root@c1 ~]# ls
codis codis-release3.2.zip
[root@c1 ~]#
#创建codis编译目录:$GOPATH是写在profile文件中的变量,这里代表的是/gowork/
[root@c1 ~]# mkdir $GOPATH/src/github.com/CodisLabs -p
一定要按照这个格式来创建,否则会编译安装会报错。
将codis传到刚才新建的目录最底层:
[root@c1 ~]# mv codis /gowork/src/github.com/CodisLabs/
[root@c1 ~]# cd /gowork/src/github.com/CodisLabs/codis/
[root@c1 codis]# ls
admin config Dockerfile Godeps MIT-LICENSE.txt scripts wandoujia_license.txt
ansible deploy example kubernetes pkg vendor
cmd doc extern Makefile README.md version
[root@c1 codis]#make
===============================================================================
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-ha ./cmd/ha
go build -i -o bin/codis-fe ./cmd/fe
[root@c1 codis]# mkdir /usr/local/codis
[root@c1 codis]# mkdir /data/codis/log -p
[root@c1 codis]# cp -R bin /usr/local/codis/
[root@c1 codis]# cp -R admin /data/codis/
[root@c1 codis]# cp -R bin /data/codis/
[root@c1 codis]# cp -R config /data/codis/
目录及配置文件结构如操作已完成,再配置一下环境变量:
#加入下面两行
[root@c1 admin]# vim /etc/profile
export CODIS_HOME=/usr/local/codis
export PATH=$PATH:$CODIS_HOME/bin
[root@c1 admin]# source /etc/profile
4.2配置dashboard
在第三台配置即可
[root@c3 ~]# cd /data/codis/config/
[root@c3 config]# ls
dashboard.toml proxy.toml redis.conf sentinel.conf
[root@c3 config]# vim dashboard.toml
#dashboard.toml需要修改的配置如下:只修改前5行就可以了
[root@c3 config]# grep -v "#" dashboard.toml | grep -v "^$"
coordinator_name = "zookeeper"
coordinator_addr = "192.168.6.31:2181,192.168.6.32:2181,192.168.6.33:2181"
product_name = "codis"
product_auth = ""
admin_addr = "192.168.6.33:18080"
migration_method = "semi-async"
migration_parallel_slots = 100
migration_async_maxbulks = 200
migration_async_maxbytes = "32mb"
migration_async_numkeys = 500
migration_timeout = "30s"
sentinel_client_timeout = "10s"
sentinel_quorum = 2
sentinel_parallel_syncs = 1
sentinel_down_after = "30s"
sentinel_failover_timeout = "5m"
sentinel_notification_script = ""
sentinel_client_reconfig_script = ""
[root@c3 config]#
#启动dashboard
[root@c3 ~]# cd /data/codis/admin/
[root@c3 admin]# ls
codis-dashboard-admin.sh codis-fe-admin.sh codis-proxy-admin.sh codis-server-admin.sh
[root@c3 admin]# ./codis-dashboard-admin.sh start
/data/codis/admin/../config/dashboard.toml
starting codis-dashboard ...
[root@c3 admin]# ps -ef | grep dash
root 12889 1 0 06:36 pts/0 00:00:00 /data/codis/admin/../bin/codis-dashboard --config=/data/codis/admin/../config/dashboard.toml --log=/data/codis/admin/../log/codis-dashboard.log --log-level=INFO --pidfile=/data/codis/admin/../bin/codis-dashboard.pid
root 12898 6105 0 06:36 pts/0 00:00:00 grep --color=auto dash
[root@c3 admin]# netstat -tunlap| grep dash
tcp 0 0 192.168.6.33:18080 0.0.0.0:* LISTEN 12889/codis-dashboa
[root@c3 admin]#
dashboard已经启动,配置完成。
4.3配置proxy
proxy这里只配置2台,分别部署在c1和c2服务器上:
[root@c1 ~]# cd /data/codis/config/
[root@c1 config]# ls
dashboard.toml proxy.toml redis.conf sentinel.conf
[root@c1 config]# vim proxy.toml
product_name = "rayman" #codis集群名称和dashboard的一致
product_auth = "" #dashboard密码(与reids requirepass一致)
session_auth = ""
admin_addr = "172.31.1.31:11080" #与dashboard.toml的admin_addr
proxy_addr = "192.168.6.31:19000" #codis客户端连接端口
jodis_name = "zookeeper" #外部存储类型
jodis_addr = "192.168.6.31:2181,192.168.6.32:2181,192.168.6.33:2181"
jodis_auth = ""
jodis_timeout = "20s"
jodis_compatible = true
session_recv_timeout = “0" #如果不设置为0会导致程序 write:broken pipe问题
#备注:其他参数使用默认配置
第二台proxy就要把配置文件里的IP地址改为c2的服务器的地址
启动proxy:
[root@c1 config]# cd /data/codis/admin/
[root@c1 admin]# ls
codis-dashboard-admin.sh codis-fe-admin.sh codis-proxy-admin.sh codis-server-admin.sh
[root@c1 admin]#
[root@c1 admin]#
[root@c1 admin]# ./codis-proxy-admin.sh start
/data/codis/admin/../config/proxy.toml
starting codis-proxy ...
[root@c1 admin]# ps -ef | grep proxy
root 14356 1 0 06:48 pts/0 00:00:00 /data/codis/admin/../bin/codis-proxy --config=/data/codis/admin/../config/proxy.toml --dashboard=127.0.0.1:18080 --log=/data/codis/admin/../log/codis-proxy.log --log-level=INFO --ncpu=4 --pidfile=/data/codis/admin/../bin/codis-proxy.pid
root 14367 14114 0 06:49 pts/0 00:00:00 grep --color=auto proxy
[root@c1 admin]#
[root@c1 admin]#
[root@c1 admin]# netstat -tunlap|grep proxy
tcp 0 0 0.0.0.0:19000 0.0.0.0:* LISTEN 14356/codis-proxy
tcp6 0 0 :::11080 :::* LISTEN 14356/codis-proxy
[root@c1 admin]#
proxy配置完成
4.4配置sentinel
sentilnel三台都要配置
[root@c1 ~]# cd /data/codis/config/
[root@c1 config]# ls
dashboard.toml proxy.toml redis.conf sentinel.conf
[root@c1 config]# vim sentinel.conf
dir "/data/codis/sentinel"
logfile “/data/codis/logs/sentinel.log”
daemonize yes
protected-mode no
# 备注: 其他参数使用默认配置
[root@c1 ~]# mkdir /data/codis/sentinel //创建sentinel的工作目录
由于没有sentinel的启动文件,而sentinel可以和redis使用相同的启动文件,只需要将redis的启动文件复制一份修改为sentinel即可:
[root@c1 ~]# cd /data/codis/admin/
[root@c1 admin]# cp codis-server-admin.sh codis-sentinel.sh
[root@c1 admin]# vim codis-sentinel.sh
只需要将如下部分做修改就可以了,原理就是将redis-server替换成codis-sentinel
CODIS_SERVER_BIN=$CODIS_BIN_DIR/redis-sentinel
CODIS_SERVER_PID_FILE=/tmp/sentinel.pid
CODIS_SERVER_LOG_FILE=/tmp/sentinel.log
CODIS_SERVER_DAEMON_FILE=$CODIS_LOG_DIR/codis-sentinel.out
CODIS_SERVER_CONF_FILE=$CODIS_CONF_DIR/sentinel.conf
启动sentinel:
[root@c1 admin]# ./codis-sentinel.sh start
/data/codis/admin/../config/sentinel.conf
starting codis-server ...
[root@c1 admin]# ps -ef | grep redis-sentinel
root 14885 1 0 07:13 ? 00:00:00 /data/codis/admin/../bin/redis-sentinel *:26379 [sentinel]
root 15001 14114 0 07:22 pts/0 00:00:00 grep --color=auto redis-sentinel
[root@c1 admin]# netstat -tunlap| grep redis
tcp 0 0 0.0.0.0:26379 0.0.0.0:* LISTEN 14885/redis-sentine
tcp6 0 0 :::26379 :::* LISTEN 14885/redis-sentine
[root@c1 admin]#
sentinel配置完成
4.4配置codis-server
在三台机器上都要配置
[root@c1 ~]# cd /data/codis/config/
[root@c1 config]# vim redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump_6379.rdb
dir /data/codis/redis_6379
logfile “/data/codis/logs/redis_6379.log”
bind 192.168.6.31 #根据自己的主机地址填写
maxmemory 1g #一定要设置最大内存,否则后面的codis无法使用
修改完记得创建/data/codis/redis_6379这个目录,否则会启动失败,启动codis-server:
[root@c1 ~]# cd /data/codis/admin/
[root@c1 admin]# ls
codis-dashboard-admin.sh codis-proxy-admin.sh codis-server-admin.sh
codis-fe-admin.sh codis-sentinel.sh
[root@c1 admin]# ./codis-server-admin.sh start
/data/codis/admin/../config/redis.conf
starting codis-server ...
[root@c1 admin]# ps -ef| grep codis-server
root 15444 1 0 07:41 ? 00:00:00 /data/codis/admin/../bin/codis-server 192.168.6.31:6379
root 15482 14114 0 07:41 pts/0 00:00:00 grep --color=auto codis-server
[root@c1 admin]# netstat -tunlap| grep codis-server
tcp 0 0 192.168.6.31:6379 0.0.0.0:* LISTEN 15444/codis-server
[root@c1 admin]#
codis-server配置完成
4.5配置codis-fe
fe是管理web页面,这里配置在第三台服务器上:
[root@c3 ~]# cd /data/codis/admin/
[root@c3 admin]# ls
codis-dashboard-admin.sh codis-fe-admin.sh codis-proxy-admin.sh codis-server-admin.sh
[root@c3 admin]# vim codis-fe-admin.sh
COORDINATOR_NAME="zookeeper"
COORDINATOR_ADDR="192.168.6.31:2181,192.168.6.32:2181,192.168.6.33:2181"
CODIS_FE_ADDR="0.0.0.0:9090"
只需要配置这里就可以了,启动codis-fe
[root@c3 admin]# ./codis-fe-admin.sh start
starting codis-fe ...
[root@c3 admin]# ps -ef | grep codis-fe
root 13179 1 0 07:50 pts/0 00:00:00 /data/codis/admin/../bin/codis-fe --assets-dir=/data/codis/admin/../bin/assets --zookeeper=192.168.6.31:2181,192.168.6.32:2181,192.168.6.33:2181 --log=/data/codis/admin/../log/codis-fe.log --pidfile=/data/codis/admin/../bin/codis-fe.pid --log-level=INFO --listen=0.0.0.0:9090
root 13209 6105 0 07:52 pts/0 00:00:00 grep --color=auto codis-fe
[root@c3 admin]# netstat -tunlap | grep fe
tcp6 0 0 :::9090 :::* LISTEN 13179/codis-fe
[root@c3 admin]#
codis-fe配置完成,到此命令行部分配置结束,下面开始用web图形界面配置
5、web操作管理
使用浏览器打开codis-fe管理地址:http://ip:port,我们把codis-fe部署在第三台服务器上,端口是9090,直接用浏览器访问这个地址
5.1添加proxy
web管理页面如上图所示,下面开始添加codis-proxy,我们的proxy有2台,分别是192.168.6.31和32,管理端口为11080
两台proxy添加完成。
5.2添加Sentinels
sentinel有三台,端口为26379,依次添加:
新加入的sentinel并未开始同步,点一下SYNC让他们开始协同工作:
sentinel已正常工作
5.3添加redis数据库
首选要对数据库服务器进行分组,创建Group 1
然后对Group 1中添加redis服务器
如果下面从节点服务器未开始同步可以点击它后面的绿色表扳手让他开始同步,如上图所示就是正常的。
5.4对数据分组
codis是将数据从0-1023分成1024份,可以指定哪些编号的数据存放在哪些redis组服务器中,我们这里只有一个组,所以就设置将所有数据分片放在同一个组中,目前默认是这样的,所有分片数据都是离线的
指定分组之后开始迁移数据
迁移完成后:
到此整个架构搭建完成,下面来测试一下对codis的读写操作
6、测试
6.1连接测试
对codis的读写操作都是要经过proxy,也就是直接对proxy进行读写操作就可以了,至于数据怎么分配那是codis自行决定。简单测试一下
[root@c3 ~]# redis-cli -h 192.168.6.31 -p 19000
192.168.6.31:19000> set a 100
OK
192.168.6.31:19000> get a
"100"
192.168.6.31:19000>
在第三台服务器上连接proxy1,使用端口19000,写入一个key,在codis的web管理页面上可以看到已经有了一个key了
也可以使用redis提供的工具来做一下压力测试
6.2使用redis-benchmark
6.2.1用100个线程发送10万个请求:
[root@c3 ~]# redis-benchmark -h 192.168.6.31 -p 19000 -c 100 -n 100000
6.2.2自定义字节数压测(定义字节数为100):
[root@c3 ~]# redis-benchmark -h 192.168.6.31 -p 19000 -q -d 100
6.2.3对某些单独的命令进行压测,如下对set和lpush命令压测,不写就测试全部命令:
[root@c3 ~]# redis-benchmark -h 192.168.6.31 -p 19000 -t ser,lpush -n 10000 -q
6.2.4对某一具体操作进行压测:
[root@c3 ~]# redis-benchmark -h 192.168.6.31 -p 19000 -n 100000 -q script load "redis.call('set','foo','bar')"
其他的测试就不再演示了,codis环境搭建完工。