Redis集群全网最全详解,看完可以出去吹牛了

Redis集群详解

Redis有三种集群模式,分别是:

*主从模式*Sentinel模式*Cluster模式
主从模式

主从模式介绍

主从模式是三种模式中最简单的,在主从复制中,数据库分为两类:主数据库(master)和从数据库(slave)。

其中主从复制有如下特点:

*主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库*从数据库一般都是只读的,并且接收主数据库同步过来的数据*一个master可以拥有多个slave,但是一个slave只能对应一个master*slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来*master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务*master挂了以后,不会在slave节点中重新选一个master

工作机制:

当slave启动后,主动向master发送SYNC命令。master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令。

复制初始化后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。

安全设置:

当master节点设置密码后,

客户端访问master需要密码启动slave需要密码,在配置文件中配置即可客户端访问slave不需要密码

缺点:

从上面可以看出,master节点在主从模式中唯一,若master挂掉,则redis无法对外提供写服务。

主从模式搭建

环境准备:

master节点192.168.30.128slave节点192.168.30.129slave节点192.168.30.130

全部下载安装:

wget;//usr/local/redisecho$?0

全部配置成服务:

服务文件

vim/usr/libexec/redis-shutdownRetrieveservicenameSERVICE_NAME="$1"if[-z"$SERVICE_NAME"];thenSERVICE_NAME=redisfiUseawktoretrievehost,portfromconfigfileHOST=`awk'/^[[:blank:]]*bind/{print$2}'$CONFIG_FILE|tail-n1`PORT=`awk'/^[[:blank:]]*port/{print$2}'$CONFIG_FILE|tail-n1`PASS=`awk'/^[[:blank:]]*requirepass/{print$2}'$CONFIG_FILE|tail-n1`SOCK=`awk'/^[[:blank:]]*unixsocket\s/{print$2}'$CONFIG_FILE|tail-n1`Setupadditionalparametersshutdowntheserviceproperlyif[-e"$SOCK"];then$REDIS_CLI-s$SOCK$ADDITIONAL_PARAMSshutdownelse$REDIS_CLI-h$HOST-p$PORT$ADDITIONAL_PARAMSshutdownfi
useradd-s/sbin/nologinredischown-Rredis:redis/data/redis命令补全systemctlenableredis

修改配置:

192.168.30.128

vim/usr/local/redis/允许后台启动logfile"/usr/local/redis/"数据库备份文件存放目录masterauth123456设置master连接密码,slave可省略apponlyyesecho'_memory=1'/etc//data/redisecho'_memory=1'/etc//data/redisecho'_memory=1'/etc/

查看集群状态:

Replicationrole:masterconnected_slaves:2slave0:ip=192.168.30.129,port=6379,state=online,offset=168,lag=1slave1:ip=192.168.30.130,port=6379,state=online,offset=168,lag=1master_replid:fb4941e02d5032ad74c6e2383211fc58963dbe90master_replid2:0000000000000000000000000000000000000000master_repl_offset:168second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:168
Replicationrole:slavemaster_host:192.168.30.128master_port:6379master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:196slave_priority:100slave_read_only:1connected_slaves:0master_replid:fb4941e02d5032ad74c6e2383211fc58963dbe90master_replid2:0000000000000000000000000000000000000000master_repl_offset:196second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:196

数据演示:

192.168.30.128:6379keys*(emptylistorset)192.168.30.128:6379:6379:6379keys*1)"key1"2)"key2"
:Usingapasswordwith'-a'or'-u':6379keys*1)"key2"2)"key1"192.168.30.130:6379CONFIGGETdir1)"dir"2)"/data/redis"192.168.30.130:6379CONFIGGETdbfilename1)"dbfilename"2)""192.168.30.130:6379getkey1"100"192.168.30.130:6379getkey2"lzx"192.168.30.130:6379setkey3aaa(error)READONLYYoucan'twriteagainstareadonlyreplica.

可以看到,在master节点写入的数据,很快就同步到slave节点上,而且在slave节点上无法写入数据。

Sentinel模式

Sentinel模式介绍

