Redis

Redis 主从同步

当有多台 Redis 服务器的时候,就会有一台主服务器进行写操作,多台从服务器进行读操作;

一、Redis 介绍

Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。

与 memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了 master-slave(主从) 同步。

Redis 是一个高性能的 key-value 数据库。 redis 的出现,很大程度补偿了 memcached 这类 key/value 存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。

二、Redis 主从同步

Redis 主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得 Redis 可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布 记录。同步对读取操作的可扩展性和数据冗余很有帮助。

工作原理:

Redis 的主从结构可以采用一主多从或者级联结构,Redis 主从复制可以根据是否是全量分为全量同步和增量同步。

全量同步
  Redis 全量复制一般发生在 Slave 初始化阶段,这时 Slave 需要将 Master 上的所有数据都复制一份。具体步骤如下:

  1)从服务器连接主服务器,发送 SYNC 命令;

  2)主服务器接收到 SYNC 命名后,开始执行 BGSAVE 命令生成 RDB 文件并使用缓冲区记录此后执行的所有写命令;

  3)主服务器 BGSAVE 执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;

  4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;

  5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;

  6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

完成上面几个步骤后就完成了从服务器数据初始化的所有操作,从服务器此时可以接收来自用户的读请求。

增量同步
  Redis 增量复制是指 Slave 初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。

增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。

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

注意点
如果多个 Slave 断线了,需要重启的时候,因为只要 Slave 启动,就会发送 sync 请求和主机全量同步,当多个同时出现的时候,可能会导致 Master IO 剧增宕机。

实验环境:

server3:172.25.254.103 redis-slave

server4:172.25.254.104 redis-slave

server2:172.25.254.101 redis-master

1.redis 环境搭建
1)在所有实验主机上安装 Redis

先下载安装包 redis-4.0.8.tar.gz 并做以下操作

tar zxf redis-4.0.8.tar.gz ##解压安装包
cd redis-4.0.8
yum install gcc -y
make && make install ###安装
cd redis-4.0.8/utils/
./install_server.sh 执行这个脚本
2)编辑配置文件

vim /etc/redis/6379.conf
找到第 70 行的 bind 后面写 0.0.0.0
/etc/init.d/redis_6379 stop
/etc/init.d/redis_6379 start

2.配置 redis-slave
[root@server3 ~]# vim /etc/redis/6379.conf
slaveof 172.25.254.101 6379 # redis-master 的 ip

[root@server3 ~]# /etc/init.d/redis_6379 restart
Stopping …
Redis stopped
Starting Redis server…

[root@server4 ~]# vim /etc/redis/6379.conf
slaveof 172.25.254.101 6379

[root@server4 ~]# /etc/init.d/redis_6379 restart
Stopping …
Redis stopped
Starting Redis server…

如上操作所示,已经完成 redis 的主从复制
3.测试
在 master 端 server2:操作,在 slave 端 server3 查看
执行 redis-cli,登陆 若数据一致,则同步成功

1)在 master 端操作

2)在 selave 端查看

三、Redis Sentinel(哨兵)架构下的高可用

Redis 的主从复制下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,对于很多应用场景这种故障处理的方法是无法接受的。但是 Redis 从 2.8 开始正式提供了 Redis Sentinel(哨兵)架构来解决这个问题。

Redis Sentinel 是一个分布式架构,其中包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他 Sentinel 节点进行“协商”,当大多数 Sentinel 节点都认为主节点不可达时,它们会选举出一个 Sentinel 节点来完成自动故障转移的工作,同时会将这个变化通知给 Redis 应用方。整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了 Redis 的高可用问题。

实现原理:

三个定时监控任务
1)每隔 10 秒,每个 Sentinel 节点会向主节点和从节点发送 info 命令获取最新的拓扑结构。

2)每隔 2 秒,每个 Sentinel 节点会向 Redis 数据节点的sentinel:hello 频道上发送该 Sentinel 节点对于主节点的判断以及当前 Sentinel 节点的信息,同时每个 Sentinel 节点也会订阅该频道,来了解其他 Sentinel 节点以及它们对主节点的判断。

