Home >Database >Mysql Tutorial >codis实现redis分片和在线扩展
Codis是一个开源的分布式redis解决方案,由以下四个组件组成: codis-proxy:后端redis的代理,本事实现了redis协议。 codis-config:是codis的管理配置工具,用于增删redis server、操作数据迁移。 zookeeper:用来存放数据路由表和codis-proxy节点的元信息,co
Codis是一个开源的分布式redis解决方案,由以下四个组件组成:
codis-proxy:后端redis的代理,本事实现了redis协议。
codis-config:是codis的管理配置工具,用于增删redis server、操作数据迁移。
zookeeper:用来存放数据路由表和codis-proxy节点的元信息,codis-config发起的命令都会通过 zookeeper同步到各个存活的codis-proxy。
codis-server:codis项目维护的一个 redis 分支, 基于 2.8.13 开发, 加入了 slot 的支持和原子的数据迁移指令,如果要使用codis的在线扩展迁移功能的话必须使用codis自带的codis-server,codis不支持对原生redis做在线的扩展和数据迁移。
节点规划:
codis-proxy |
192.168.0.100:19000 |
codis-config |
192.168.0.100 |
codis-server1 |
192.168.0.100:6381 |
codis-server2 | 192.168.0.100:6382 |
codis-server3 | 192.168.0.100:6380 |
codis-server4 | 192.168.0.100:6383 |
1、安装配置
a、首先安装golang
## 解压下载好的go软件包 $ tar xf/opt/go1.4.2.linux-amd64.tar.gz -C/usr/local/ ## 配置环境变量 在.bash_profile中加入go的相关环境变量,并使新的环境变量生效 PATH=$PATH:$HOME/bin exportGOROOT=/usr/local/go exportGOOS=linux exportGOARCH=amd64 exportGOBIN=$GOROOT/bin exportGOPATH=/opt/mygo PATH=$PATH:$GOBIN export PATH ##编写一个 测试程序验证go是否安装成功 $ cat hello.go package main import"fmt" func main() { fmt.Printf("hello, world\n") } ## 运行测试程序,输出hello,word说明go已经安装成功 $ go run hello.go hello, world
b、安装codis
## 安装工具软件 $ yum install gccmake git -y ## 下载codis,会下载到环境变量GOPATH指定的目录 $ go get github.com/wandoulabs/codis#ssdb-server config packagegithub.com/wandoulabs/codis imports github.com/wandoulabs/codis imports github.com/wandoulabs/codis: nobuildable Go source files in /opt/mygo/src/github.com/wandoulabs/codis ## 下载完成后进入/opt/mygo/src/github.com/wandoulabs/codis $ cd /opt/mygo/src/github.com/wandoulabs/codis ## 执行安装命令 $ ./bootstrap.sh ## 这一步时间稍久,会下载一些文件目录到本地,耐心等待即可
c、安装zookeeper
## 解压zookeeper $ tar xfzookeeper-3.4.6.tar.gz -C /opt/ ## 进入zk的安装目录,修改配置文件 $ cd /opt/zookeeper-3.4.6 $ cp conf/zoo_sample.cfgconf/zoo.cfg $ vim conf/zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/zookeeper dataLogDir=/opt/zookeeper-3.4.6/logs clientPort=2181 ## 创建所需要的目录 mkdir /data/zookeeper -p mkdir /opt/zookeeper-3.4.6/logs ## 启动zk $ /opt/zookeeper-3.4.6/bin/zkServer.sh start JMX enabled bydefault Using config:/opt/zookeeper-3.4.6/bin/../conf/zoo.cfg Starting zookeeper... STARTED ## 验证是否启动成功,若2181端口被监听,则表示成功 $ netstat-alnut|grep 2181 tcp 0 0 :::2181 :::* LISTEN
d、配置codis
## codis中配置zk的信息 $ cd /opt/mygo/src/github.com/wandoulabs/codis/sample/ ## 修改config.ini $ vim config.ini zk=localhost:2181 product=codis_proxy proxy_id=proxy_1 net_timeout=5 dashboard_addr=localhost:18087 coordinator=zookeeper
2、启动codis
a、 启动dashboard
## 进入相关目录 $ cd /opt/mygo/src/github.com/wandoulabs/codis/sample/ ## 启动dashboard ./start_dashboard.sh ## 验证是否成功 $ netstat -alnut|grep 18087 tcp 0 0 :::18087 :::* LISTE
浏览器中访问http://192.168.0.100:18087/admin/,出现如下页面:
b、初始化slots
##进入相关目录 $ cd /opt/mygo/src/github.com/wandoulabs/codis/sample/ ## 执行初始化 $ ../bin/codis-config slot init { "msg": "OK", "ret": 0 }
c、启动codis-server
## codis自带有一个启动脚本,会启动两个codis-server,监听端口为6381和6382 [root@mgs02 sample]#./start_redis.sh sleep 3s [6294] 09 Apr 14:28:02.796* Increased maximum number of open files to 10032 (it was originally set to1024). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 2.8.13 (1e823fd3/1) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in stand alone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6381 | `-._ `._ / _.-' | PID: 6294 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' [6294] 09 Apr14:28:02.814 # Server started, Redis version 2.8.13 [6294] 09 Apr14:28:02.814 # WARNING overcommit_memory is set to 0! Background save may failunder low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to/etc/sysctl.conf and then reboot or run the command 'sysctlvm.overcommit_memory=1' for this to take effect. [6294] 09 Apr14:28:02.814 * The server is now ready to accept connections on port 6381 [6295] 09 Apr14:28:02.795 * Increased maximum number of open files to 10032 (it wasoriginally set to 1024). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 2.8.13 (1e823fd3/1) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in stand alone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6382 | `-._ `._ / _.-' | PID: 6295 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' [6295] 09 Apr14:28:02.811 # Server started, Redis version 2.8.13 [6295] 09 Apr14:28:02.811 # WARNING overcommit_memory is set to 0! Background save may failunder low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to/etc/sysctl.conf and then reboot or run the command 'sysctlvm.overcommit_memory=1' for this to take effect. [6295] 09 Apr 14:28:02.812 * The server is nowready to accept connections on port 6382
d、 添加分片
## 添加分片,每个分片只有一个master节点 $ ../bin/codis-config server add 1192.168.0.99:6381 master "msg": "OK", "ret": 0 } $ ../bin/codis-config server add 2192.168.0.99:6382 master { "msg": "OK", "ret": 0 }
web页面中可以看到新添加的分片组:
e、开启分片
## 开启分片,分片的规则为SlotId= crc32(key) % 1024 $ ../bin/codis-config slot range-set 0 511 1 online { "msg": "OK", "ret": 0 } $ ../bin/codis-config slot range-set 512 1023 2 online { "msg": "OK", "ret": 0 }
f、启动codis-proxy
## 启动codis-proxy $ ../bin/codis-proxy -c config.ini -L ./log/proxy.log --addr=0.0.0.0:19000--http-addr=0.0.0.0:11000 &
web界面显示:
这时codis-proxy是offline的状态,要将其设为online
## 这里的proxy_1为codis-proxy代理的id $ ../bin/codis-config -c config.ini proxyonline proxy_1 { "msg": "OK", "ret": 0 }
web页面查看状态,发现已经为online了
3、测试分片
在插入数据之前,各分片是没有key的,web页面上可以看到
连接代理,并插入数据
## 连接代理 $ ./redis-cli -p 19000 127.0.0.1:19000> ## 代理中插入数据 127.0.0.1:19000>set kora 1 OK 127.0.0.1:19000>set foway 2 OK 127.0.0.1:19000>set kade 3 OK 127.0.0.1:19000>set hongyi 4 OK
web页面中再次查看各分片间数据,各分片上已有数据,说明分片成功
4、在线增加分片
a、添加两个新的分片
## 再启动两个redis实例 $ nohup ../bin/codis-server ./redis_conf/6380.conf &> ./log/redis_6380.log& [2] 6362 $ nohup ../bin/codis-server ./redis_conf/6383.conf &> ./log/redis_6383.log & [3] 6365 ## 将两个新的实例添加到代理中 $ ../bin/codis-config server add 3 192.168.0.99:6380 master { "msg": "OK", "ret": 0 } $ ../bin/codis-config server add 4 192.168.0.99:6383 master { "msg": "OK", "ret": 0 }
web页面查看新添加的节点
b、将group1 上slot_id在256-511间的keys迁移到group3 上去
$ ../bin/codis-config slot migrate 256 511 3 { "msg": "OK", "ret": 0 }
命令执行完成后,数据会在后台进行迁移,web页面中可以看到迁移的状态
查看桶中的key分布
迁移过程中如下,当红色覆盖到511时表明迁移完成,蓝色表示group1,红色为group3
迁移完成后状态
c、将group2 上slot_id在768~2013间的keys迁移到group4 上去
$ ../bin/codis-config slot migrate 768 1023 4 { "msg": "OK", "ret": 0 }
web页面上查看迁移状态
迁移完成后状态
web页面查看分片情况,发现新添加的分片上有了数据
代理中插入数据,看各分片接受数据是否正常
$ ./redis-cli -p19000 127.0.0.1:19000>set avro 19 OK 127.0.0.1:19000>set boss 19 OK 127.0.0.1:19000>set sex 29 OK 127.0.0.1:19000>set zook 29 OK 127.0.0.1:19000>set hadoop 29 OK 127.0.0.1:19000>set kafka 30 OK 127.0.0.1:19000>set word 32 OK 127.0.0.1:19000>set xcode 32 OK
查看web页面各分片接受的keys情况
5、移除分片
a、设置proxy为offline
$ ../bin/codis-config-c config.ini proxy offline proxy_1 { "msg": "OK", "ret": 0 }
b、重新初始化slot
$ ../bin/codis-config slot init -f { "msg": "OK", "ret": 0 }
c、移除分片
$ ../bin/codis-config server remove-group 1 { "msg": "OK", "ret": 0 } $ ../bin/codis-config server remove-group 2 { "msg": "OK", "ret": 0 } $ ../bin/codis-config server remove-group 3 { "msg": "OK", "ret": 0 } $ ../bin/codis-config server remove-group 4 { "msg": "OK", "ret": 0 }
d、web页面查看
1、slot在线迁移不支持原生的redis,只能使用codis内嵌的codis-server(codis-server 是 Codis 项目维护的一个 Redis 分支, 基于 2.8.13 开发, 加入了 slot 的支持和原子的数据迁移指令).
2、slot迁移是原子性的,且对上层应用是安全透明的,迁移的过程中不会阻塞上层业务的服务。
3、迁移的过程中每次只能有一个slot处于迁移状态,所以在迁移操作时,应单片单片的进行迁移,在没有确认当前的迁移是否完成前,不要开启下一个迁移。
4、codis-proxy对原生的redis是有效的,已经测试过(版本redis 2.8.19),但是slot是不支持原生redis的。
5、codis-proxy、slot对SSDB都是无效的,使用codis-proxy代理SSDB是无法实现分片的,数据会落在配置中的第一个分片上。