主从模式的弊端就是不具备高可用性,当master挂掉以后,Redis将不能再对外提供写入操作,因此sentinel应运而生。

sentinel中文含义为哨兵,顾名思义,它的作用就是监控redis集群的运行状况,特点如下:

*sentinel模式是建立在主从模式的基础上,如果只有一个Redis节点,sentinel就没有任何意义*当master挂了以后,sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master*当master重新启动后,它将不再是master而是做为slave接收新的master的同步数据*sentinel因为也是一个进程有挂掉的可能,所以sentinel也会启动多个形成一个sentinel集群*多sentinel配置的时候,sentinel之间也会自动监控*当主从模式配置密码时,sentinel也会同步将配置信息修改到配置文件中,不需要担心*一个sentinel或sentinel集群可以管理多个主从Redis,多个sentinel也可以监控同一个redis*sentinel最好不要和Redis部署在同一台机器,不然Redis的服务器挂了以后,sentinel也挂了

工作机制:

*每个sentinel以每秒钟一次的频率向它所知的master,slave以及其他sentinel实例发送一个PING命令*如果一个实例距离最后一次有效回复PING命令的时间超过down-after-milliseconds选项所指定的值,则这个实例会被sentinel标记为主观下线。*如果一个master被标记为主观下线,则正在监视这个master的所有sentinel要以每秒一次的频率确认master的确进入了主观下线状态*当有足够数量的sentinel(大于等于配置文件指定的值)在指定的时间范围内确认master的确进入了主观下线状态,则master会被标记为客观下线*在一般情况下,每个sentinel会以每10秒一次的频率向它已知的所有master,slave发送INFO命令*当master被sentinel标记为客观下线时,sentinel向下线的master的所有slave发送INFO命令的频率会从10秒一次改为1秒一次*若没有足够数量的sentinel同意master已经下线,master的客观下线状态就会被移除;若master重新向sentinel的PING命令返回有效回复,master的主观下线状态就会被移除

当使用sentinel模式的时候,客户端就不要直接连接Redis,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。

Sentinel模式搭建

环境准备:

master节点192.168.30.128sentinel端口:26379slave节点192.168.30.129sentinel端口:26379slave节点192.168.30.130sentinel端口:26379

修改配置:

前面已经下载安装了redis,这里省略,直接修改sentinel配置文件。

192.168.30.128

sentinel工作目录判断master主观下线时间,默认30s

这里需要注意,sentinelauth-passmymaster123456需要配置在下面,否则启动报错:

mkdir/usr/local/redis/sentinelchown-Rredis:redis/usr/local/redistail-f/usr/local/redis/:X09May201915:32:04.298+:X09May201915:32:04.299*+:6379192.168.30.1296379@:X09May201915:32:04.300*+:6379192.168.30.1306379@:X09May201915:32:16.347*+@:X09May201915:32:31.584*+@

Sentinel模式下的几个事件:

·+reset-master:主服务器已被重置。·+slave:一个新的从服务器已经被Sentinel识别并关联。·+failover-state-reconf-slaves:故障转移状态切换到了reconf-slaves状态。·+failover-detected:另一个Sentinel开始了一次故障转移操作,或者一个从服务器转换成了主服务器。·+slave-reconf-sent:领头(leader)的Sentinel向实例发送了[SLAVEOF](/commands/)命令,为实例设置新的主服务器。·+slave-reconf-inprog:实例正在将自己设置为指定主服务器的从服务器,但相应的同步过程仍未完成。·+slave-reconf-done:从服务器已经成功完成对新主服务器的同步。·-dup-sentinel:对给定主服务器进行监视的一个或多个Sentinel已经因为重复出现而被移除——当Sentinel实例重启的时候,就会出现这种情况。·+sentinel:一个监视给定主服务器的新Sentinel已经被识别并添加。·+sdown:给定的实例现在处于主观下线状态。·-sdown:给定的实例已经不再处于主观下线状态。·+odown:给定的实例现在处于客观下线状态。·-odown:给定的实例已经不再处于客观下线状态。·+new-epoch:当前的纪元(epoch)已经被更新。·+try-failover:一个新的故障迁移操作正在执行中,等待被大多数Sentinel选中(waitingtobeelectedbythemajority)。·+elected-leader:赢得指定纪元的选举,可以进行故障迁移操作了。·+failover-state-select-slave:故障转移操作现在处于select-slave状态——Sentinel正在寻找可以升级为主服务器的从服务器。·no-good-slave:Sentinel操作未能找到适合进行升级的从服务器。Sentinel会在一段时间之后再次尝试寻找合适的从服务器来进行升级,又或者直接放弃执行故障转移操作。·selected-slave:Sentinel顺利找到适合进行升级的从服务器。·failover-state-s-slaveof-noone:Sentinel正在将指定的从服务器升级为主服务器,等待升级功能完成。·failover--for-timeout:故障转移因为超时而中止,不过最终所有从服务器都会开始复制新的主服务器(slaveswilleventuallybeconfiguredtoreplicatewiththenewmasteranyway)。·failover-:故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了。·+switch-master:配置变更,主服务器的IP和地址已经改变。这是绝大多数外部用户都关心的信息。·+tilt:进入tilt模式。·-tilt:退出tilt模式。