3)每隔一秒,每个 Sentinel 节点会向主节点、从节点、其余 Sentinel 节点发送一条 ping 命令做一次心跳检测,来确认这些节点当前是否可达。

主观下线
因为每隔一秒,每个 Sentinel 节点会向主节点、从节点、其余 Sentinel 节点发送一条 ping 命令做一次心跳检测,当这些节点超过 down-after-milliseconds 没有进行有效回复,Sentinel 节点就会对该节点做失败判定,这个行为叫做主观下线。

客观下线
当 Sentinel 主观下线的节点是主节点时,该 Sentinel 节点会向其他 Sentinel 节点询问对主节点的判断,当超过 个数,那么意味着大部分的 Sentinel 节点都对这个主节点的下线做了同意的判定,于是该 Sentinel 节点认为主节点确实有问题,这时该 Sentinel 节点会做出客观下线的决定。

领导者 Sentinel 节点选举
Raft 算法:假设 s1(sentinel-1) 最先完成客观下线,它会向其余 Sentinel 节点发送命令,请求成为领导者;收到命令的 Sentinel 节点如果没有同意过其他 Sentinel 节点的请求,那么就会同意 s1 的请求,否则拒绝;如果 s1 发现自己的票数已经大于等于某个值,那么它将成为领导者。

故障转移
1)领导者 Sentinel 节点在从节点列表中选出一个节点作为新的主节点

2)上一步的选取规则是与主节点复制相似度最高的从节点

3)领导者 Sentinel 节点让剩余的从节点成为新的主节点的从节点

4)Sentinel 节点集合会将原来的主节点更新为从节点,并保持着对其关注,当其恢复后命令它去复制新的主节点

1.实验环境 (首先搭建好 Redis 环境并可以进行主从同步)
系统版本:rhel6.5

server3:172.25.254.103 redis-slave

server4:172.25.254.104 redis-slave

server2:172.25.254.101 redis-master

2.主节点操作
1)在安装包中将 sentinel 文件复制到/etc/redis/下

[root@server2 ~]# cd redis-4.0.1
[root@server2 redis-4.0.1]# cp sentinel.conf /etc/redis/
[root@server2 redis-4.0.1]# cd /etc/redis/

2) 修改配置文件
[root@server2 redis]# vim sentinel.conf

关闭保护模式

第 98 行 Sentinel 去监视一个名为 mymaster 的主服务器, 这个主服务器的 IP 地址为 172.25.154.101,端口号为 6379 ,而将这个主服务器判断为失效至少需要 2 个 Sentinel 同意 (只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行)
如:

sentinel monitor mymaster 172.25.254.101 6379 2

3)将配置好的文件发送给所有从节点

[root@server2 redis]# scp sentinel.conf [email protected]:/etc/redis/
sentinel.conf 100% 7609 7.4KB/s 00:00
[root@server2 redis]# scp sentinel.conf [email protected]:/etc/redis/
sentinel.conf 100% 7609 7.4KB/s 00:00

4)三台 redis 开启 sentinel 服务

[root@server2 redis]# redis-sentinel /etc/redis/sentinel.conf

两台 slave
[root@server3 ~]# redis-sentinel /etc/redis/sentinel.conf

[root@server4 ~]# redis-sentinel /etc/redis/sentinel.conf

+slave 表示 :一个新的从服务器已经被 Sentinel 识别并关联 可以看到片此时 master 是 server2;server3 和 server4 是 slave。

3.测试
1) 停掉现在的 Redis-master info 查看 replication 信息

[root@server2 ~]# redis-cli -p 26379
127.0.0.1:26379> info
master0:name=mymaster,status=ok,address=172.25.254.101:6379,slaves=2,sentinels=3[root@server2 ~]# redis-cli
127.0.0.1:6379> SHUTDOWN
not connected>
[root@server2 ~]# redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>
[root@server2 ~]# redis-cli -p 26379
127.0.0.1:26379> info
master0:name=mymaster,status=ok,address=172.25.254.102:6379,slaves=2,sentinels=3
127.0.0.1:26379>

2) 查看任意一台 redis 主机的监控日志

