redis 主从 哨兵 集群部署

介绍

Redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统。和Memcache类似,但很大程度补偿了Memcache的不足,它支持存储的value类型相对更多,包括string、list、set、zset和hash。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作。在此基础上,Redis支持各种不同方式的排序。

和Memcache一样,Redis数据都是缓存在计算机内存中,不同的是,Memcache只能将数据缓存到内存中,无法自动定期写入硬盘,这就表示,一断电或重启,内存清空,数据丢失。所以Memcache的应用场景适用于缓存无需持久化的数据。而Redis不同的是它会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,实现数据的持久化。

Redis有下面四种部署方式

模式优点缺点
单机版架构简单,部署方便机器故障、容量瓶颈、QPS瓶颈
主从复制高可靠性,读写分离故障恢复复杂,主库的写跟存受单机限制
Sentinel 哨兵集群部署简单,HA原理繁琐,slave存在资源浪费,不能解决读写分离问题
Redis Cluster数据动态存储solt,可扩展,高可用客户端动态感知后端变更,批量操作支持查

redis主从复制

该模式下 具有高可用性且读写分离, 会采用 增量同步 跟 全量同步 两种机制。

Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份

1、slave连接master,发送psync命令。
2、master接收到psync命名后,开始执行bgsave命令生成RDB文件并使用缓冲区记录此后执行的所有写命令。
3、master发送快照文件到slave,并在发送期间继续记录被执行的写命令。
4、slave收到快照文件后丢弃所有旧数据,载入收到的快照。
5、master快照发送完毕后开始向slave发送缓冲区中的写命令。
6、slave完成对快照的载入,开始接收命令请求,并执行来自master缓冲区的写命令。

增量同步也叫指令同步,。Redis会把指令存放在一个环形队列当中,因为内存容量有限,如果备机一直起不来,不可能把所有的内存都去存指令,也就是说,如果备机一直未同步,指令可能会被覆盖掉。

Redis增量复制是指Slave初始化后开始正常工作时master发生的写操作同步到slave的过程。增量复制的过程主要是master每执行一个写命令就会向slave发送相同的写命令。

1、主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

2、slave在同步master数据时候如果slave丢失连接不用怕,slave在重新连接之后丢失重补。

3、一般通过主从来实现读写分离,但是如果master挂掉后如何保证Redis的 HA呢?引入Sentinel进行master的选

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cXbCPzZK-1666513033881)(./image/Snipaste_2022-10-23_10-17-00_q4oLXdIAuH.png)]

安装环境

HostnameIP address
master10.196.110.72
slave110.196.110.121
slave210.196.110.81

1. 修改主机名

master节点

[root@localhost ~]# hostnamectl set-hostname master

slave1节点

[root@localhost ~]# hostnamectl set-hostname slave1

slave2节点

[root@localhost ~]# hostnamectl set-hostname slave2

2. 配置hosts主机解析

[root@master ~]# vi /etc/hosts
10.196.110.72 master
10.196.110.121 slave1 
10.196.110.81 slave2


#将hosts文件复制到从节点
[root@master ~]# scp /etc/hosts slave1:/etc/hosts
[root@master ~]# scp /etc/hosts slave2:/etc/hosts

3. 配置yum源

[root@master ~]# rm -f /etc/yum.repos.d/*  
[root@master ~]# vi /etc/yum.repos.d/local.repo
[redis]
name=redis
baseurl=https://mirrors.huaweicloud.com/redis/
gpgcheck=0
enabled=1

#将yum源复制到从节点
[root@master ~]# scp /etc/yum.repos.d/local.repo slave1:/etc/yum.repos.d/local.repo
[root@master ~]# scp /etc/yum.repos.d/local.repo slave2:/etc/yum.repos.d/local.repo

4. 安装redis

三个节点一起安装

[root@master ~]# yum install -y redis
[root@slave1 ~]# yum install -y redis
[root@slave2 ~]# yum install -y redis

5. 修改配置文件

master节点

[root@master ~]# vi /etc/redis.conf 

# 1. 修改绑定ip为服务器内网ip地址,做绑定,三台各自填写各自的ip地址
bind 0.0.0.0
# 2. 保护模式修改为否,允许远程连接
protected-mode no
# 4. 设定密码
requirepass "123456"
# 5. 设定主库密码与当前库密码同步,保证从库能够提升为主库
masterauth "123456"      

[root@master ~]# systemctl restart redis

slave1,slave2节点

[root@slave1 ~]# vi /etc/redis.conf 
bind 0.0.0.0        #修改监听所有网段
protected-mode no   #关闭保护模式
daemonize yes       #开启守护进程      
slaveof 10.196.110.72 6379   #配置主的ip和端口
requirepass "123456"
masterauth "123456"

[root@slave1 ~]# systemctl restart redis

6.测试

[root@master ~]# redis-cli 
127.0.0.1:6379> info Replication
# Replication
role:master
connected_slaves:2   #数量为2
slave0:ip=10.196.110.121,port=6379,state=online,offset=267,lag=1
slave1:ip=10.196.110.81,port=6379,state=online,offset=267,lag=0
master_repl_offset:267
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:266