master宕机演示:

192.168.30.128

tail-f/usr/local/redis/:X09May201915:51:29.287++new-epoch122428:X09May201915:51:29.371+vote-for-leader30c417116a8edbab09708037366c4a7471beb770122428:X09May201915:51:29.40379b8d61626afd4d059fb5a6a63393e9a1374e78fvotedfor30c417116a8edbab09708037366c4a7471beb770122428:X09May201915:51:29.451+:X09May201915:51:29.528+:6379192.168.30.1296379@:X09May201915:51:30.190-:X09May201915:51:31.233*+:6379192.168.30.1306379@:X09May201915:51:31.233*+:6379192.168.30.1306379@:X09May201915:51:31.297+:X09May201915:51:31.298*+:6379192.168.30.1306379@:X09May201915:51:31.298*+:6379192.168.30.1286379@:X09May201915:52:31.307/usr/local/bin/:Usingapasswordwith'-a'or'-u':6379inforeplicationsystemctlstartredis+:X09May201915:51:31.298*+:6379192.168.30.1306379@:X09May201915:51:31.298*+:6379192.168.30.1286379@:X09May201915:52:31.307-:6379192.168.30.1286379@

查看集群信息

Replicationrole:slavemaster_host:192.168.30.129master_port:6379master_link_status:upmaster_last_io_seconds_ago:0master_sync_in_progress:0slave_repl_offset:514774slave_priority:100slave_read_only:1connected_slaves:0master_replid:757aff269236ed2707ba584a86a40716c1c76d74master_replid2:0000000000000000000000000000000000000000master_repl_offset:514774second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:376528repl_backlog_histlen:138247192.168.30.128:6379getkey4"linux"192.168.30.128:6379setkey5(error)ERRwrongnumberofargumentsfor'set'command

即使192.168.30.128重新启动redis服务,也是作为slave加入redis集群,192.168.30.129仍然是master。

Cluster模式

Cluster模式介绍

sentinel模式基本可以满足一般生产的需求,具备高可用性。但是当数据量过大到一台服务器存放不下的情况时,主从模式或sentinel模式就不能满足需求了,这个时候需要对存储的数据进行分片,将数据存储到多个Redis实例中。cluster模式的出现就是为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。

cluster可以说是sentinel和主从模式的结合体,通过cluster可以实现主从和master重选功能,所以如果配置两个副本三个分片的话,就需要六个Redis实例。因为Redis的数据是根据一定规则分配到cluster的不同机器的,当数据量过大时,可以新增机器进行扩容。

使用集群,只需要将redis配置文件中的cluster-enable配置打开即可。每个集群中至少需要三个主数据库才能正常运行,新增节点非常方便。

cluster集群特点:

*多个redis节点网络互联,数据共享*所有的节点都是一主一从(也可以是一主多从),其中从不提供服务,仅作为备用*不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上,并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为*支持在线增加、删除节点*客户端可以连接任何一个主节点进行读写
Cluster模式搭建

环境准备:

三台机器,分别开启两个redis服务(端口)192.168.30.128端口:7001,7002192.168.30.129端口:7003,7004192.168.30.130端口:7005,7006

修改配置文件:

192.168.30.128

cp/usr/local/redis//usr/local/redis/cluster/redis_7001.confchown-Rredis:redis/usr/local/redisvim/usr/local/redis/cluster/redis_7001."/var/run/redis_7001.pid"logfile"/usr/local/redis/cluster/redis_7001.log"dir"/data/redis/cluster/redis_7001"vim/usr/local/redis/cluster/redis_7002."/var/run/redis_7002.pid"logfile"/usr/local/redis/cluster/redis_7002.log"dir"/data/redis/cluster/redis_7002"redis-server/usr/local/redis/cluster/redis_7001.confredis-server/usr/local/redis/cluster/redis_7002.confyum-ygroupinstall"DevelopmentTools"mkdir-p~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}cp/usr/local/redis/src//usr/bin/:7001192.168.30.128:7002192.168.30.129:7003192.168.30.129:7004192.168.30.130:7005192.168.30.130:7006--cluster-replicas1Warning:Usingapasswordwith'-a'or'-u'[0]-Slots0-5460Master[1]-Slots5461-10922Master[2]-:7004:7001:7006:7003:7002:7005M:80:7001slots:[0-5460](5461slots)masterS::7002replicates6788453ee9a8d7f72b1d45a9093838efd0e501f1M:4:7003slots:[5461-10922](5462slots)masterS::7004replicates80c80a3f3e33872c047a8328ad579b9bea001ad8M:6788453:7005slots:[10923-16383](5461slots)masterS:277:7006replicates4d74ec66e898bf09006dac86d4928f9fad81f373CanIsettheaboveconfiguration?(type'yes'toaccept):yesls/data/redis/cluster/redis_7001/集群状态cluster_state:okcluster_slots_assigned:16384cluster_slots_ok:16384cluster_slots_pfail:0cluster_slots_fail:0cluster_known_nodes:6cluster_size:3cluster_current_epoch:6cluster_my_epoch:1cluster_stats_messages_ping_sent:580cluster_stats_messages_pong_sent:551cluster_stats_messages_sent:1131cluster_stats_messages_ping_received:546cluster_stats_messages_pong_received:580cluster_stats_messages_meet_received:5cluster_stats_messages_received:1131

列出节点信息:

192.168.30.128:7001CLUSTERNODES说明数据到了192.168.30.130:7005上:7005setkey222bbb-Redirectedtoslot[2320]:7001说明数据到了192.168.30.129:7003上:7003getkey111-Redirectedtoslot[13680]:7005"aaa"192.168.30.130:7005getkey333-Redirectedtoslot[7472]:7003"ccc"192.168.30.129:7003

可以看出rediscluster集群是去中心化的,每个节点都是平等的,连接哪个节点都可以获取和设置数据。

当然,平等指的是master节点,因为slave节点根本不提供服务,只是作为对应master节点的一个备份。

增加节点:

192.168.30.129上增加一节点:

vim/usr/local/redis/cluster/redis_7007."/var/run/redis_7007.pid"logfile"/usr/local/redis/cluster/redis_7007.log"dir"/data/redis/cluster/redis_7007"mkdir/data/redis/cluster/redis_7007redis-server/usr/local/redis/cluster/redis_7007.conf

192.168.30.130上增加一节点:192.168.30.130上增加一节点:

vim/usr/local/redis/cluster/redis_7007."/var/run/redis_7008.pid"logfile"/usr/local/redis/cluster/redis_7008.log"dir"/data/redis/cluster/redis_7008"mkdir/data/redis/cluster/redis_7008redis-server/usr/local/redis/cluster/redis_7008.conf

集群中增加节点:

