Redis集群之主从、哨兵、分片集群,SpringBoot整合Redis集群
在我看来主从模式和哨兵集群这都不能算是真正的集群,只有Redis分片集群模式才是真的集群。
可能看到这么说大家会很疑惑,那么请看下面相信你一定会有所获。
- Redis集群中文文档
- 之前一直担心搭建集群虚拟机内存不足,搭建完发现6个Redis只用了0.1G内存。(可能是Redis数据存储在内存中的,没数据的时候内存使用就很少)
文章目录
- 一、主从集群
- 二、哨兵集群
- 2-1、哨兵的作用
- 2-2、哨兵原理
- 三、分片集群
- 3-1、分片集群简单理解
- 3-2、分片集群深入理解
- 3-3、Redis集群图
- 3-4、其它补充
- 三、集群搭建
- 3-1、环境准备
- 3-2、配置文件修改
- 3-3、启动全部的redis
- 3-4、集群搭建
- 四、集群相关知识
- 4-1、Redis集群选举原理
- 4-2、新增节点、删除节点
- 4-3、集群的重启、重新创建
- 4-3-1、不改变原有集群
- 4-3-2、新建集群
- 五、使用Java来操作Redis集群
- 5-1、单节点整合Redis
- 5-2、集群整合
一、主从集群
相信有一点集群知识的人,一看到主从集群脑海里很快就浮现出了概念图,没错正如你所想的。
单机模式下,如果Redis宕机了,那服务就会不可用了。所以我们需要搭建主从集群。
- 主数据库可读可写
- 从数据库只能读(从数据库从主数据库同步数据)
但是主从模式存在一个问题就是当主服务断掉后,服务将只可读不可写
二、哨兵集群
哨兵其实和数据的存储没有关系,上面我们遗留了一个问题:主从模式下当主服务断掉后,服务将只可读不可写,哨兵则是来解决这个问题的。
哨兵的作用就是在主服务宕机后,在从服务里面选一个来做新的主服务。
2-1、哨兵的作用
- 监控:哨兵会不断的检查你的主服务器和从服务器是否运作正常
- 通知:当被监控的某个 Redis 服务器出现问题时, 哨兵可以通过API向管理员或者其他应用程序发送通知
- 故障迁移:当主服务器不能正常工作时,哨兵会自动进行故障迁移,也就是主从切换
- 统一的配置管理:连接者询问哨兵取得主从的地址
2-2、哨兵原理
哨兵使用的算法核心是 Raft 算法,主要用途就是用于分布式系统,系统容错,以及Leader选举,每个哨兵都需要定期的执行以下任务
- 每个 哨兵会自动发现其他 哨兵和从服务器,它以每秒钟一次的频率向它所知的主服务器、从服务器以及其他 哨兵实例发送一个 PING 命令。
- 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 那么这个实例会被 哨兵标记为主观下线。 有效回复可以是: +PONG 、 -LOADING 或者 -MASTERDOWN 。
- 如果一个主服务器被标记为主观下线, 那么正在监视这个主服务器的所有哨兵要以每秒一次的频率确认主服务器的确进入了主观下线状态。
- 如果一个主服务器被标记为主观下线, 并且有足够数量的哨兵(至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断, 那么这个主服务器被标记为客观下线。
- 在一般情况下, 每个哨兵会以每 10 秒一次的频率向它已知的所有主服务器和从服务器发送 INFO 命令。 当一个主服务器被哨兵标记为客观下线时,哨兵向下线主服务器的所有从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
- 当没有足够数量的哨兵同意主服务器已经下线, 主服务器的客观下线状态就会被移除。 当主服务器重新向哨兵的 PING 命令返回有效回复时, 主服务器的主管下线状态就会被移除。
三、分片集群
如果数据量很大,虽然我们可以考虑加大Redis的硬件,但仍不是一个好的解决办法,这时候我们就需要使用分片集群。
3-1、分片集群简单理解
我们把集群中的每一个节点当作是一个水桶,而我们的数据只存在其中一个水桶(不用管怎么存怎么取Redis已经做好了),这样当数据越来越多,我们只需要新增“水桶”就好了
因为集群中的每一个服务中的数据都是独一无二的,所以每一个服务需要一个备用服务,也就是主从模式(和上面的不一样哦)
3-2、分片集群深入理解
Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:
- 节点 A 包含 0 到 5500号哈希槽
- 节点 B 包含5501 到 11000 号哈希槽
- 节点 C 包含11001 到 16384号哈希槽
这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态
Redis 集群的主从复制模型
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N个复制品
在我们例子中具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用
然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了
不过当B和B1 都失败后,集群是不可用的
3-3、Redis集群图
需要说明的是,分片集群里面的主从是不需要依赖哨兵的,当其中一个主节点宕机也是可以由另外的从节点顶替上
3-4、其它补充
我们知道主从模式中,都是客户端插入数据到主节点,然后主节点去插入到其它的从节点。如果从节点过多就会导致主节点的性能下降(毕竟数据的复制是需要消耗的)
使用主-从-从的模式可以降低主节点的压力
三、集群搭建
主从模式、哨兵集群感觉没啥用,就不搭建了,这里直接搭建真·Redis集群
3-1、环境准备
集群里面有三份,然后按照主从模式搭建,也就是需要6台Redis。按照下面的文档按照6次即可
Linux下安装Redis,并修改默认端口和密码,设置后台启动【阿里云CentOS7.3】
3-2、配置文件修改
为了方便大家,我把redis.conf里面的注释全部删掉了,然后整理整理了一份简洁版的,需要修改的地方我全部加了注释,大家简单修改复制进去即可。
这只是为了方便大家搭建,正式环境不要这样做
#去掉bind绑定访问ip信息
bind 0.0.0.0
#关闭保护模式
protected-mode no
#修改对应的端口
port 5001
#启动集群模式
cluster-enabled yes
#集群节点信息文件,这里500x最好和port对应上
cluster-config-file nodes-5001.conf
#节点离线的超时时间
cluster-node-timeout 5000
#如果要设置密码需要增加如下配置:
#设置redis访问密码
requirepass xdx97
#设置集群节点间访问密码,跟上面一致
masterauth xdx97
# 修改启动进程号存储位置
pidfile /var/run/redis_5001.pid
#指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据
dir /usr/local/redis-cluster/redis-5001
#修改为后台启动
daemonize yes
#启动AOF文件
appendonly yes
tcp-backlog 511
timeout 0
tcp-keepalive 300
supervised no
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
3-3、启动全部的redis
打码的这一台是平时我自己使用的,不用在意
3-4、集群搭建
使用 redis-cli 创建整个 redis 集群(redis5.0版本之前使用的ruby脚本 redis-trib.rb)
- /usr/local/redis-cluster/redis-5001/redis-5.0.5/src/redis-cli 随便找一台服务使用它的redis-cli命令
- -a xdx97 我们之前设置的密码
- –cluster-replicas 1 主从搭配比例,1表示一主一从,2表示一主2从
特别说明一下,我下面使用的127.0.0.1只是一个展示,要使用可以被客户端访问到的ip
/usr/local/redis-cluster/redis-5001/redis-5.0.5/src/redis-cli -a xdx97 --cluster create --cluster-replicas 1 127.0.0.1:5001 127.0.0.1:5002 127.0.0.1:5003 127.0.0.1:5004 127.0.0.1:5005 127.0.0.1:5006
执行完后会出现下面的界面,输入yes回车即可,我们可以得到以下信息
- 每一个主服务的哈希槽是多少
- 谁是主谁是从,谁是谁的主,谁是谁的从
成功标识
可以通过命令查看Redis集群的相关命令
./redis-cli --cluster help
四、集群相关知识
4-1、Redis集群选举原理
从节点的选举和提升都是由从节点处理的,主节点会投票要提升哪个从节点。一个从节点的选举是在主节点被至少一个具有成为主节点必备条件的从节点标记为 FAIL 的状态的时候发生的。
当以下条件满足时,一个从节点可以发起选举:
- 该从节点的主节点处于 FAIL 状态
- 这个主节点负责的哈希槽数目不为零
- 从节点和主节点之间的重复连接(replication link)断线不超过一段给定的时间,这是为了确保从节点的数据是可靠的
- 一个从节点想要被推选出来,那么第一步应该是提高它的 currentEpoch 计数,并且向主节点们请求投票
从节点通过广播一个 FAILOVER_AUTH_REQUEST 数据包给集群里的每个主节点来请求选票。然后等待回复(最多等 NODE_TIMEOUT 这么长时间)。一旦一个主节点给这个从节点投票,会回复一个 FAILOVER_AUTH_ACK,并且在 NODE_TIMEOUT * 2 这段时间内不能再给同个主节点的其他从节点投票。在这段时间内它完全不能回复其他授权请求。
从节点会忽视所有带有的时期(epoch)参数比 currentEpoch 小的回应(ACKs),这样能避免把之前的投票的算为当前的合理投票。
一旦某个从节点收到了大多数主节点的回应,那么它就赢得了选举。否则,如果无法在 NODE_TIMEOUT 时间内访问到大多数主节点,那么当前选举会被中断并在 NODE_TIMEOUT * 4 这段时间后由另一个从节点尝试发起选举。
一旦有从节点赢得选举,它就会开始用 ping 和 pong 数据包向其他节点宣布自己已经是主节点,并提供它负责的哈希槽,设置 configEpoch 为 currentEpoch(选举开始时生成的)。
4-2、新增节点、删除节点
参考文档:http://www.redis.cn/topics/cluster-tutorial.html
4-3、集群的重启、重新创建
4-3-1、不改变原有集群
如果不改变原有集群,只是想重启一下,只需要把全部节点都关闭,然后再把全部节点打开即可。
4-3-2、新建集群
- 关闭之前的全部节点
- 删除nodes-500x.conf、dump.rdb、appendonly.aof文件 (如果是按照我上面的conf,则这几个文件在安装目录下面)
- 重启全部的服务
- 使用上面的命令重新创建集群
五、使用Java来操作Redis集群
下面的整合都是基于RedisTemplate
5-1、单节点整合Redis
https://blog.csdn.net/Tomwildboar/article/details/109923596
5-2、集群整合
其实只要搭建好上面的环境,整合集群是相当简单的,只需要把配置文件修改为如下即可:
spring.redis.cluster.nodes=127.0.0.1:5001,127.0.0.1:5002,127.0.0.1:5003,127.0.0.1:5004,127.0.0.1:5005,127.0.0.1:5006
spring.redis.password=xdx97
spring.redis.timeout=5000
spring.redis.cluster.max-redirects=3
还没有评论,来说两句吧...