1. Redis集群原理
构建Redis集群,需要至少3个节点作为master,以此组成一个高可用的集群,此外每个master都需要配备一个slave,所以整个集群需要6个节点,这也是最经典的Redis集群,也可以称之为三主三从,容错性更佳。
1、16384个slots(*槽位*) **
Redis Cluster没有单机的那种16个数据库(0-15)的概念,而是分成了16384个slots(槽位),每个节点负责其中一部分槽位,槽位的信息存储于每个节点中;当客户端来连接集群时,它先得到一份集群的槽位配置信息并将其缓存在客户端本地。这样当客户端要查找某个key时,可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不一致的情况,还需要纠正机制来实现槽位信息的校验调整。
2、槽位定位算法
Redis Cluster默认会对key值使用CRC16算法进行hash得到一个整数值,然后用这个整数值对16384进行取模来得到具体槽位。HASH_SLOT = CRC16(key) mod 16384
3、跳转重定位
当客户端向一个错误的节点发出了指令,该节点会发现指令的key所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有key将使用新的槽位映射表。
2. redis高可用集群搭建步骤**
1.下载redis
wget https://github.com/redis/redis/archive/6.2-rc1.tar.gz
tar axf 6.2-rc1.tar.gz
cd 6.2-rc1 && make
2.集群环境(本地一台linux主机,采用伪集群模式搭建),实际搭建按照生产环境需求搭建
cd 6.2-rc1
mkdir redis-cluster #创建集群相关目录
cd redis-cluster
mkdir {redis-cluster-7000,redis-cluster-7001,redis-cluster-7002,redis-cluster-7003,redis-cluster-7004,redis-cluster-7005,redis-cluster-7006,redis-cluster-7007,redis-cluster-7008}
cp ../redis.conf ./redis-cluster-7000/ #copy集群配置文件,进行配置集群
vim ./redis-cluster7000/redis
protected-mode no (关闭保护模式)
port 6379
daemonize yes (设置redis在后台启动)
pidfile /var/run/redis_6379.pid
logfile "/opt/module/redis/6379/logs/redis_6379.log" (设置日志文件的存放位置)
dbfilename dump_6379.rdb (设置dump文件名)
dir "/opt/module/redis/6379" (设置dump文件和nodes文件的存放位置)
masterauth bigdata (设置集群节点间访问密码,跟上面一致)
requirepass bigdata (设置redis访问密码)
cluster-enabled yes (启动集群模式)
cluster-config-file nodes-6379.conf (集群节点信息文件,这里800x最好和port对应上)
cluster-node-timeout 5000
bind 0.0.0.0
appendonly yes
3.替换集群配置文件相关参数内容
for i in {1,2,3,4,5,6,7,8} ;do sed "s/7000/700$i/g" ./redis-cluster-7000/redis.conf >./redis-cluster-700$i/redis.conf;done
4.启动redis
for i in {0,1,2,3,4,5};do ../src/redis-server ./redis-cluster-700$i/redis.conf ;done
ps -ef |grep redis
5.创建集群&&连接集群
#创建集群
../src/redis-cli --cluster create 121.37.166.20:7000 121.37.166.20:7001 121.37.166.20:7002 121.37.166.20:7003 121.37.166.20:7004 121.37.166.20:7005 --cluster-replicas 1
#连接集群测试
[root@node1 redis-cluster]# ../src/redis-cli -c -p 7000
127.0.0.1:7000> cluster nodes
e22c6e6aa38df2987f73b25220bd11ac19f25550 121.37.166.20:7005@17005 slave 7ed993561b2f694231182595680c143a3748db55 0 1610291284000 2 connected
1ff20d857f05498105be84e6e5585d1be2fd7583 121.37.166.20:7003@17003 slave 6a2d961024a7bebc69c3060906bf8beaa6c1f132 0 1610291283000 3 connected
6a2d961024a7bebc69c3060906bf8beaa6c1f132 121.37.166.20:7002@17002 master - 0 1610291283997 3 connected 10923-16383
255327ff2a63376701c6e216030f19ea3bb91b01 121.37.166.20:7004@17004 slave e25a018ac7da5e9064d2eed35213b6e1730c25fc 0 1610291285002 1 connected
7ed993561b2f694231182595680c143a3748db55 121.37.166.20:7001@17001 master - 0 1610291282000 2 connected 5461-10922
e25a018ac7da5e9064d2eed35213b6e1730c25fc 192.168.0.102:7000@17000 myself,master - 0 1610291283000 1 connected 0-5460
127.0.0.1:7000>
3. Redis集群的水平扩容
-
启动新增加redis节点
../src/redis-server ./redis-cluster-7006/redis.conf ../src/redis-server ./redis-cluster-7007/redis.conf #登录到新节点查看节点状态 ../src/redis-cli -h localhost -p 7006 cluster nodes
-
执行添加节点命令
add-node new_host:new_port existing_host:existing_port #新节点ip:端口 已存在的节点ip跟端口 7000-7005任意一个,因为已存在的节点已经是一个集群了。 --cluster-slave --cluster-master-id
#添加节点命令,默认是以主节点加入 ../src/redis-cli --cluster add-node 121.37.166.20:7006 121.37.166.20:7005 #添加从节点,并指定master id(master就是7006的id) ../src/redis-cli --cluster add-node 121.37.166.20:7007 121.37.166.20:7005 --cluster-slave --cluster-master-id 03d491827c9614cf6d5af2bad8041e6aba5a5a47 #登录到新添加的节点,查看节点状态 ../src/redis-cli -c -p 7006 cluster nodes
执行加入主节点与从节点后查看节点状态信息(可以根据id查看到7006是master节点 7007是slave节点)
添加从节点,并指定master id(master就是7006的id)
../src/redis-cli --cluster add-node 121.37.166.20:7007 121.37.166.20:7005 --cluster-slave --cluster-master-id 03d491827c9614cf6d5af2bad8041e6aba5a5a47
给新增节点分配槽位
../src/redis-cli --cluster help
reshard host:port #ip:端口 任意一个ip跟端口,因为现在8个实例已经是一个集群
--cluster-from
--cluster-to
--cluster-slots
--cluster-yes
--cluster-timeout
--cluster-pipeline
--cluster-replace
1.进行槽位分配,分配的槽位跟数据同时分配到机器上去
../src/redis-cli --cluster reshard 121.37.166.20:7000
2.需要多少个槽移动到新的节点上,自己设置,比如4000个hash槽
How many slots do you want to move (from 1 to 16384)? 4000
3.把这4000个hash槽移动到哪个节点上去,需要指定节点id
What is the receiving node ID? 03d491827c9614cf6d5af2bad8041e6aba5a5a47
4.输入all为从所有主节点(7000,7001,7002)中分别抽取相应的槽数指定到新节点中,抽取的总槽数为4000个
也可以通过某个id进行分配(指定的id进行槽位的分配)填入节点id done 进行槽位分配
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
4. Redis集群的水平缩容
1.先将主节槽位迁移到指定节点,无法进行平均到每个节点
../src/redis-cli --cluster reshard 121.37.166.20:7000 --cluster-from id --cluster-to id --cluster-slots 4000
2.进行节点删除(先删除从节点,再删除主节点)
del-node host:port node_id#节点ip:端口(集群任意ip跟端口,因为现在集群是一个整体),节点id
../src/redis-cli --cluster del-node 121.37.166.20:7000 从节点id