一 3.0版本之前
在redis3.0版本之前是不支持集群的,我们的redis如果想要集群的话,就需要一个中间件,然后这个中间件负责将我们需要存入redis中的数据的key通过一套算法计算得出一个值。然后根据这个值找到对应的redis节点,将这些数据存在这个redis的节点中,在取值的时候,同样先将key进行计算,得到对应的值,然后就去找对应的redis节点,从对应的节点中取出对应的值,这样做有很多不好的地方,比如说我们的这些计算都需要在系统中去进行,所以会增加系统的负担。还有就是这种集群模式下,某个节点挂掉,其他的节点无法知道。而且也不容易对每个节点进行负载均衡。
二 常见集群方案
1.官方方案redis-cluster搭建实战
2.客户端分片技术(不推荐),扩容/缩容时,必须手动调整分片程序,出现故障不能自动转移
3.可以使用主从复制方式(不推荐)
4.使用一些代理工具
三 Redis-cluster原理
Redis 是一个开源的 key-value 存储系统,由于出众的性能,大部分互联网企业都用来做服务器端缓存。Redis 在3.0版本前只支单点故持单实例模式,虽然支持主从模式、哨兵模式部署来解决障,但是现在互联网企业动辄几百G的数据,可完全是没法满足业务的需求,所以,Redis 在 3.0 版本以后就推出了集群模式。
Redis 集群采用了P2P的模式,完全去中心化。Redis 把所有的 Key 分成了 16384 个 slot,每个 Redis 实例负责其中一部分 slot 。集群中的所有信息(节点、端口、slot等),都通过节点之间定期的数据交换而更新。
Redis 客户端可以在任意一个 Redis 实例发出请求,如果所需数据不在该实例中,通过重定向命令引导客户端访问所需的实例。
每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。
在redis的每一个节点上,都有这么两个东西,一个是插槽(slot)可以理解为是一个可以存储两个数值的一个变量这个变量的取值范围是:0-16383。还有一个就是cluster我个人把这个cluster理解为是一个集群管理的插件。当我们的存取的key到达的时候,redis会根据crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
如果想要集群不是那么容易挂掉,理论上就应该给集群中的每个节点至少一个备用的redis服务。这个备用的redis称为从节点(slave),它们之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。如果某个节点和所有从节点全部挂掉,我们集群就进入faill状态。还有就是如果有一半以上的主节点宕机,那么我们集群同样进入发力了状态。这就是我们的redis的投票机制,具体原理如下图所示:
四 Redis-cluster集群搭建
由于集群至少需要6个节点(3主3从模式),所以,没有这么多机器给我玩,我本地也起不了那么多虚拟机(电脑太烂),现在计划是在一台机器上模拟一个集群,当然,这和生产环境的集群搭 建没本质区别。
(1)我们计划集群中 Redis 节点的端口号为 6001-6006 ,端口号即集群下各实例文件夹。数据存放在 端口号/data 文件夹中。
mkdir /usr/local/redis-cluster
cd redis-cluster/
mkdir -p 6001/data 6002/data 6003/data 6004/data 6005/data 6006/data
(2)复制脚本
在 /usr/local/redis-cluster 下创建 bin 文件夹,用来存放集群运行脚本,并把安装好的 Redis 的 src 路径下的运行脚本拷贝过来。看命令:
cd /usr/local/redis-cluster
mkdir bin
cd /usr/local/redis-3.2.9/src
cp mkreleasehdr.sh redis-benchmark redis-check-aof redis-cli redis-server redis-trib.rb /usr/local/redis-cluster/bin
(3)复制一个新 Redis 实例
我们现在从已安装好的 Redis 中复制一个新的实例到 6001 文件夹,并修改 redis.conf 配置。
cp -r /usr/local/redis /usr/local/redis-cluster/6001
注意,修改 redis.conf 配置和单点唯一区别是下图部分,其余还是常规的这几项:
port 6001(每个节点的端口号)
daemonize yes
bind 192.168.217.131(绑定当前机器 IP)
dir /usr/local/redis-cluster/6001/data/(数据文件存放位置)
pidfile /var/run/redis_6001.pid(pid 6001和port要对应)
cluster-enabled yes(启动集群模式)
cluster-config-file nodes6001.conf(6001和port要对应)
cluster-node-timeout 15000
appendonly yes
(5)再复制出五个新 Redis 实例
我们已经完成了一个节点了,其实接下来就是机械化的再完成另外五个节点,其实可以这么做:把 6001 实例 复制到另外五个文件夹中,唯一要修改的就是 redis.conf 中的所有和端口的相关的信息即可,其实就那么四个位置。开始操作,看命令:
\cp -rf /usr/local/redis-cluster/6001/* /usr/local/redis-cluster/6002
接下来一样,把对应的文件夹修改一下,依次复制。
(6)修改 6002-6006 的 redis.conf 文件
vi /usr/local/redis-cluster/9002/redis/etc/redis.conf
%s/9001/9002
其他的配置文件也一样。
(7)安装集群所需软件
由于 Redis 集群需要使用 ruby 命令,所以我们需要安装 ruby 和相关接口。
yum install ruby
yum install rubygems
gem install redis
(8)集群环境测试
命令:/usr/local/redis-cluster/bin/redis-trib.rb create --replicas 1 192.168.217.131:6001 192.168.217.131:6002 192.168.217.131:6003 192.168.217.131:6004 192.168.217.131:6005192.168.217.131:6006
至此,redis集群环境已搭建完毕。