codis是豌豆荚开源的一个类似于twemproxy的redis代理程序,但是它解决了在使用twemproxy过程中遇到的一些问题,比如动态扩容的问题。
Github地址:https://github.com/wandoulabs/codis
架构图:
可以很容易的看出来,codis的架构和上面twemproxy的架构实际上差不多,不过豌豆荚的团队自己做了二次开发,加入了对于zookeeper的依赖,可以很轻松的在不影响现在服务的情况下完成动态扩容。
Codis 由四部分组成:
Codis Proxy (codis-proxy)
Codis Manager (codis-config)
Codis Redis (codis-server)
ZooKeeper
codis-proxy 是客户端连接的 Redis 代理服务, codis-proxy 本身实现了 Redis 协议, 表现得和一个原生的 Redis 没什么区别 (就像 Twemproxy), 对于一个业务来说, 可以部署多个 codis-proxy, codis-proxy 本身是无状态的。
codis-config 是 Codis 的管理工具, 支持包括, 添加/删除 Redis 节点, 添加/删除 Proxy 节点, 发起数据迁移等操作. codis-config 本身还自带了一个 http server, 会启动一个 dashboard, 用户可以直接在浏览器上观察 Codis 集群的运行状态。
codis-server 是 Codis 项目维护的一个 Redis 分支, 基于 2.8.21 开发, 加入了 slot 的支持和原子的数据迁移指令. Codis 上层的 codis-proxy 和 codis-config 只能和这个版本的 Redis 交互才能正常运行。
Codis 依赖 ZooKeeper 来存放数据路由表和 codis-proxy 节点的元信息, codis-config 发起的命令都会通过 ZooKeeper 同步到各个存活的 codis-proxy。
Codis 支持按照 Namespace 区分不同的产品, 拥有不同的 product name 的产品, 各项配置都不会冲突。
go get -u -d github.com/wandoulabs/codis
cd $GOPATH/src/github.com/wandoulabs/codis
./bootstrap.sh
这里第一步和第三步需要从github copy数据,鉴于网络环境的问题,时间会比较长。
之后生成的可执行文件都在 codis/bin 文件夹下。
将 bin 文件夹下的 codis-server 拷贝到集群中每个节点,和redis-server一样,指定配置文件,启动。
这里要注意 redis.conf 配置中需要设置 maxmemory,不然无法自动分配 slot(可以根据每个redis实例可用内存的多少自动进行均衡分配),需要手动配置。
启动web控制面板,注意这里要用到配置文件,不指定的话就是当前目录下的 config.ini,可以用 -c 参数指定。
nohup bin/codis-config -c /etc/config.ini dashboard &
bin/codis-config slot init
该命令会在zookeeper上创建slot相关信息
每个group只能有一个master和多个slave
命令格式: codis-config server add <group_id> <redis_addr> <role>
bin/codis-config server add 1 localhost:6379 master
1 代表 group_id,必须为数字
bin/codis-config server add 1 localhost:6380 slave
codis-config slot range-set <slot_from> <slot_to> <group_id> <status>
例如:
bin/codis-config slot range-set 0 511 1 online
bin/codis-config slot range-set 512 1023 2 online
也可以在dashboard上自动进行分配,需要注意的是slot默认为1024个,范围是0 - 1023。
bin/codis-config slot rebalance
这个会根据内存进行自动分配
bin/codis-proxy -c /etc/config.ini -L ./log/proxy.log –cpu=8 –addr=0.0.0.0:19000 –http-addr=0.0.0.0:11000
codis-proxy是无状态的,可以部署多个,且用go编写,可以利用多核,建议cpu设置核心数的一半到2/3,19000即为访问redis集群的端口,11000为获取相关状态的端口
使用codis-config将 codis-proxy 加入进来,也就是设置online
bin/codis-config -c /etc/config.ini proxy online <proxy_name>
proxy_name通常为 proxy_1 等
需要注意的是 启动codis-proxy,会在zookeeper中注册一个node,地址为 /zk/codis/db_test/fence,如果使用 kill -9 杀掉进程的话,这个会一直存在,需要手工删除。 且node名为 hostname:port,所以需要注意这个组合不能重复。
官方建议是手工操作,避免数据不一致的问题。
另外提供了一个工具,codis-ha(https://github.com/ngaut/codis-ha),这是一个通过codis开放的api实现自动切换主从的工具。该工具会在检测到master挂掉的时候将其下线并选择其中一个slave提升为master继续提供服务。
需要注意的是,其他slave的状态不会改变,还是从原master同步数据。原来的master重启之后处于offline状态,也需要手动加入group指定为slave。 也就是说有master挂掉后,其余机器的状态需要手动修改。 bin/codis-config server add 1 192.168.177.130:6379 slave
官方提供了一个 redis-port 工具可以将旧redis中的数据实时迁移到 codis 集群中,之后需要修改各服务配置文件,重启服务,指向codis集群即可。
测试命令:redis-benchmark -p 11001 -r 1048576 -c 100 -d 256 -t set,get,mset –csv -n 100000
测试环境: 开发机,24核 2.1GHz,4个redis实例
不启用pipeline
SET | GET |
MSET(10 keys) | |
redis单机 | 58997 | 58651 | 33557 |
codis,1核,单proxy | 42973 | 33003 | 12295 |
codis,4核,单proxy | 44208 | 39936 | 21743 |
codis,8核,单proxy | 39478 | 23052 | 24679 |
codis,12核,单proxy | 28943 | 24224 | 21376 |
codis,8核,2proxy | 62085 | 68964 | 48298 |
pipeline=100
SET | GET | MSET(10 keys) | |
redis单机 | 259067 | 340136 | 40387 |
codis,1核,单proxy | 158982 | 166112 | 15199 |
codis,4核,单proxy | 491159 | 403551 | 40157 |
codis,8核,单proxy | 518134 | 537634 | 58156 |
codis,12核,单proxy | 520833 | 500000 | 53418 |
codis,8核,2proxy | 529812 | 607041 | 62872 |
由于redis实例,codis都部署在开发机上,并且redis-benchmark测试程序也是跑在开发机上,所以数据准确性上会有一些误差,比如codis和测试客户端不能充分发挥多核的特性。
4个redis实例,设置内存上限1GB:
192.168.98.84:11001
192.168.98.84:11002
192.168.98.84:11003
192.168.98.84:11004
2个codis-proxy:
192.168.98.84:10900
192.168.98.84:10901
zookeeper集群:
目前用的开发机上的zookeeper,端口 2181
dashboard:
192.168.98.84:18087
可以通过web界面进行一些操作,并且可以看到每个redis实例的状态以及当前整个集群的qps数据。