前言
哈喽大家好,我是后端摸鱼工程师。最近面试被Redis集群虐了?搭集群的时候踩了无数坑,要么节点连不上,要么槽位分配失败,要么主节点挂了集群直接崩了?别慌!这篇文章我把Redis集群的核心灵魂拷问、底层原理、保姆级搭建步骤、高可用验证、避坑指南全给你扒得明明白白,看完不仅能搭出稳定的3主3从集群,面试再被问Redis集群,直接给面试官聊懵!
本文覆盖面试90%的Redis集群考点,建议先收藏再看,避免刷着刷着就找不到了~
@[TOC](文章目录)
一、Redis集群灵魂4连问,面试答不对直接凉凉
很多同学背了集群的搭建步骤,但是一被面试官问原理就卡壳,先把这4个核心问题搞懂,集群的底层逻辑就通了!
1. 为什么集群节点之间要疯狂ping-pong?
很多同学背答案:"为了投票找挂掉的节点",只说对了一半!
Redis集群里没有哨兵(Sentinel)来做节点监控,所有节点都是对等的平级节点,靠的是Gossip协议来传播集群状态。节点之间的ping-pong心跳,干的是这几件事:
-
交换各自的节点状态信息(谁在线、谁离线、主从角色、槽位分配)
-
检测节点的存活状态,为后续的故障判断、投票下线做准备
-
同步集群配置信息,保证所有节点的集群视图一致
说白了,ping-pong就是集群节点之间的"微信群聊",随时同步谁在线谁跑路了,不然整个集群就是一盘散沙~
2. 为什么要费尽心机找出挂掉的节点?
这里先纠正一个很多新手的误区:不是一个节点挂了集群就直接挂了!
那为什么要找挂掉的节点?因为Redis集群把所有数据分成了16384个哈希槽(Slot),每个主节点负责一部分槽位,所有的读写操作都必须在负责对应槽位的节点上执行。
如果一个主节点挂了,而且它没有从节点来接替它的工作,那它负责的槽位就没人管了,整个集群就会进入下线状态,无法处理任何读写请求。
所以找出挂掉的节点,核心目的是快速完成故障转移:把挂掉的主节点的从节点提拔成新主节点,接管对应的槽位,保证集群不宕机!
3. 为什么集群一个节点挂了不一定崩?为什么客户端连哪台节点都行?
这两个问题,核心都在16384个哈希槽上!
先讲槽位的核心逻辑:Redis集群会把16384个槽平均分配给所有主节点,比如3主节点,就是每个节点负责约5461个槽。
当你要存/取一个key的时候,Redis会执行这个公式:CRC16(key) % 16384,计算出这个key对应的槽位编号,然后找到负责这个槽位的节点,去执行操作。
那为什么客户端连哪台节点都行?
因为Redis集群的任意节点,都有完整的槽位分配映射表!你连任意一台节点,它都能告诉你这个key归哪个节点管,会给你返回重定向地址。而我们用redis-cli -c参数的时候,就是开启了自动重定向,客户端会自动帮你跳转到对应的节点执行命令,不用手动跳转,所以你感觉连哪台都一样~
那为什么一个节点挂了集群不一定崩?
如果我们给每个主节点都配了从节点(也就是副本),主节点挂了之后,集群会通过投票,把对应的从节点提拔成新的主节点,接管原来的槽位,整个集群的槽位还是完整的,所以集群能正常运行,这就是高可用!
4. Redis集群最少要搭几台?高可用集群要几台?
划重点!面试必问!
-
故障下线的投票规则:必须超过半数的主节点认为某个节点挂了,这个节点才会被判定为客观下线,才能触发故障转移。
-
所以如果只有1台主节点,挂了之后没有半数节点投票,无法完成故障转移,集群直接崩;
-
如果只有2台主节点,半数是1,超过半数需要2台,其中1台挂了,剩下1台达不到"超过半数"的要求,无法投票下线,也无法故障转移;
-
所以能完成故障投票的最小集群,是3台主节点!
而高可用集群,需要给每个主节点配从节点,避免主节点挂了集群崩,所以最小的高可用集群是3主3从,共6台节点,也就是我们接下来要搭建的集群模式!
二、3主3从Redis集群保姆级搭建步骤
这里我给大家分**新版Redis(5.0+,推荐)和老版Redis(3.x/4.x)**两种搭建方式,现在企业里基本都是5.0+了,老版的ruby方式大家了解就行,踩坑巨多!
先说明:本次搭建是在单台Linux服务器上模拟6个节点,端口分别是7001-7006,生产环境建议每台服务器一个节点,避免单机故障导致整个集群挂掉!
前置准备
首先你得在Linux上装好Redis,安装目录默认是/usr/local/redis,不会安装的同学可以先看基础安装教程,这里就不赘述了。
步骤1:清理残留的持久化文件,避免集群启动异常
很多同学搭集群失败,第一步就踩坑了!之前Redis单机模式生成的dump.rdb、appendonly.aof持久化文件,会导致集群节点启动时数据冲突,必须先删掉!
步骤2:修改原生Redis配置,开启集群支持
先修改原生的redis.conf配置文件,后续我们复制的节点都用这个配置为模板,避免每个节点都改一堆配置!
修改以下核心配置(划重点!这些配置不改,集群100%启动失败):
修改完保存退出。
步骤3:复制6个Redis节点目录
我们在/usr/local下创建redis-cluster目录,用来存放6个节点的文件,分别对应7001-7006端口:
步骤4:修改每个节点的端口配置
这里纠正新手最容易踩的坑!很多同学像新手笔记里一样,全改7001的配置文件,其他节点根本没改,肯定启动失败!
我们需要给每个节点修改对应的端口、集群配置文件名、pid文件:
嫌麻烦的同学,可以用sed命令批量替换,一行搞定,效率拉满!
步骤5:编写集群批量启动/停止脚本
一个个启动节点太麻烦了,我们写个一键启动和一键停止的脚本,摸鱼必备!
一键启动脚本[start-all.sh](start-all.sh)
脚本内容:
给脚本加执行权限,然后启动:
如果能看到6个端口的redis进程,就说明启动成功了!
一键停止脚本[stop-all.sh](stop-all.sh)
同理,写个停止脚本,不用一个个kill了:
脚本内容:
加权限执行即可。
步骤6:创建Redis集群(分新版&老版)
划重点!Redis 5.0之后,官方已经弃用了ruby的redis-trib.rb脚本,直接用redis-cli就可以创建集群,不用装一堆ruby依赖,踩坑少了90%!
方式一:新版Redis(5.0+,推荐)
直接用redis-cli的cluster命令创建集群,一行命令搞定!
这里的IP地址要改成你自己的服务器IP,别写[127.0.0.1](127.0.0.1)!
执行之后,会自动分配主从节点和槽位,输入yes确认,集群就创建完成了!
方式二:老版Redis(3.x/4.x,仅了解)
老版需要安装ruby环境,用redis-trib.rb脚本创建集群,也就是新手笔记里的方式,踩坑巨多,这里仅做了解:
步骤7:集群测试&高可用验证
集群创建好了,咱们来测试一下,看看是不是真的能用,高可用是不是真的生效!
1. 集群数据存取测试
我们用集群模式连接redis,-c参数就是开启集群自动重定向,必加!
不管你连7001-7006哪个节点,都能正常存取数据,自动重定向,完美!
2. 查看集群节点状态
执行之后,你能看到3个主节点(master),每个主节点对应1个从节点(slave),还有每个主节点负责的槽位范围。
3. 高可用故障转移测试
重头戏来了!咱们来模拟主节点挂掉,看看集群会不会自动完成故障转移!
你会发现,原来7001的从节点,已经被提拔成了新的主节点,接管了7001原来的槽位,集群还是正常运行的!这就是Redis集群的高可用!
三、Redis集群搭建常见踩坑避坑指南
我把自己搭集群踩过的坑全给大家列出来,避免大家重蹈覆辙:
-
防火墙/端口没开放:7001-7006业务端口,还有集群总线端口(端口+10000,比如17001-17006)都要开放,不然节点之间无法通信!
-
bind地址配置错误:别写[127.0.0.1](127.0.0.1),生产环境写服务器的内网IP,不然其他节点连不上!
-
持久化文件没清理:之前单机的rdb/aof文件会导致集群数据冲突,启动前必须删掉!
-
配置文件修改错误:每个节点的port、cluster-config-file、pidfile必须对应自己的端口,不能重复!
-
IP地址变化:创建集群的时候用的IP,后续不能变,不然集群会崩!
-
节点数量不对:--replicas 1的时候,节点数量必须是偶数,3主3从6个节点,不能少!
四、面试高频考点总结
-
Redis集群为什么用16384个槽?
-
Redis集群的Gossip协议原理?
-
Redis集群的故障转移完整流程是什么?
-
Redis集群和哨兵模式的区别?
-
Redis集群的读写分离怎么实现?
-
Redis集群的槽位迁移怎么做?
好了,以上就是Redis集群的全部内容了,从核心原理到保姆级搭建,再到避坑指南,全给大家讲透了!如果这篇文章对你有帮助,别忘了点赞、收藏、关注三连,后续会给大家更新更多Redis进阶内容,有任何问题都可以在评论区留言,我都会回复~
#Redis #Redis集群 #分布式缓存 #后端开发 #Java #面试