192.168.30.129:7003:7003:7003@17003myself,master-0003:7001@17001master-0461:7006@17006slave4d74ec66e898bf09006dac86d4928f9fa:7004@17004slave80c80a3f3e33872c047a8328ad579b9be:7002@17002slave6788453ee9a8d7f72b1d45a9093838efd0:7007@17007:7005@17005master-0395connected10923-16383
192.168.30.129:7003:7003:7003@17003myself,master-0003:7001@17001master-0001:7006@17006slave4d74ec66e898bf09006dac86d4928f9fa:7004@17004slave80c80a3f3e33872c047a8328ad579b9be:7002@17002slave6788453ee9a8d7f72b1d45a9093838efd0:7008@17008:7007@17007:7005@17005master-0755connected10923-16383

可以看到,新增的节点都是以master身份加入集群的

更换节点身份:

将新增的192.168.30.130:7008节点身份改为192.168.30.129:7007的slave

:7008:7008:7006@17006slave4d74ec66e898bf09006dac86d4928f9fa:7001@17001master-0641:7003@17003master-0003:7005@17005master-0725:7002@17002slave6788453ee9a8d7f72b1d45a9093838efd0:7008@17008myself,slavee51ab166bc0f33026887bcf8eba0dff3d5:7004@17004slave80c80a3f3e33872c047a8328ad579b9be:7007@17007master-0000connected

查看相应的文件,可以发现有更改,它记录当前集群的节点信息

无法删除登录节点192.168.30.130:7008CLUSTERFORGETe51ab166bc0f33026887bcf8eba0dff3d5b0bf14(error)ERRCan'tforgetmymaster!可以删除其它的master节点192.168.30.130:7008:7006@17006slave4d74ec66e898bf09006dac86d4928f9fa:7001@17001master-0001:7003@17003master-0003:7002@17002:7008@17008myself,slavee51ab166bc0f33026887bcf8eba0dff3d5:7004@17004slave80c80a3f3e33872c047a8328ad579b9be:7007@17007:7008CLUSTERFORGETb4d3eb411a7355d4767c6c23b4df69fa183ef8bcOK将节点配置信息保存到硬盘:Usingapasswordwith'-a'or'-u':7008:7006@17006slave4d74ec66e898bf09006dac86d4928f9fa:7001@17001master-0001:7003@17003master-0003:7005@17005master-0005:7002@17002slave6788453ee9a8d7f72b1d45a9093838efd0:7008@17008myself,slavee51ab166bc0f33026887bcf8eba0dff3d5:7004@17004slave80c80a3f3e33872c047a8328ad579b9be:7007@17007master-0000connected

可以看到,之前删除的节点又恢复了,这是因为对应的配置文件没有删除,执行CLUSTERSAVECONFIG恢复。

模拟master节点挂掉:

192.168.30.128

kill6701
192.168.30.130:7008:7006@17006slave4d74ec66e898bf09006dac86d4928f9fa:7001@17001master,fa:7003@17003master-0223:7005@17005master-0035:7002@17002slave6788453ee9a8d7f72b1d45a9093838efd0:7008@17008myself,slavee51ab166bc0f33026887bcf8eba0dff3d5:7004@17004master-0818:7007@17007master-0000connected

对应7001的一行可以看到,masterfail,状态为disconnected;而对应7004的一行,slave已经变成master。

重新启动7001节点:

#redis-server/usr/local/redis/cluster/redis_7001.:7008:7006@17006slave4d74ec66e898bf09006dac86d4928f9fa:7001@17001slaveb6331cbc986794237c83ed2d5c30777c1551546:7003@17003master-0623:7005@17005master-0355:7002@17002slave6788453ee9a8d7f72b1d45a9093838efd0:7008@17008myself,slavee51ab166bc0f33026887bcf8eba0dff3d5:7004@17004master-0728:7007@17007master-0000connected

可以看到,7001节点启动后为slave节点,并且是7004的slave节点。即master节点如果挂掉,它的slave节点变为新master节点继续对外提供服务,而原来的master节点如果重启,则变为新master节点的slave节点。

另外,如果这里是拿7007节点做测试的话,会发现7008节点并不会切换,这是因为7007节点上根本没数据。集群数据被分为三份,采用哈希槽(hashslot)的方式来分配16384个slot的话,它们三个节点分别承担的slot区间是:

节点7004覆盖0-5460节点7003覆盖5461-10922节点7005覆盖10923-16383
发布于 2025-07-02
40
目录

    推荐阅读