请添加图片描述

redis哨兵模式

Redis-sentinel 本身是一个独立运行的进程,一般sentinel集群 节点数至少三个且奇数个,它能监控多个master-slave集群,sentinel节点发现master宕机后能进行自动切换。Sentinel可以监视任意多个主服务器以及主服务器属下的从服务器,并在被监视的主服务器下线时,自动执行故障转移操作。这里需注意sentinel也有single-point-of-failure问题。大致罗列下哨兵用途:

集群监控:循环监控master跟slave节点。
消息通知:当它发现有redis实例有故障的话,就会发送消息给管理员
故障转移:这里分为主观下线(单独一个哨兵发现master故障了)。客观下线(多个哨兵进行抉择发现达到quorum数时候开始进行切换)。
配置中心:如果发生了故障转移,它会通知将master的新地址写在配置中心告诉客户端。

存在的问题

就是会有脑裂的情况,就是当一台主节点的机子因为某些原因无法进行连接了,哨兵以为它挂了,就重新选举出一台新的机子作为主节点,但后续之前那台机子又恢复过来了,这样整个集群就有了两个主节点了,就好像大脑分裂了一样。

解决方案也很简单:就是将之前的主节点降级为从节点就行了

请添加图片描述

基于上面的实验继续完成

HostnameIP address
master,sentinel10.196.110.72
slave1,sentinel10.196.110.121
slave2,sentinel10.196.110.81

1.配置redis-sentinel文件

master,slave1,slave节点

[root@master ~]# vi /etc/redis-sentinel.conf 
#修改监听所有网段
bind 0.0.0.0
# 1. 保护模式修改为否,允许远程连接
protected-mode no

# 2. 设定监控地址,为对应的主redis库的内网地址
sentinel monitor mymaster 10.196.110.35 6379 2

# 3. 主数据库密码,需要将配置放在sentinel monitor master 127.0.0.1 6379 1下面
sentinel auth-pass mymaster 123456

[root@master ~]# systemctl restart redis-sentinel  

2. 测试

[root@node-1 ~]# redis-cli -a 123456 -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.196.110.72:6379,slaves=2,sentinels=3

redis-cluster集群

HostnameIP address
master110.196.110.72
master210.196.110.91
master310.196.110.74
slave110.196.110.102
slave210.196.110.81
slave310.196.110.121

1.关闭防火墙

2.配置yum源

3.配置redis.conf 配置文件

全部节点配置一致

[root@master ~]# vi /etc/redis.conf 
port 6379        
daemonize yes    //开启守护进程
protected-mode no
requirepass "123456"           //设置密码
masterauth lafenfen            //如果requirepass设置了,masterauth也必须要保持一样,否则无法同步。

cluster-enabled yes    //开启集群模式 
cluster-config-file nodes-6379.conf    //每台机器的集群配置文件,不需要人工修改,程序自动记录,这块名字可以根据端口号进行设置。
cluster-node-timeout 15000  //单位是毫秒,如果在15秒还没有响应,结点会被认为出了故障。
[root@master ~]# systemctl restart redis

4. 加入集群

[root@node-1 ~]# redis-cli -a "123456"                             
127.0.0.1:6379> cluster meet 10.196.110.102 6379
OK
127.0.0.1:6379> cluster meet 10.196.110.91 6379
OK
127.0.0.1:6379> cluster meet 10.196.110.74 6379
OK
127.0.0.1:6379> cluster meet 10.196.110.121 6379
OK
127.0.0.1:6379> cluster meet 10.196.110.81 6379
OK

127.0.0.1:6379> cluster nodes
eb1db940c71aadfeeca530812eb39c63fe577986 10.196.110.91:6379 master - 0 1666511773894 0 connected
d880ff25f5d5c905b37844eff665511faa986dc2 10.196.110.74:6379 master - 0 1666511767872 3 connected
4b12dd385ebfdff5852eec7c871e6e88c440e3f9 10.196.110.81:6379 master - 0 1666511772890 5 connected
017dc81cb683491a4ae6ac349b4523e8b2e96a55 10.196.110.102:6379 master - 0 1666511770884 1 connected
5af65b0b9ff6b7e02ac1cabdf3c8efbb0287e3e7 10.196.110.121:6379 master - 0 1666511771887 4 connected
eabb57e8922da890f32c1d727a5e01d6b8c3e72f 10.196.110.72:6379 myself,master - 0 0 2 connected
127.0.0.1:6379> 

可以采用联想法在大脑里记忆,集群节点开大会。 meet就是会议的意思。

每个节点被添加后,都会随机产生一个角色(master或slave)

通过cluser nodes命令查看各节点的身份信息,6个节点都是master 这个角色。
请添加图片描述

5. 分配插槽

关于插槽的概念是这样的。
在Redis Cluster 将把所有的数据映射到16384个槽中。我们使用redis时,创建的每个key会映射到一个固
定的插槽,只有当节点分配了槽,才能响应和这些槽关联的键命令。通过
cluster addslots命令为指定的master主节点分配插槽。