[root@server4 ~]# redis-sentinel /etc/redis/sentinel.conf

+switch-master :配置变更,主服务器的 IP 和地址已经改变 由之前的 172.25.254.101 更改为 172.25.254.102。
+sdown :给定的实例 server2 现在处于主观下线状态。
在原先的 master 被停掉后,通过选举产生新的 master 172.25.254.102 6379

实际现在只有一个 slave 可以使用

四、Redis Cluster(集群)下的高可用

实现原理:

主观下线
集群中每个节点都会定期向其他节点发送 ping 消息,接受节点回复 ping 消息作为响应。如果在 cluster-node-timeout 时间内通信一直失败,则发送节点会认为接收节点存在故障,把接受节点标记为主观下线 (pfail) 状态。

客观下线
1) 当某个节点判断另一个节点主观下线后,相应的节点状态会跟随消息在集群内传播。

2) 假设节点 a 标记节点 b 为主观下线,一段时间后节点 a 通过消息把节点 b 的状态发送到其他节点,当其他节点收到消息并解析出消息体中含有 b 的 pfail 状态,把节点 b 加入下线报告链表;

3) 当某一节点 c 收到节点 b 的 pfail 状态时,此时有超过一半的槽主节点都标记了节点 b 为 pfail 状态时,则标记故障节点 b 为客观下线;

4) 向集群广播一条 pfail 消息,通知集群内的所有节点标记故障节点 b 为客观下线状态并立刻生效,同时通知故障节点 b 的从节点触发故障转移流程。

故障恢复
1) 资格检查

若从节点与主节点断线时间超过一定时间,则不具备资格
2) 准备选举时间

当从节点符合故障转移资格后,要等待一段选举时间后才开始选举

在故障节点的所有从节点中,复制偏移量最大的那个从节点最先开始(与主节点的数据最一致)进行选举,然后是次大的节点开始选举…..剩下其余的从节点等待到它们的选举时间到达后再进行选举
3) 发起选举
4) 选举投票

只有持有槽的主节点才具有一张唯一的选票,从从节点收集到 N/2 + 1 个持有槽的主节点投票时,从节点可以执行替换主节点操作
5) 替换主节点

当从节点收集到足够的选票之后,触发替换主节点操作

当前从节点取消复制变为主节点
撤销故障主节点负责的槽,并把这些槽委派给自己
向集群广播自己的 pong 消息,通知集群内所有的节点当前从节点变为主节点并接管了故障主节点的槽信息
1.实验环境:
使用任意一台 redis 主机

2.部署高可用
1)搭建环境

[root@server2 redis]# /etc/init.d/redis_6379 stop

cd /usr/local/ mkdir cluster ##建立集群目录

[root@server2 local]# cd cluster/
[root@server2 cluster]# pwd
/usr/local/cluster
[root@server2 cluster]# mkdir 700{1..6}
[root@server2 cluster]# ll
total 24
drwxr-xr-x 2 root root 4096 Oct 9 11:02 7001
drwxr-xr-x 2 root root 4096 Oct 9 11:02 7002
drwxr-xr-x 2 root root 4096 Oct 9 11:02 7003
drwxr-xr-x 2 root root 4096 Oct 9 11:02 7004
drwxr-xr-x 2 root root 4096 Oct 9 11:02 7005
drwxr-xr-x 2 root root 4096 Oct 9 11:02 7006
[root@server2 cluster]# cd 7001/

[root@server2 7001]# vim redis.conf
[root@server2 ~]# cat /usr/local/cluster/7001/redis.conf
port 7001
cluster-enabled yes #打开集群设备

cluster-config-file nodes.conf
cluster-node-timeout 5000 #延时时间
appendonly yes
daemonize yes

pidfile /usr/local/cluster/7001/redis.pid ##pid 文件存放目录

logfile /usr/local/cluster/7001/redis.log ##日志存放目录

[root@server2 7001]# redis-server redis.conf ###打开集群服务

