近几年,随着互联网的飞速发展,做为程序员,咱们须要处理的数据规模也在不断扩大。若是你使用Redis做为数据库时,面临大数据高并发的场景时,单个Redis实例就会显得力不从心。这时Redis的集群方案应运而生,他将众多Redis实例综合起来,共同应对大数据高并发的场景。html
Codis是Redis集群方案的一种。它是由豌豆荚的中间件团队开发的,因此,它有一套详细的中文版README,方便你们学习。git
它的架构如上图所示,由codis-proxy对外提供Redis的服务。ZooKeeper用来存储数据路由表和codis-proxy节点的元信息。codis-proxy会监听全部的redis集群,当Redis集群处理能力达到上限时,能够动态增长Redis实例来实现扩容的需求。程序员
如今咱们已经知道了Codis会将指定key的Redis命令转发给下层的Redis。那么Codis如何知道某个key在哪一个Redis上呢。github
Codis采用Pre-sharding的技术来实现数据分片,默认分为1024个slot(0-1023)。Codis在接收到命令时,先对key进行crc32运算,而后再对1024取余,获得的结果就是对应的slot。而后就能够将命令转发给slot对应的Redis实例进行处理了。redis
Codis的动态扩容/缩容能力是它的一大亮点之一。它能够对Redis客户端透明。在扩容时,Codis提供了SLOTSSCAN指令,这个指令能够扫描指定的slot上的全部key,而后对每一个key进行迁移。在扩容过程当中,若是有新的key须要转发到正在迁移的slot上,那么codis会判断这个key是否须要迁移,若是须要,则对指定的key进行强制迁移,迁移完成后,再将命令转发到新的Redis上。数据库
看了上面的介绍是否是以为扩容是一件很麻烦的事情,Codis已经为咱们考虑到这点了,它提供了自动均衡的功能,只须要在界面上点一下"Auto Rebalance"按钮,就能够自动实现slot迁移(能够说很是贴心了)。缩容也比较简单,只须要将须要下线的实例的slot迁移到其余实例上,而后删除group就能够了。后端
当Redis Group的master挂掉时,codis不会自动将某个slave升为master,codis提供了一个叫作codis-ha的工具,这个工具经过dashboard提供RESTful API来实现自动主从切换。可是,当codis将某个slave升为master时,其余的slave并不会改变状态,仍然会从旧的master上同步数据,这就致使了主从数据不一致。所以,当出现主从切换时,须要管理员手动建立新的sync action来完成数据同步。api
此外,Codis还面临一个比较尴尬的状况就是,因为它不是Redis“亲生”的,所以,当Redis发布了new feature时,它总会慢一步,所以,它须要在Redis发布new feature后迅速遇上,以保持竞争力。bash
Mac用户能够参考这个,其余系统的用户也能够看这个教程。数据结构
安装好之后,验证一下是否安装成功
$ go version
go version go1.11.2 darwin/amd64
复制代码
须要下载到指定目录:$GOPATH/src/github.com/CodisLabs/codis
$ mkdir -p $GOPATH/src/github.com/CodisLabs
$ cd $_ && git clone https://github.com/CodisLabs/codis.git -b release3.2
复制代码
进入源码的codis目录,直接执行make命令便可。编译完成后,bin目录下的结构应该是这样的
$ ll bin
total 178584
drwxr-xr-x 8 jackey staff 256B 11 13 10:57 assets
-rwxr-xr-x 1 jackey staff 17M 11 13 10:57 codis-admin
-rwxr-xr-x 1 jackey staff 18M 11 13 10:56 codis-dashboard
-rw-r--r-- 1 jackey staff 5B 11 21 18:06 codis-dashboard.pid
-rwxr-xr-x 1 jackey staff 16M 11 13 10:57 codis-fe
-rw-r--r-- 1 jackey staff 5B 11 21 18:24 codis-fe.pid
-rwxr-xr-x 1 jackey staff 15M 11 13 10:57 codis-ha
-rwxr-xr-x 1 jackey staff 19M 11 13 10:57 codis-proxy
-rw-r--r-- 1 jackey staff 5B 11 21 18:08 codis-proxy.pid
-rwxr-xr-x 1 jackey staff 1.1M 11 13 10:56 codis-server
-rwxr-xr-x 1 jackey staff 98K 11 13 10:56 redis-benchmark
-rwxr-xr-x 1 jackey staff 161K 11 13 10:56 redis-cli
-rwxr-xr-x 1 jackey staff 1.1M 11 13 10:56 redis-sentinel
-rw-r--r-- 1 jackey staff 170B 11 13 10:56 version
复制代码
到这里为止,咱们的准备工做已经完成了。接下来咱们来看一下如何在单机环境启动测试集群。
进入admin目录,执行codis-dashboard-admin.sh脚本
$ ./codis-dashboard-admin.sh start
/Users/jackey/Documents/go_workspace/src/github.com/CodisLabs/codis/admin/../config/dashboard.toml
starting codis-dashboard ...
复制代码
而后查看日志,观察是否启动成功
$ tail -100 ../log/codis-dashboard.log.2018-11-21
2018/11/21 18:06:57 main.go:155: [WARN] option --pidfile = /Users/jackey/Documents/go_workspace/src/github.com/CodisLabs/codis/bin/codis-dashboard.pid
2018/11/21 18:06:57 topom.go:429: [WARN] admin start service on [::]:18080
2018/11/21 18:06:57 fsclient.go:195: [INFO] fsclient - create /codis3/codis-demo/topom OK
2018/11/21 18:06:58 topom_sentinel.go:169: [WARN] rewatch sentinels = []
2018/11/21 18:06:58 main.go:179: [WARN] [0xc000374120] dashboard is working ...
复制代码
执行codis-proxy-admin.sh脚本
$ ./codis-proxy-admin.sh start
/Users/jackey/Documents/go_workspace/src/github.com/CodisLabs/codis/admin/../config/proxy.toml
starting codis-proxy ...
复制代码
查看是否启动成功
$ tail -100 ../log/codis-proxy.log.2018-11-21
2018/11/21 18:08:34 proxy_api.go:44: [WARN] [0xc0003262c0] API call /api/proxy/start/212d13827c84455d487036d4bb07ce15 from 10.1.201.43:58800 []
2018/11/21 18:08:34 proxy_api.go:44: [WARN] [0xc0003262c0] API call /api/proxy/sentinels/212d13827c84455d487036d4bb07ce15 from 10.1.201.43:58800 []
2018/11/21 18:08:34 proxy.go:293: [WARN] [0xc0003262c0] set sentinels = []
2018/11/21 18:08:34 main.go:343: [WARN] rpc online proxy seems OK
2018/11/21 18:08:35 main.go:233: [WARN] [0xc0003262c0] proxy is working ...
复制代码
执行codis-server-admin.sh脚本
$ ./codis-server-admin.sh start
/Users/jackey/Documents/go_workspace/src/github.com/CodisLabs/codis/admin/../config/redis.conf
starting codis-server ...
复制代码
查看是否启动成功
$ tail -100 /tmp/redis_6379.log
12854:M 21 Nov 18:09:29.172 * Increased maximum number of open files to 10032 (it was originally set to 256).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 3.2.11 (de1ad026/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 12854
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-' `-.__.-'
12854:M 21 Nov 18:09:29.187 # Server started, Redis version 3.2.11
12854:M 21 Nov 18:09:29.187 * The server is now ready to accept connections on port 6379
复制代码
若是执行报错,请先确认使用的用户是否有/tmp/redis_6379.log文件的读写权限。
这里我为了测试Codis的Auto Rebalance功能,因此启动了两个实例。方法很简单,只须要分别将admin/codis-server-admin.sh和config/redis.conf这两个文件复制一份,修改文件中的端口等信息,而后再以一样的方法执行一下新的脚本。
执行codis-fe-admin.sh脚本
$ ./codis-fe-admin.sh start
starting codis-fe ...
复制代码
查看是否执行成功
$ tail -100 ../log/codis-fe.log.2018-11-21
2018/11/21 18:24:33 main.go:101: [WARN] set ncpu = 4
2018/11/21 18:24:33 main.go:104: [WARN] set listen = 0.0.0.0:9090
2018/11/21 18:24:33 main.go:120: [WARN] set assets = /Users/jackey/Documents/go_workspace/src/github.com/CodisLabs/codis/bin/assets
2018/11/21 18:24:33 main.go:162: [WARN] set --filesystem = /tmp/codis
2018/11/21 18:24:33 main.go:216: [WARN] option --pidfile = /Users/jackey/Documents/go_workspace/src/github.com/CodisLabs/codis/bin/codis-fe.pid
复制代码
所有启动成功以后,就能够访问http://127.0.0.1:9090,开始设置集群了。
刚刚咱们启动了两个codis-server,所以,咱们能够new两个group,而后分别将codis-server加入到两个group中
一开始全部的slot都是offline状态。
点击下方的Rebalance All Slots按钮,codis会自动把1024个slot分配给两个group(每一个分512个)。
固然,也能够手动分配slot,好比,咱们将group-1的10个slot分配给group-2,只须要点击Migrate Some按钮便可。
Codis的动态扩容能力简直好用到爆 ,不过目前也存在一些问题(前面咱们也介绍过了)。因此你的集群是否要使用Codis还须要看具体的需求。最后仍是要为Codis的开发团队点赞,另外他们还开发出了一套分布式数据库——TiDB。有兴趣的同窗能够学习一下。