Redis-Cluster集群(上)

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis-Cluster集群

一、Redis-Cluster集群概述


(1)Cluster集群概述


在Redis5.0版本发布时,推出了各种新特性,其中一点就是放弃Ruby的集群方式,改为使用C语言编写的redis-cli的方式,使集群的构建方式的复杂度降低,在Redis3.0以前的版本要实现集群一般都是借助哨兵sentinel工具来监控Master节点的状态,如果Master出现故障则会进行故障转移,主从切换,选择一台数据较完整的Slave来做Master,哨兵的配置略微复杂,并且性能和高可用方面表现一般,特别是在主从进行切换时,会有访问瞬断的情况,而且哨兵模式只有一个Master对外提供写服务,没办法支持很高的并发,并且单个主节点的内存也不能设置的太大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率


哨兵模式的缺陷:


  1. 哨兵的配置略微复杂,并且性能和高可用方面表现一般,特别是在主从进行切换时,会有访问瞬断的情况
  2. 哨兵模式只有一个Master对外提供写服务,没办法支持很高的并发
  3. 单个主节点的内存也不能设置的太大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率


  • 之前没有Cluster之前使用的是Codis(豌豆荚)+redis


(2)Redis数据分区


Redis-Cluster采用虚拟槽进行分区,所有的键根据hash哈希函数映射到0—16383个整数槽内,总共有16384个整数槽


计算公式为:Slot=CRC16(key)&16384


每个节点负责维护一部分虚拟槽以及虚拟槽所映射的键值数据


Redis集群中的每个节点都负责虚拟槽的子集,例如:


一个集群有三个节点,那么


节点A包含从0到5500的散列槽。


节点B包含从5501到11000的散列槽。


节点C包含从11001到16383的散列槽。


当用户创建键时,比如set aaa bbb,Redis会根据上面的算法计算出这个键的值,这个值不超过16383,假如说算出的值为5700,那么这个键就会保存在节点B中。当用户访问某个键时,这个键肯定也会有一个值,例如3500,那么就会从节点A上面去读取。但是用户连接的数据库时节点A,但是访问的数据在节点B怎么办,那么节点A会直接转发请求到节点B上去读取数据

69371e6570b7467f8de23a1aa8fe22bb.png

(3)Redis-Cluster集群搭建


Redis集群至少需要3个节点,因为Cluster集群的投票容错机制要求至少半数节点认为某个节点挂了,该节点才算是挂了,当只有两个节点时是无法进行投票的,所以说至少需要3个节点


要保证集群的高可用,需要每个Master主节点都有一个Slave从节点,也就是用来备份的节点,在这个基础上,Redis-Cluster至少需要6台服务器,最终组成的集群架构是三主三从


(4)集群选举原理分析(ping-pong机制)


选举流程:(PING-PONG机制)


当Slave发现自己的Master变成Fail(失败)状态时,会尝试发起选举,以成为新的Master,由于挂掉的Master可能会有多个Slave,从而会存在多个Slave去竞争Master节点的过程:


  1. Slave发现自己的Master变成Fail(失败)状态
  2. Slave会将自己记录的集群currentEpoch(选举轮次标记)加1,并广播信息到集群中的其他节点
  3. 集群中的其他节点接收到Slave广播的消息,只有Master主节点会进行响应,判断请求者的合法性(就是确认选举Slave的Master确实是挂了),并且发送结果
  4. 尝试选举Master的Slave会收集其他节点的Master返回的结果,收到超过半数节点的Master的同意后,这个Slave就会变成新的Master
  5. 广播Pong消息通知其他集群的节点


这是成功选举的过程,前四步就是Ping的机制,而第五步就是Pong的机制,但是如果选举不成功怎么办:


如果这次Slave的选举没有成功,例如,三个节点组成的集群,三个节点分别是节点A、B、C,每个节点都有两个从服务器,当A节点的Master挂了之后,A节点的两个从服务器都会进行选举,最后的结果是B投给了第一个从服务器,C投给了第二个从服务器,这个时候会发生第二次选举,选举轮次加1继续上面的选举流程,直到选举成功