[root@server2 cluster]# cp 7001/redis.conf 7002/
[root@server2 cluster]# cp 7001/redis.conf 7003/
[root@server2 cluster]# cp 7001/redis.conf 7004/
[root@server2 cluster]# cp 7001/redis.conf 7005/
[root@server2 cluster]# cp 7001/redis.conf 7006/

[root@server2 cluster]# cd 7002/

[root@server2 7002]# vim redis.conf ###将文件中的端口号改为 7002 和存放目录的更改

redis-server redis.conf ###打开集群的 redis

cd ..

cd 7003/ vim redis.conf ###将文件中的端口号改为 7003 和存放目录的更改

redis-server redis.conf ###打开集群的 redis

cd ..

cd 7004/ vim redis.conf ###将文件中的端口号改为 7004 和存放目录的更改

redis-server redis.conf ###打开集群的 redis

cd ..

cd 7005/

vim redis.conf ###将文件中的端口号改为 7005 和存放目录的更改

redis-server redis.conf ###打开集群的 redis

cd ..

cd 7006/ vim redis.conf ###将文件中的端口号改为 7006 和存放目录的更改

redis-server redis.conf ###打开集群的 redis
ps ax ##查看进程是否都打开了
netstat -antlp ##查看端口号是否开启

[root@server2 ~]# cd redis-4.0.1
[root@server2 redis-4.0.1]# cd src/
[root@server2 src]# cp redis-trib.rb /usr/local/bin/
[root@server2 src]# yum install -y ruby
[root@server2 ~]# yum install -y rubygems-1.3.7-5.el6.noarch.rpm

[root@server2 ~]# rpm -Uvh ruby-2.2.3-1.el6.x86_64.rpm
[root@server2 ~]# yum install -y ruby-2.2.3-1.el6.x86_64.rpm libyaml-0.1.3-4.el6_6.x86_64.rpm
[root@server2 ~]# gem install –local redis-4.0.1.gem

2)创建集群

[root@server2 ~]# redis-trib.rb create –replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006

[root@server2 ~]# redis-cli -c -p 7001
127.0.0.1:7001> set name linux
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002>

[root@server2 ~]# redis-cli -c -p 7006
127.0.0.1:7006> set name kb
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002> get name
“kb”
127.0.0.1:7002>

redis-cli -c -p 7001
登录,set name linux 写入内容,会提示写入内容传到 2 上
redis-cli -c -p 7002

输入 info,发现 2 是 master,他的 slave 是 6

3)测试

停掉 master 2

[root@server2 ~]# redis-cli -c -p 7002
127.0.0.1:7002> SHUTDOWN
not connected>

redis-trib.rb check 127.0.0.1:7001 ##查看集群的状态

可以查看之前的内容

[root@server2 ~]# redis-cli -c -p 7001
127.0.0.1:7001> get name
-> Redirected to slot [5798] located at 127.0.0.1:7005
“kb”
127.0.0.1:7005>

再关掉一个 master

[root@server2 ~]# redis-cli -c -p 7005
127.0.0.1:7005> SHUTDOWN
not connected>

查看信息

关闭掉两个 master 后,集群的功能会破坏

[root@server2 ~]# redis-cli -c -p 7001
127.0.0.1:7001> get name
(error) CLUSTERDOWN The cluster is down
127.0.0.1:7001>

4)恢复关闭的两个节点

[root@server2 ~]# cd /usr/local/cluster/
[root@server2 cluster]# ls
7001 7002 7003 7004 7005 7006
[root@server2 cluster]# cd 7002
[root@server2 7002]# redis-server redis.conf
1292:C 09 Oct 11:40:46.513 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1292:C 09 Oct 11:40:46.513 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1292, just started
1292:C 09 Oct 11:40:46.513 # Configuration loaded
[root@server2 7002]# cd ..
[root@server2 cluster]# cd 7005
[root@server2 7005]# redis-server redis.conf
1298:C 09 Oct 11:41:15.609 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1298:C 09 Oct 11:41:15.609 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1298, just started
1298:C 09 Oct 11:41:15.609 # Configuration loaded

高可用搭建成功

作者:白小黑..
来源:CSDN
原文:https://blog.csdn.net/weixin_42711549/article/details/83061052
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(Redis)