命令:CLUSTER ADDSLOTS slot [slot ...]

[root@master ~]# redis-cli -h 127.0.0.1 -p 6379 -a 123456 cluster addslots {0..5461}        
OK
[root@master ~]# redis-cli -h 10.196.110.91 -p 6379 -a 123456 cluster addslots {5462..10922}
OK
[root@master ~]# redis-cli -h 10.196.110.74 -p 6379 -a 123456 cluster addslots {10923..16383}
OK


[root@node-1 ~]# redis-cli -a "123456"
127.0.0.1:6379> cluster slots
1) 1) (integer) 5462
   2) (integer) 10922
   3) 1) "10.196.110.91"
      2) (integer) 6379
      3) "eb1db940c71aadfeeca530812eb39c63fe577986"
2) 1) (integer) 10923
   2) (integer) 16383
   3) 1) "10.196.110.74"
      2) (integer) 6379
      3) "d880ff25f5d5c905b37844eff665511faa986dc2"
3) 1) (integer) 0
   2) (integer) 5461
   3) 1) "10.196.110.72"
      2) (integer) 6379
      3) "eabb57e8922da890f32c1d727a5e01d6b8c3e72f"

6. 修改节点角色

登陆指定节点服务器,然后运行上面的命令,其中的node_id 就是指定主节点的运行ID

在我的规划里 3主3从的对应结点关系如下

masterslave
10.196.110.7210.196.110.102
10.196.110.9110.196.110.81
10.196.110.7410.196.110.121

现在10.196.110.72 的集群运行id 为 b5a9577be8bf4aadcdaaa41aef41c8e311fa8b15

可以通过上面来查看

登陆10.196.110.102服务器上的redis

[root@slave1 ~]# redis-cli -a "123456"
127.0.0.1:6379> CLUSTER REPLICATE eb1db940c71aadfeeca530812eb39c63fe577986
OK

别的服务器也这样操作

最后各结点的对应关系如下:

请添加图片描述

Cluster 故障恢复

当某个master节点出现故障时,对应的slave节点会成为新的master节点。如果有多个slave节点时,会通过选举,选出一个做为新的master节点。

但是一个至少负责一个插槽的主数据库下线且没有相应的从数据库可以进行故障恢复时,整个集群会进入下线状态无法继续工作。

需要将下面的配置,改成no 就不会出现这种情况了。

cluster-require-full-coverage no

集群配置项


(1) cluster-enabled yes     开启集群运行模式

(2) cluster-config-file nodes-6379.conf    集群配置文件
这里记录的内容和执行 cluster nodes 命令看到的是一样的。
这个文件程序自动添加和更新,不需要人工处理。

dd42566f143bdf4731fbaa22fb1160634b310a7a 192.168.100.5:6380@16380 master - 0 1623805285501 0 connected 5462-10922

第1列:结点的运行ID,它是集群中的唯一标识。
第2列:IP和端口号
第3列:角色 master 或者slave
最后一列:是分配的插槽起始和结束范围。

(3)cluster-node-timeout 15000

单位:毫秒

集群中的各结点,会对其它结点进行ping操作,
当超出 cluster-node-timeout  选项的时间,还没有反应,就疑似这个结点出了故障。

(4)cluster-replica-validity-factor 10

(5)cluster-migration-barrier 1

(6)cluster-require-full-coverage yes
说明:
当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群下线,状态不可用。 
可以设置为no,将忽略这个影响。

这块有相关技术人员做了试验,可以看下链接:
https://www.qedev.com/bigdata/866.html

(7)cluster-replica-no-failover no


集群操作命令整理

集群
cluster info :打印集群的信息
cluster nodes :列出集群当前已知的所有节点( node),以及这些节点的相关信息。
节点
cluster meet <ip> <port> :将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
cluster forget <node_id> :从集群中移除 node_id 指定的节点。
cluster replicate <master_node_id> :将当前从节点设置为 node_id 指定的master节点的slave节点。只能针对slave节点操作。
cluster saveconfig :将节点的配置文件保存到硬盘里面。
槽(slot)
cluster addslots <slot> [slot ...] :将一个或多个槽( slot)指派( assign)给当前节点。
cluster delslots <slot> [slot ...] :移除一个或多个槽对当前节点的指派。
cluster flushslots :移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
cluster setslot <slot> node <node_id> :将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给
另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
cluster setslot <slot> migrating <node_id> :将本节点的槽 slot 迁移到 node_id 指定的节点中。
cluster setslot <slot> importing <node_id> :从 node_id 指定的节点中导入槽 slot 到本节点。
cluster setslot <slot> stable :取消对槽 slot 的导入( import)或者迁移( migrate)。
键
cluster keyslot <key> :计算键 key 应该被放置在哪个槽上。
cluster countkeysinslot <slot> :返回槽 slot 目前包含的键值对数量。
cluster getkeysinslot <slot> <count> :返回 count 个 slot 槽中的键 。


  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值