Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有显著区别 (不支持的命令列表), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务。
Codis的主要特性如下:
Codis 采用 Pre-sharding 的技术来实现数据的分片, 默认分成 1024 个 slots (0-1023), 对于每个key来说, 通过以下公式确定所属的 Slot Id : SlotId = crc32(key) % 1024。
每一个 slot 都会有一个且必须有一个特定的 server group id 来表示这个 slot 的数据由哪个 server group 来提供。数据的迁移也是以slot为单位的。
Codis 3.x 由以下组件组成:
Codis Server:基于 redis-3.2.8 分支开发。增加了额外的数据结构,以支持 slot 有关的操作以及数据迁移指令。具体的修改可以参考文档 redis 的修改。
Codis Proxy:客户端连接的 Redis 代理服务, 实现了 Redis 协议。 除部分命令不支持以外(不支持的命令列表),表现的和原生的 Redis 没有区别(就像 Twemproxy)。
Codis Dashboard:集群管理工具,支持 codis-proxy、codis-server 的添加、删除,以及据迁移等操作。在集群状态发生改变时,codis-dashboard 维护集群下所有 codis-proxy 的状态的一致性。
Codis Admin:集群管理的命令行工具。
Codis FE:集群管理界面。
Storage:为集群状态提供外部存储。
基于二进制的代码进行演示
在一台机器上部署所有的服务,部署机器为:testcluster1v.zzt.ddddd.cn
所有操作都在codis3.2.2-go1.9.2-linux目录下执行
在本机配置好zookeeper,本文不对该流程进行描述
将一下配置保存proxy.toml:
jodis_name = "zookeeper"
jodis_addr = "testcluster1v.zzt.ddddd.cn:2181"
jodis_timeout= "20s"
jodis_compatible = true
启动Proxy:$./codis-proxy --zookeeper=testcluster1v.zzt.ddddd.cn:2181 --config=proxy.toml
启动dashboard:$././codis-dashboard --zookeeper=testcluster1v.zzt.ddddd.cn:2181
首先将创建redis配置文件,redis.conf,内容如下:
bind 0.0.0.0
protected-mode no
启动server:./codis-server redis.conf
为了演示master-slave效果,可以在启动个实例:./codis-server --port 6380
启动fe:$ ./codis-fe --ncpu=4 --log=fe.log --log-level=
WARN --zookeeper=testcluster1v.zzt.ddddd.cn:2181 --listen=:8080
服务都启动完之后,打开http://testcluster1v.zzt.ddddd.cn:8080/#codis-demo
此时,按照下面的顺序进行操作
通过4台机器模拟集群的搭建
机器 | 角色 |
---|---|
testcluster1v.zzt.ddddd.cn | Zookeeper(只用单节点),fe,dashboard,server,proxy,sentinel |
testcluster2v.zzt.ddddd.cn | server,proxy,sentinel |
testcluster3v.zzt.ddddd.cn | server,proxy,sentinel |
testcluster4v.zzt.ddddd.cn | server,proxy,sentinel |
codis-fe,codis-dashboard,codis-fe的配置与单机相同,且只需要在一个机器上运行
codis-server,codis-proxy的配置也与单机配置相同,只是运行在多台机器上
最终分组配置以及代理的配置信息如下:
只要是进行高可用的架构部署,那么就必须保证多节点,在Redis里面使用了主从模式可以实现多节点配置,但是传统的主从模式的设计有一个缺陷:一旦Master主机出现了问题之后,两台Slave主机将无法提供正常的工作支持,例如:slave主机为只读主机,而且如果要想继续提供支持,那么你至少应该通过剩余的几台slave里面去推选出一个新的master,并且最为重要的是,这个新的master还必须能够被用户的程序找到,哨兵机制就可以达到该目的。
基于Codis配置哨兵非常简单,只需简单的配置,就可以完成哨兵的配置。
配置步骤如下:
port 26379
bind 0.0.0.0
protected-mode no
对 Java 用户来说,可以使用基于 Jedis 的实现 Jodis ,来实现 proxy 层的 HA:
它会通过监控 zookeeper 上的注册信息来实时获得当前可用的 proxy 列表,既可以保证高可用性;
也可以通过轮流请求所有的proxy实现负载均衡。
Maven配置:
io.codis.jodis
jodis
0.5.1
Java代码:
package com.eric.redis;
import redis.clients.jedis.Jedis;
import io.codis.jodis.RoundRobinJedisPool;
import io.codis.jodis.JedisResourcePool;
public class JodisSample {
public static void main(String[] args) {
JedisResourcePool jedisPool = RoundRobinJedisPool.create().
curatorClient("testcluster1v.zzt.ddddd.cn:2181", 30000).zkProxyDir("/zk/codis/db_codis-demo/proxy").build();
try (Jedis jedis = jedisPool.getResource()) {
for (int i = 0; i < 100; i++) {
jedis.set("ikey"+i,"value"+i);
}
jedis.set("foo", "bar");
String value = jedis.get("foo");
System.out.println(value);
}
}
}