Redis集群
Redis集群
Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N即切片集群,也叫分片集群。解决了大型单实例持久化阻塞主线程的问题,也方便了扩容问题。
并且Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
数据切片和实例的对应分布关系
切片集群是一种保存大量数据的通用机制,这个机制可以有不同的实现方案。一般使用的是Redis Cluster,这里也讲的是Redis Cluster。
Redis Cluster 方案采用哈希槽(Hash Slot,接下来我会直接称之为 Slot),来处理数据和实例之间的映射关系。
在 Redis Cluster 方案中,一个切片集群共有 16384 个哈希槽,这些哈希槽类似于数据分区,每个键值对都会根据它的 key,被映射到一个哈希槽中。
映射过程:
- 根据键值对的 key,按照CRC16 算法计算一个 16 bit 的值
- 再用这个 16bit 值对 16384 取模,得到的模数代表一个相应编号的哈希槽。
哈希槽分摊:
- 可以使用
cluster create
命令创建集群,自动平均分配 - 也可以使用
cluster meet
命令手动建立实例间的连接,形成集群,再使用cluster addslots
命令,指定每个实例上的哈希槽个数。(在手动分配哈希槽时,需要把 16384 个槽都分配完,否则 Redis 集群无法正常工作。)
集群的方案选择
集群方案目前主要有两种:
- Codis
- Redis Cluster
两者区别:
选择建议:
- 从稳定性和成熟度来看,Codis 应用得比较早,在业界已经有了成熟的生产部署。虽然 Codis 引入了 proxy 和 Zookeeper,增加了集群复杂度,但是,proxy 的无状态设计和 Zookeeper 自身的稳定性,也给 Codis 的稳定使用提供了保证。而 Redis Cluster 的推出时间晚于 Codis,相对来说,成熟度要弱于 Codis,如果你想选择一个成熟稳定的方案,Codis 更加合适些。
- 从业务应用客户端兼容性来看,连接单实例的客户端可以直接连接 codis proxy,而原本连接单实例的客户端要想连接 Redis Cluster 的话,就需要开发新功能。所以,如果你的业务应用中大量使用了单实例的客户端,而现在想应用切片集群的话,建议你选择 Codis,这样可以避免修改业务应用中的客户端。
- 从使用 Redis 新命令和新特性来看,Codis server 是基于开源的 Redis 3.2.8 开发的,所以,Codis 并不支持 Redis 后续的开源版本中的新增命令和数据类型。另外,Codis 并没有实现开源 Redis 版本的所有命令,比如 BITOP、BLPOP、BRPOP,以及和与事务相关的 MUTLI、EXEC 等命令。Codis 官网上列出了不被支持的命令列表,你在使用时记得去核查一下。所以,如果你想使用开源 Redis 版本的新特性,Redis Cluster 是一个合适的选择。
- 从数据迁移性能维度来看,Codis 能支持异步迁移,异步迁移对集群处理正常请求的性能影响要比使用同步迁移的小。所以,如果你在应用集群时,数据迁移比较频繁的话,Codis 是个更合适的选择。
客户端如何定位数据?
在定位键值对数据时,它所处的哈希槽是可以通过计算得到的,但是还需要指定哈希槽分布在哪个实例上。
Redis 实例会把自己的哈希槽信息发给和它相连接的其它实例,来完成哈希槽分配信息的扩散。当实例之间相互连接后,每个实例就有所有哈希槽的映射关系了。
客户端收到哈希槽信息后,会把哈希槽信息缓存在本地。当客户端请求键值对时,会先计算键所对应的哈希槽,然后就可以给相应的实例发送请求了。
当对应关系已经发生变化:
Redis Cluster 方案提供了一种重定向机制,如果实例上没有该数据,会用
MOVED命令
带着新实例地址响应给客户端,收到后更新本地缓存再重新请求。当Slot正在进行迁移:
如果实例上没有该数据,会用
ASK命令
来返回新实例地址,收到后不会更新本地缓存,并发送ASKING命令
再发送操作命令。
无中心化集群的搭建
进行每个服务器的配置
1
2
3
4
5
6
7
8
9
10include /home/bigdata/redis.conf #导入基础配置文件
port 6379 #设置端口
pidfile "/var/run/redis_6379.pid" #设置redis的进程文件
dbfilename "dump6379.rdb" #设置数据备份文件
dir "/home/bigdata/redis_cluster" #设置数据目录,数据库的写入会在这个目录。rdb、aof文件也会写在这个目录
logfile "/home/bigdata/redis_cluster/redis_err_6379.log" #设置日志文件地址
cluster-enabled yes #打开集群模式
cluster-config-file nodes-6379.conf #设定节点配置文件名不需要我们创建,由redis自己维护
cluster-node-timeout 15000 #设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换。启动各个redis服务
合成集群:
redis-cli --cluster create --cluster-replicas 1 所有主机ip:端口
(每一台主机后跟几个从机,这里写1是一主一从 –replicas 1 采用最简单的方式配置集群,一台主机,一台从机;一般前几个是主后几个是从)以集群方式连接:
redis-cli -c -p 6379 -a 123321
进入客户端后可以通过
cluster nodes
命令查看集群状态
查询集群中某个插槽的值:
CLUSTER GETKEYSINSLOT <slot> <count>