漫漫长路,其修远兮!
分类: NOSQL
2015-11-27 11:17:52
一.Codis简介
Codis由豌豆荚于2014年11月开源,基于Go和C开发,是近期涌现的、国人开发的优秀开源软件之一。现已广泛用于豌豆荚的各种Redis业务场景(已得到豌豆荚@刘奇同学的确认,呵呵)。从3个月的各种压力测试来看,稳定性符合高效运维的要求。性能更是改善很多,最初比Twemproxy慢20%;现在比Twemproxy快近100%(条件:多实例,一般Value长度)
二.Codis体系结构
Codis 由四部分组成:
Codis Proxy (codis-proxy)
Codis Manager (codis-config)
Codis Redis (codis-server)
ZooKeeper
1. codis-proxy 是客户端连接的 Redis 代理服务, codis-proxy 本身实现了 Redis 协议, 表现 得和一个原生的 Redis 没什么区别 (就像 Twemproxy), 对于一个业务来说, 可以部署多个 codis-proxy, codis-proxy 本身是无状态的.
2. codis-config 是 Codis 的管理工具, 支持包括, 添加/删除 Redis 节点, 添加/删除 Proxy 节点, 发起数据迁移等操作. codis-config 本身还自带了一个 http server, 会启动一个 dashboard, 用户可以直接在浏览器上观察 Codis 集群的运行状态.
3. codis-server 是 Codis 项目维护的一个 Redis 分支, 基于 2.8.21 开发, 加入了 slot 的支持和原子的数据迁移指令. Codis 上层的 codis-proxy 和 codis-config 只能和这个版本的 Redis 交互才能正常运行.
4. Codis 依赖 ZooKeeper 来存放数据路由表和 codis-proxy 节点的元信息, codis-config 发起的命令都会通过 ZooKeeper 同步到各个存活的 codis-proxy.
5. Codis 支持按照 Namespace 区分不同的产品, 拥有不同的 product name 的产品, 各项配置都不会冲突.
三.Codis的特点
1.codis支持水平扩展,对client完全透明,扩容缩容无知感。扩容可以直接界面的 "Auto Rebalance" 按钮,缩容只需要将要下线的实例拥有的slot迁移到其它实例,然后在界面上删除下线的group即可
2.codis是用go语言写的并支持多线程而twemproxy用C并只用单线程,在多核性能上要好于twemproxy
3.就Set操作而言,在Value长度<888B时,Codis性能优越优于Twemproxy(这在一般业务的Value长度范围之内),就Get操作而言,Codis性能一直优于Twemproxy。
4.有管理界面和工具,有提供工具数据迁移工具redis-port
5.Twemproxy本身是一个静态的分布式Redis方案,进行扩容/缩容时候对运维要求非常高,而且很难做到平滑的扩缩容。Codis的目标其实就是尽量兼容Twemproxy的基础上,加上数据迁移的功能以实现扩容和缩容,最终替换Twemproxy
一.测试服务器信息
Ip地址 |
os版本 |
安装应用 |
端口 |
内存大小 |
192.168.6.85 |
Centos6.5 |
Zookeeper |
2181 |
|
192.168.6.85 |
Centos6.5 |
Zookeeper |
2182 |
|
192.168.6.85 |
Centos6.5 |
Zookeeper |
2183 |
|
192.168.6.67 |
Centos6.5 |
Codis config |
|
|
192.168.6.67 |
Centos6.5 |
Codis proxy |
|
|
192.168.6.155 |
Centos6.5 |
Codis Server |
6380 |
|
192.168.6.155 |
Centos6.5 |
Codis Server |
6381 |
|
192.168.6.155 |
Centos6.5 |
Codis Server |
7380 |
|
192.168.6.155 |
Centos6.5 |
Codis Server |
7381 |
|
|
|
|
|
|
二.安装部署
1.安装go环境[6.67,6.155上部署]
wget
国内下载地址:
tar -zxvf go1.4.1.linux-amd64.tar.gz
Bash all.bash
mv go /usr/local/
cd /usr/local/go/src/
bash all.bash
cat >> ~/.bashrc << _bashrc_export
export GOROOT=/usr/local/go
export PATH=\$PATH:\$GOROOT/bin
export GOARCH=amd64
export GOOS=linux
_bashrc_export
source ~/.bashrc
2.安装zookeeper
由于只有一台机器所以在一台机器上面部署3个虚拟的zookeeper
yum -y install zookeeper jdk-----这样安装有问题
wget
mv zookeeper-3.4.6.tar.gz /usr/local/zookeeper
Cp -ra zookeeper zookeeper01
Cp -ra zookeeper zookeeper02
Cp -ra zookeeper zookeeper03
修改机器192.168.6.85名称为zookeeper
/etc/hosts
/etc/sysconfig/network
Reboot
配置虚拟结点1
/usr/local/zookeeper01/conf
cp zoo_sample.cfg zoo.cfg
---------------------------------------------
tickTime=2000 #一个时间单元
initLimit=10
syncLimit=5
dataDir=/usr/local/zookeeper01/data
server.1=zookeeper:8881:7771
server.2=zookeeper:8882:7772
server.3=zookeeper:8883:7773
clientPort=2181
cd /usr/local/zookeeper01/data
echo 1 > myid
结点2
tickTime=2000 #一个时间单元
initLimit=10
syncLimit=5
dataDir=/usr/local/zookeeper01/data
server.1=zookeeper:8881:7771
server.2=zookeeper:8882:7772
server.3=zookeeper:8883:7773
clientPort=2182
cd /usr/local/zookeeper02/data
echo 2 > myid
结点3
tickTime=2000 #一个时间单元
initLimit=10
syncLimit=5
dataDir=/usr/local/zookeeper01/data
server.1=zookeeper:8881:7771
server.2=zookeeper:8882:7772
server.3=zookeeper:8883:7773
clientPort=2183
cd /usr/local/zookeeper03/data
echo 3 > myid
启动zookeeper
/usr/local/zookeeper01/bin/zkServer.sh start
/usr/local/zookeeper02/bin/zkServer.sh start
/usr/local/zookeeper03/bin/zkServer.sh start
Jps -----可以列出本机所有java进程的pid
2980 QuorumPeerMain
3140 Jps
3048 QuorumPeerMain
3099 QuorumPeerMain
如果有QuorunPeerMain进程即表示安装OK
3.安装codis【codis-proxy,codis-config,codis-server】
yum -y install git
export GOPATH=/data/go
go get github.com/wandoulabs/codis
cd /data/go/src/github.com/wandoulabs/codis/
cp /data/go/bin/godep /usr/local/go/bin
Make
ln -fs /data/go/src/github.com/wandoulabs/codis /usr/local/codis
在 codis/bin 文件夹生成 codis-config, codis-proxy 两个可执行文件, (另外, bin/assets 文件夹是 codis-config 的 dashboard http 服务需要的前端资源, 需要和 codis-config 放置在同一文件夹下)
三.配置codis集群
cp /test/config.ini /usr/local/codis/bin/
cat config.ini
zk=192.168.6.85:2181,192.168.6.85:2182,192.168.6.85:2183
product=codis-test
dashboard_addr=192.168.6.67:18087
coordinator=zookeeper
backend_ping_period=5
session_max_timeout=1800
session_max_bufsize=131072
session_max_pipeline=128
proxy_id=proxy_1
1.启动 dashboard(codis-config上操作)
nohup ./bin/codis-config -c /usr/local/codis/bin/config.ini -L ./log/dashboard.log dashboard &
2.初始化 slots (codis-config上操作)
./bin/codis-config -c /usr/local/codis/bin/config.ini slot init
3.启动 Codis Redis , 和官方的Redis Server参数一样(codis-server上操作)
./bin/codis-server /usr/local/codis/etc/codis_6380.conf &
./bin/codis-server /usr/local/codis/etc/codis_6381.conf &
./bin/codis-server /usr/local/codis/etc/codis_7380.conf &
./bin/codis-server /usr/local/codis/etc/codis_7381.conf &
4.添加redis server group,每一个 Server Group 作为一个 Redis 服务器组存在, 只允许有一个 master, 可以有多个 slave, group id 仅支持大于等于1的整数(codis-config上操作)
./bin/codis-config -c /usr/local/codis/bin/config.ini server add 1 192.168.6.155:6380 master
./bin/codis-config -c /usr/local/codis/bin/config.ini server add 1 192.168.6.155:6381 slave
./bin/codis-config -c /usr/local/codis/bin/config.ini server add 2 192.168.6.155:7380 master
./bin/codis-config -c /usr/local/codis/bin/config.ini server add 2 192.168.6.155:7381 slave
这个也可以在网站中操作
5.设置 server group 服务的 slot 范围 Codis 采用 Pre-sharding 的技术来实现数据的分片, 默认分成 1024 个 slots (0-1023), 对于每个key来说, 通过以下公式确定所属的 Slot Id : SlotId = crc32(key) % 1024 每一个 slot 都会有一个特定的 server group id 来表示这个 slot 的数据由哪个 server group 来提供.(codis-config上操作)
./bin/codis-config -c /usr/local/codis/bin/config.ini slot range-set 0 100 1 online
./bin/codis-config -c /usr/local/codis/bin/config.ini slot range-set 101 200 2 online
这个也可以在界面中操作完成
6.启动codis-proxy
./bin/codis-config -c /usr/local/codis/bin/config.ini slot range-set 0 100 1 online
上线proxy_1
./bin/codis-config -c /usr/local/codis/bin/config.ini proxy online proxy_1
这里要把所有的solt 1024个,不然online就会报错
2015/11/12 10:47:54 main.go:154: [PANIC] run sub-command failed
[error]: http status code 500, slot {
"product_name": "codis-test",
"id": 990,
"group_id": -1,
"state": {
"status": "offline",
"migrate_status": {
"from": -1,
"to": -1
},
"last_op_ts": "0"
}
至此所有的codis集群都已经部署好了。总结一下安装部署的过程。
步骤如下
1.在codis-server,codis-proxy,codis-config 机器上安装go的环境
2.安装zookeeper服务
3.安装codis-server,codis-proxy,codis-config。所有的安装都是一样的
4.启动 dashboard在(codis-config机器上)
5.初始化 slots在(codis-config机器上)
6.启动codis-server,建立主从关系(codis-server机器上)
7.添加redis server group(codis-config机器上)
8.设置 server group 服务的 slot
9.启动codis-proxy
四.数据迁移
在 codis-config 管理工具中, 每次迁移任务的最小单位是 slot
如: 将slot id 为 [0-511] 的slot的数据, 迁移到 server group 2上, --delay 参数表示每迁移一个 key 后 sleep 的毫秒数, 默认是 0, 用于限速.
./bin/codis-config slot migrate 0 511 2 --delay=10
也可以在页面中操作完成
Codis 支持动态的根据实例内存, 自动对slot进行迁移, 以均衡数据分布.
./bin/codis-config slot rebalance
要求:
所有的codis-server都必须设置了maxmemory参数
所有的 slots 都应该处于 online 状态, 即没有迁移任务正在执行
所有 server group 都必须有 Master
在页面中完成操作
五.故障手动转移
1.从库挂掉
redis-cli -p 6381 shutdown
./bin/codis-server /usr/local/codis/etc/codis_6381.conf &
2.主库挂掉
redis-cli -p 6380 shutdown
从库提升为主库
老主库恢复
把老主库重新加入到codis-server group中
这时候会自动建立主从关系
六.故障自动转移
codis-ha实现codis-server的主从切换,codis-server主库挂了会提升一个从库为主库,从库挂了会设置这个从库从集群下线
export GOPATH=/data/go
go get github.com/ngaut/codis-ha
cd /data/go/src/github.com/ngaut/codis-ha
go build
cp codis-ha /usr/local/codis/bin/
codis-ha --codis-config=192.168.6.67:18087 --productName=test
需要注意,codis将其中一个slave升级为master时,该组内其他slave实例是不会自动改变状态的,这些slave仍将试图从旧的master上同步数据,因而会导致组内新的master和其他slave之间的数据不一致。因为redis的slave of命令切换master时会丢弃slave上的全部数据,从新master完整同步,会消耗master资源。因此建议在知情的情况下手动操作。使用 codis-config server add