当集群中其中一台主机挂掉后,是不会影响客户端的查询和写入的,但是不能挂掉多于集群半数的主机数量


(5)跳转重定位


当客户端想获取指定的A键,但是它访问的节点中没有A键,被访问的节点会发现客户端想要获取的键自己这里没有,这个时候被访问的节点会向客户端发送一个特殊的跳转指令,这个指令会携带带有A键的节点的地址,告诉客户端去连接这个节点获取A键,客户端收到跳转指令后除了会跳转到正确的节点上去操作外,还会同步更新自己的槽位映射表缓存,后续的所有键都会使用新的槽位映射表,下次访问A键的时候会直接访问正确的节点


二、部署Redis-Cluster集群


(1)实验环境


此次实验使用的Redis版本均为Redis-5.0.4版本,三个服务器上部署双实例



系统 主机名 ip 端口
Centos7.4 Centos1 192.168.100.202 6379
Centos7.4 Centos1 192.168.100.202 6380
Centos7.4 Centos2 192.168.100.203 6379
Centos7.4 Centos2 192.168.100.203 6380
Centos7.4 Centos3 192.168.100.204 6379
Centos7.4 Centos3 192.168.100.204 6380



(2)实验步骤


-配置hosts文件

******(1)修改centos1,并编写hosts文件
[root@Centos7 ~]# hostnamectl set-hostname centos1
[root@Centos7 ~]# su
[root@centos1 ~]# echo ""'
192.168.100.202 centos1
192.168.100.203 centos2
192.168.100.204 centos3
''' >> /etc/hosts
[root@centos1 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.202 centos1
192.168.100.203 centos2
192.168.100.204 centos3
[root@centos1 ~]# scp /etc/hosts root@192.168.100.203:/etc/hosts
[root@centos1 ~]# scp /etc/hosts root@192.168.100.204:/etc/hosts
******(2)修改centos2
[root@Centos7 ~]# hostnamectl set-hostname centos2
[root@Centos7 ~]# su
[root@centos2 ~]# 
******(3)修改centos3
[root@Centos7 ~]# hostnamectl set-hostname centos3
[root@Centos7 ~]# su
[root@centos3 ~]# 

-在centos1上,上传redis软件包,并且编译

[root@centos1 ~]# ll
总用量 1928
-rw-------. 1 root root    1264 1月  12 18:27 anaconda-ks.cfg
-rw-r--r--  1 root root 1966337 6月   9 23:49 redis-5.0.4.tar.gz
[root@centos1 ~]# tar xf redis-5.0.4.tar.gz 
[root@centos1 ~]# cd redis-5.0.4
[root@centos1 redis-5.0.4]# make 
[root@centos1 redis-5.0.4]# cd

-centos1的配置

******(1)创建工作目录
[root@centos1 ~]# mkdir -p /etc/redis/cluster/{6379,6380}
[root@centos1 ~]# ll /etc/redis/cluster/
总用量 0
drwxr-xr-x 2 root root 6 6月   9 23:47 6379
drwxr-xr-x 2 root root 6 6月   9 23:47 6380
******(2)创建数据存储目录
[root@centos1 ~]# mkdir -p /data/redis/data/{6379,6380}
[root@centos1 ~]# ll /data/redis/data/
总用量 0
drwxr-xr-x 2 root root 6 6月   9 23:48 6379
drwxr-xr-x 2 root root 6 6月   9 23:48 6380
******(3)为centos1部署双实例
[root@centos1 ~]# cp redis-5.0.4/redis.conf /etc/redis/cluster/6379/
[root@centos1 ~]# cp redis-5.0.4/redis.conf /etc/redis/cluster/6380/
******(4)修改配置文件
[root@centos1 ~]# vim /etc/redis/cluster/6379/redis.conf 
。。。。。。
  68 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  69 bind 192.168.100.202  #指定此实例的ip
  70 
。。。。。。
  88 protected-mode no #关闭安全模式
  89 
  90 # Accept connections on the specified port, default is 6379 (IANA #815344).
  91 # If port 0 is specified Redis will not listen on a TCP socket.
  92 port 6379  #指定此实例的端口
  93 
。。。。。。
 135 # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
 136 daemonize yes
 137 
。。。。。。
 170 # output for logging but daemonize, logs will be sent to /dev/null
 171 logfile "/var/log/redis/redis_6379.log"  #指定日志存放路径
 172  
。。。。。。
 262 # Note that you must specify a directory here, not a file name.
 263 dir /data/redis/data/6379  #指定RDB文件存放路径
 264 
。。。。。。
 837 #
 838  cluster-enabled yes #去掉注释,开启集群
 839 
。。。。。。
 845 #
 846 cluster-config-file nodes-6379.conf
 847 
。。。。。。
 851 #
 852  cluster-node-timeout 15000  #请求超时,单位为毫秒,15000为15秒
 853 
。。。。。。
#保存退出
————————————————————————————————————————
#可以直接这样,因为配置都相同,只需要修改一下端口号就行
[root@centos1 ~]# cp /etc/redis/cluster/6379/redis.conf  /etc/redis/cluster/6380/redis.conf 
cp:是否覆盖"/etc/redis/cluster/6380/redis.conf"? yes
[root@centos1 ~]# sed -i 's/6379/6380/g' /etc/redis/cluster/6380/redis.conf 
————————————————————————————————————————
[root@centos1 ~]# vim /etc/redis/cluster/6380/redis.conf 
。。。。。。
  68 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  69 bind 192.168.100.202
  70 
。。。。。。
  88 protected-mode no
  89 
  90 # Accept connections on the specified port, default is 6379 (IANA #815344).
  91 # If port 0 is specified Redis will not listen on a TCP socket.
  92 port 6380  #修改端口
  93 
。。。。。。
 135 # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
 136 daemonize yes  #放到后台运行
 137 
。。。。。。
 157 # nothing bad happens, the server will start and run normally.
 158 pidfile /var/run/redis_6380.pid  #修改一下pid文件
 159 
。。。。。。
 170 # output for logging but daemonize, logs will be sent to /dev/null
 171 logfile "/var/log/redis/redis_6380.log"  #指定日志存放路径
 172 
。。。。。。
 262 # Note that you must specify a directory here, not a file name.
 263 dir /data/redis/data/6380  #指定RDB文件存放路径
 264 
。。。。。。
 838  cluster-enabled yes
 839 
 840 # Every cluster node has a cluster configuration file. This file is not
 841 # intended to be edited by hand. It is created and updated by Redis nodes.
 842 # Every Redis Cluster node requires a different cluster configuration file.
 843 # Make sure that instances running in the same system do not have
 844 # overlapping cluster configuration file names.
 845 #
 846 cluster-config-file nodes-6380.conf
 847 
 848 # Cluster node timeout is the amount of milliseconds a node must be unreachable
 849 # for it to be considered in failure state.
 850 # Most other internal time limits are multiple of the node timeout.
 851 #
 852 cluster-node-timeout 15000
。。。。。。
#保存退出
[root@centos1 ~]# mkdir -p /usr/local/redis
[root@centos1 ~]# mkdir -p /var/log/redis
[root@centos1 ~]# cp redis-5.0.4/src/redis-server /usr/local/redis/
[root@centos1 ~]# cp redis-5.0.4/src/redis-cli /usr/local/redis/
[root@centos1 ~]# ln -s /usr/local/redis/* /usr/local/bin/
******(5)启动两台redis
[root@centos1 ~]# redis-server /etc/redis/cluster/6379/redis.conf   #指定配置文件启动redis
[root@centos1 ~]# redis-server /etc/redis/cluster/6380/redis.conf 
[root@centos1 ~]# netstat -anpt | grep redis
tcp        0      0 192.168.100.202:6379    0.0.0.0:*               LISTEN      5231/redis-server 1 
tcp        0      0 192.168.100.202:6380    0.0.0.0:*               LISTEN      5236/redis-server 1 
tcp        0      0 192.168.100.202:16379   0.0.0.0:*               LISTEN      5231/redis-server 1 
tcp        0      0 192.168.100.202:16380   0.0.0.0:*               LISTEN      5236/redis-server 1 
[root@centos1 ~]# ps -ef | grep redis #查看进程,发现后面是cluster
root       5231      1  0 00:13 ?        00:00:04 redis-server 192.168.100.202:6379 [cluster]
root       5236      1  0 00:13 ?        00:00:04 redis-server 192.168.100.202:6380 [cluster]
root      19035   1062  0 02:19 pts/0    00:00:00 grep --color=auto redis
******(6)添加开机启动项
[root@centos1 ~]# echo "redis-server /etc/redis/cluster/6379/redis.conf" >> /etc/rc.local 
[root@centos1 ~]# echo "redis-server /etc/redis/cluster/6380/redis.conf" >> /etc/rc.local 
******(7)传输文件到另外两台服务器
[root@centos1 ~]# scp -r /etc/redis/ 192.168.100.203:/etc
root@192.168.100.203's password: 
redis.conf                                                                                             100%   61KB   2.5MB/s   00:00    
redis.conf                                                                                             100%   61KB  34.3MB/s   00:00    
[root@centos1 ~]# scp -r /etc/redis/ 192.168.100.204:/etc
root@192.168.100.204's password: 
redis.conf                                                                                             100%   61KB  33.3MB/s   00:00    
redis.conf                                                                                             100%   61KB  28.8MB/s   00:00    
[root@centos1 ~]# scp -r /usr/local/redis/ 192.168.100.203:/usr/local/
root@192.168.100.203's password: 
redis-server                                                                                           100% 7912KB  35.5MB/s   00:00    
redis-cli                                                                                                0%    0     0.0KB/s   --:-- ETA^redis-cli                                                                                              100% 4694KB  34.5MB/s   00:00    
[root@centos1 ~]# scp -r /usr/local/redis/ 192.168.100.204:/usr/local/
root@192.168.100.204's password: 
redis-server                                                                                           100% 7912KB  44.6MB/s   00:00    
redis-cli          


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
存储 缓存 NoSQL
Redis常见面试题(二):redis分布式锁、redisson、主从一致性、Redlock红锁;Redis集群、主从复制,哨兵模式,分片集群;Redis为什么这么快,I/O多路复用模型
redis分布式锁、redisson、可重入、主从一致性、WatchDog、Redlock红锁、zookeeper;Redis集群、主从复制,全量同步、增量同步;哨兵,分片集群,Redis为什么这么快,I/O多路复用模型——用户空间和内核空间、阻塞IO、非阻塞IO、IO多路复用,Redis网络模型
Redis常见面试题(二):redis分布式锁、redisson、主从一致性、Redlock红锁;Redis集群、主从复制,哨兵模式,分片集群;Redis为什么这么快,I/O多路复用模型
|
27天前
|
监控 NoSQL Redis
看完这篇就能弄懂Redis的集群的原理了
看完这篇就能弄懂Redis的集群的原理了
46 0
|
3月前
|
存储 运维 NoSQL
Redis Cluster集群模式部署
Redis Cluster集群模式部署
96 4
|
3月前
|
监控 NoSQL 算法
手把手教你如何搭建redis集群(二)
手把手教你如何搭建redis集群(二)
190 1
|
3月前
|
存储 NoSQL 容灾
手把手教你如何搭建redis集群(一)
手把手教你如何搭建redis集群(一)
142 1
|
2月前
|
存储 NoSQL 算法
Redis 集群模式搭建
Redis 集群模式搭建
64 5
|
2月前
|
存储 缓存 NoSQL
高并发架构设计三大利器:缓存、限流和降级问题之Redis用于搭建分布式缓存集群问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之Redis用于搭建分布式缓存集群问题如何解决
|
1月前
|
NoSQL Redis
Redis——单机迁移cluster集群如何快速迁移
Redis——单机迁移cluster集群如何快速迁移
36 0
|
2月前
|
缓存 NoSQL Java
Redis Spring配置集群
【7月更文挑战第5天】
62 10