Redis学习 - 复制以及三种部署模式(上)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis学习 - 复制以及三种部署模式(上)

什么是复制



单机的redis通常情况是无法满足项目需求的,一般都建议使用集群部署的方式进行数据的多机备份和部署,这样既可以保证数据安全,同时在redis宕机的时候,复制也可以对于数据进行快速的修复。


采取的方式



  1. 单机部署(忽略)
  2. 主从链
  3. 一主多从
  4. 哨兵模式
  5. 集群模式


复制的前提



  1. 需要保证redis.conf里面的配置是正确的,比如:


dir ./
dbfilename "dump.rdb"
复制代码


  1. 需要保证指定的路径对于redis来说是可写的,意味着如果当前目录没有写权限同样会失败


从服务器连接主服务器的几种方式



  1. 在从服务器的配置文件里面配置连接那个主服务器:

连接的具体配置如下:

在5.0版本中使用了replicaof代替了slaveofgithub.com/antirez/red…),slaveof还可以继续使用,不过建议使用replicaof

下面是个人的配置


# replicaof <masterip> <masterport> 
replicaof 127.0.0.1 16379
复制代码


警告:此小节只说明了这一个配置的更改,进行主从配置的时候还有其他几个参数需要更改,这里只作为部分内容参考

  1. 在启动的适合,在redis从服务器的redis-cli当中敲击如下的命令:


127.0.0.1:16380> slaveof 127.0.0.1 16379
OK Already connected to specified master
复制代码


这样就可以在从服务器动态的指定要连接哪个主服务器了,但是这种配置是当前运行时有效,下次再次进入的时候,会根据配置文件进行配置或者按照默认的规则当前实例就是master3.

  1. 在从服务器执行slaveof no one,当前实例脱离控制自动成为master


redis 复制启动的过程==(重点)==



主服务器操作 从服务器操作
1. (等待命令) 1. 连接(重新连接)主服务器,发送sync命令
2. 开始执行bgsave,使用缓冲区记录bgsave之后执行所有写命令 2. 根据配置选项是使用现有的数据(存在)处理客户端请求,还是向请求的客户端返回错误信息
3. bgsave执行完毕,向从服务器发送快照文件,同时异步执行缓冲区记录的写命令 3. 丢弃所有的旧数据,载入主服务器的快照文件
4. 快照文件发送完毕,开始向着从服务器发送存储在缓冲区的写命令 4. 完成对于快照的解释操作,恢复日常的请求操作
5. 缓冲区写命令发送完成,同时现在每执行一个写命令就像从服务器发送相同写命令 5. 执行主服务器发来的所有存储在缓冲区的写命令,并且从现在开始接受主服务器的每一个命令

建议:由于bgsave需要开启进行子线程的创建写入缓冲区的创建,所以最好在系统中预留30% - 45% 内存用于redis的bgsave操作

特别注意:当从服务器连接主服务器的那一刻,执行到第三步会清空当前redis里面的所有数据。


配置方式和命令方式的区别:


redis.conf 配置slaveof 的方式:不会马上进行主服务器同步,而是先载入当前本地存在的rdb或者aof到redis中进行数据恢复,然后才开始同步复制

命令slaveof方式:会立即连接主服务器进行同步操作


关于redis的主主复制:


如果我们尝试让两台服务器互相slaveof 那么会出现上面情况呢?

从上面的复制过程可以看到,当一个服务器slaveof另一个服务器,产生的结果只会是两边相互覆盖,也就是从服务器会去同步主服务器的数据,如果此时按照主主的配置,两边互相同步对方的数据,这样产生的数据可能会不一致,或者数据干脆就是不完整的。不仅如此,这种操作还会大量占用资源区让两台服务器互相知道对方


当一台服务器连接另一台服务器的时候会发生什么?


当有新服务器连接的时候 主服务器操作
步骤3还没有执行 所有从服务器都会收到相同的快照文件和相同缓冲区写命令
步骤3正在执行或者已经执行 完成了之前同步的五个操作之后,会跟新服务器重新执行一次新的五个步骤


系统故障处理



复制和持久化虽然已经基本可以保证系统的数据安全,但是总有意外的情况,比如突然断电断网,系统磁盘故障,服务器宕机等一系列情况,那么会出现各种莫名奇妙的问题,下面针对这些情况说明一下解决方式:


验证快照文件以及aof文件


在redis的bin目录下面,存在如下的两个sh


-rwxr-xr-x 1 root root 9722168 Nov 15 20:53 redis-check-aof
-rwxr-xr-x 1 root root 9722168 Nov 15 20:53 redis-check-rdb
复制代码


他们的命令作用和内容如下:


[xd@iZwz99gyct1a1rh6iblyucZ bin]$ ./redis-check-aof 
Usage: ./redis-check-aof [--fix] <file.aof>
[xd@iZwz99gyct1a1rh6iblyucZ bin]$ ./redis-check-rdb 
Usage: ./redis-check-rdb <rdb-file-name>
复制代码


redis-check-aof:如果加入--fix选项,那么命令会尝试修复aof文件,会将内容里面出现错误的命令以及下面的所有命令清空,一般情况下回清空尾部的一些未完成命令。

redis-check-rdb:遗憾的是目前这种修复收效甚微。建议在修复rdb的时候,用SHA1和SHA256验证文件是否完整。


校验和与散列值:


redis2.6 之后加入了校验和与散列值进行验证。

快照文件增加CRC64校验和

什么是crc循环冗余校验

zh.wikipedia.org/wiki/%E5%BE…


更换故障主服务器:


  1. 假设A故障,存在BC两台机器,B为从服务,C为将要替换的主服务器
  2. 向机器B发送save命令,同时创建一个新的快照文件,同步完成之后,发送给C
  3. 机器C上面启动redis,让C成为B的主服务器


Redis sentienel 哨兵


可以监视指定主服务器以及属下的从服务器

也就是我们常用的哨兵模式

但是随着时代进步,目前使用redis基本还是以cluster模式为主


redis主从复制模式(redis6.0版本):



前提说明:


有条件的可以弄三台虚拟机查看效果,这样模拟出来的效果算是比较真实的。


三台从服务器以及一台主服务器的配置


个人的办法是copy一个公用的配置,然后进行修改(这里只列举区别以及改动较多的地方,其他地方根据需要配置):

第一台机器的配置:


pidfile /var/run/redis_16379.pid
port 16379
dbfilename dump16379.rdb
appendfilename "appendonly16379.aof"
logfile "log16379"
复制代码


第二台机器的配置:


pidfile /var/run/redis_16380.pid
port 16380
dbfilename dump16380.rdb
appendfilename "appendonly16380.aof"
logfile "log16380"
复制代码


第三台机器的配置:


pidfile /var/run/redis_16381.pid
port 16381
dbfilename dump16381.rdb
appendfilename "appendonly16381.aof"
logfile "log16381"
复制代码


这时候要配置一台主服务器


pidfile /var/run/redis_10000.pid
port 10000
dbfilename dump10000.rdb
appendfilename "appendonly10000.aof"
logfile "log10000"
复制代码


启动redis一主多从:



配置很简单,可以用手动进行主从复制,也可以使用redis.conf提前配置,具体区别上文已经进行过介绍,这里不再赘述。

从服务器可以通过命令:slaveof 127.0.0.1 10000 实现主从复制拷贝

可以通过命令info replication 查看主从配置的信息。

主服务器启动日志:


127.0.0.1:10000> info replication
# Replication
role:master
connected_slaves:0
master_replid:e2a92d8c59fbdde3b162da12f4d74ff28bab4fbb
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:10000> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=127.0.0.1,port=16381,state=online,offset=14,lag=1
slave1:ip=127.0.0.1,port=16380,state=online,offset=14,lag=1
slave2:ip=127.0.0.1,port=16379,state=online,offset=14,lag=1
master_replid:029e455ee6f8fdc0e255b6d5c4f63136d933fb24
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
复制代码


可以看到进行主从配置之后,当前的目录下面多出了对应备份文件


网络异常,图片无法展示
|


当进行主从配置之后,从服务就无法进行写入了,主服务器才可以写入:


127.0.0.1:16379> set key 1
(error) READONLY You can't write against a read only replica.
复制代码


测试一主多从复制:


主服务器敲入如下命令:


127.0.0.1:10000> hset key1 name1 value1
(integer) 1
127.0.0.1:10000> keys *
1) "key1"
复制代码


从服务器:


127.0.0.1:16379> hget key1 name1
"value1"
127.0.0.1:16380> hget key1 name1
"value1"
127.0.0.1:16381> hget key1 name1
"value1"
复制代码


主从链


网络异常,图片无法展示
|


配置方式:

和主从配置一样,只不过主节点换为从节点。

注意:主从链的配置依然只能是master节点可以写数据,同时中间的节点也是slave


扩展


如何检测磁盘是否写入数据?

  1. 主从服务器通过一个虚标值(unique dummy value)来验证从服务器是否真的把数据写入到自己的磁盘。
  2. 通过命令:info检查结果当中的 aof_appending_bio_fsync的值是否为0:

# 5.0 版本之后改为如下形式验证

repl_backlog_active:0


redis主从哨兵模式(Redis sentienel)(redis6.0版本)



哨兵模式有什么作用:


Redis的哨兵模式就是对redis系统进行实时的监控,其主要功能有下面两点

1.监测主数据库和从数据库是否正常运行。

2.当我们的主数据库出现故障的时候,可以自动将从数据库转换为主数据库,实现自动的切换


为什么要使用哨兵模式:


  1. 主从复制在主节点宕机的情况下,需要人工干预恢复redis,无法实现高可用。
  2. 主节点宕机的情况下需要备份数据到新的从节点,然后其他节点将主节点设置为新的redis,需要一次全量复制同步数据的过程


哨兵模式原理


主节点故障的时候,由redis sentinel自动完成故障发现和转移


如何部署哨兵模式:


  1. 首先按照上一节配置,已经设置了一个主节点三个从节点的配置

下面的配置如下:

主节点:10000

从节点1:16379

从节点2:16380

从节点3:16381


[xd@iZwz99gyct1a1rh6iblyucZ ~]$ ps -ef | grep redis
xd        2964  2910  0 18:02 pts/0    00:00:00 grep --color=auto redis
root     26412     1  0 Nov23 ?        00:06:07 ./redis-server 127.0.0.1:10000
root     26421     1  0 Nov23 ?        00:05:37 ./redis-server 127.0.0.1:16379
root     26428     1  0 Nov23 ?        00:05:37 ./redis-server 127.0.0.1:16380
root     26435     1  0 Nov23 ?        00:05:37 ./redis-server 127.0.0.1:16381
复制代码


  1. sentinel.conf 配置文件在安装redis的源码包里面有,所以如果误删了可以下回来然后把文件弄到手,其实可以配置一个常用的或者通用的配置放到自己的本地有需要直接替换
  2. 配置5个sentienl.conf文件(建议奇数个哨兵,方便宕机选举产生新的节点)


[xd@iZwz99gyct1a1rh6iblyucZ bin]$ sudo cp sentinel.conf sentinel_26379.conf
[xd@iZwz99gyct1a1rh6iblyucZ bin]$ sudo cp sentinel.conf sentinel_26380.conf
[xd@iZwz99gyct1a1rh6iblyucZ bin]$ sudo cp sentinel.conf sentinel_26381.conf
[xd@iZwz99gyct1a1rh6iblyucZ bin]$ sudo cp sentinel.conf sentinel_10000.conf
复制代码


  1. 四个配置文件的改动依次如下:

所有的sentinel.conf 配置如下:


# 指定哨兵端口
port 20000
# 监听主节点10000
sentinel monitor mymaster 127.0.0.1 10000 2
# 连接主节点时的密码,如果redis配置了密码需要填写
sentinel auth-pass mymaster 12345678
# 故障转移时最多可以有2从节点同时对新主节点进行数据同步
sentinel config-epoch mymaster 2
# 故障转移超时时间180s,
sentinel failover-timeout mymasterA 180000 
# sentinel节点定期向主节点ping命令,当超过了300S时间后没有回复,可能就认定为此主节点出现故障了……
sentinel down-after-milliseconds mymasterA 300000
# 故障转移后,1代表每个从节点按顺序排队一个一个复制主节点数据,如果为3,指3个从节点同时并发复制主节点数据,不会影响阻塞,但存在网络和IO开销
sentinel parallel-syncs mymasterA 1
# 设置后台启动
daemonize yes
# 进程的pid文件,保险起见设置不一样的,特别是设置后台启动的时候
pidfile /var/run/redis-sentinel.pid
复制代码


扩展:如何判定转移失败:

a - 如果转移超时失败,下次转移时时间为之前的2倍;

b - 从节点变主节点时,从节点执行slaveof no one命令一直失败的话,当时间超过180S时,则故障转移失败

c - 从节点复制新主节点时间超过180S转移失败


下面为配好五个之后的配置:


-rw-r--r-- 1 root root   10772 Nov 28 21:00 sentienl_26382.conf
-rw-r--r-- 1 root root   10767 Nov 28 20:43 sentinel_10000.conf
-rw-r--r-- 1 root root   10772 Nov 28 21:03 sentinel_26379.conf
-rw-r--r-- 1 root root   10766 Nov 28 20:46 sentinel_26380.conf
-rw-r--r-- 1 root root   10772 Nov 28 20:59 sentinel_26381.conf
-rw-r--r-- 1 root root   10772 Nov 28 21:03 sentinel_26382.conf
-rw-r--r-- 1 root root   10744 Nov 28 18:06 sentinel.conf
复制代码


  1. 上一节已经启动过,这里不再介绍
  2. 启动sentinel服务

启动五个哨兵:


./redis-sentinel ./sentinel_10000.conf 
./redis-sentinel ./sentinel_26379.conf 
./redis-sentinel ./sentinel_263780.conf 
./redis-sentinel ./sentinel_263781.conf 
./redis-sentinel ./sentinel_263782.conf 
复制代码


使用ps命令查看所有的服务:


root      3267     1  0 21:14 ?        00:00:01 ./redis-sentinel *:20000 [sentinel]
root      3280     1  0 21:15 ?        00:00:01 ./redis-sentinel *:26379 [sentinel]
root      3296     1  0 21:20 ?        00:00:00 ./redis-sentinel *:26380 [sentinel]
root      3303     1  0 21:21 ?        00:00:00 ./redis-sentinel *:26381 [sentinel]
root      3316  3254  0 21:28 pts/0    00:00:00 grep --color=auto redis
root     26412     1  0 Nov23 ?        00:06:17 ./redis-server 127.0.0.1:10000
root     26421     1  0 Nov23 ?        00:05:47 ./redis-server 127.0.0.1:16379
root     26428     1  0 Nov23 ?        00:05:47 ./redis-server 127.0.0.1:16380
root     26435     1  0 Nov23 ?        00:05:47 ./redis-server 127.0.0.1:16381
复制代码


  1. 验证一下哨兵是否管用

10000是主节点,他的info信息如下:


# Keyspace
db0:keys=1,expires=0,avg_ttl=0
127.0.0.1:10000> info replication
# Replication
role:master
connected_slaves:3
复制代码


使用kill -9 master节点进程端口号之后,我们已经干掉了额主进程,验证一下从节点是否启动

进入到6379端口的redis-cli当中,可以看到从节点6379的实例被选举为新的的节点


127.0.0.1:16379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=16380,state=online,offset=857706,lag=1
slave1:ip=127.0.0.1,port=16381,state=online,offset=858242,lag=1
复制代码


挂掉的主节点恢复之后,能不能进行恢复为主节点?

尝试重启挂掉的master之后,可以发现他变成了从节点


127.0.0.1:10000> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:16379
master_link_status:up
master_last_io_seconds_ago:2
复制代码


注意:生产环境建议让redis Sentinel部署到不同的物理机上

如果不喜欢上面的启动哨兵模式,也可以使用下面的命令开启:


[root@dev-server-1 sentinel]# redis-server sentinel1.conf --sentinel
[root@dev-server-1 sentinel]# redis-server sentinel2.conf --sentinel
[root@dev-server-1 sentinel]# redis-server sentinel3.conf --sentinel
复制代码


哨兵模式部署建议


a,sentinel节点应部署在多台物理机(线上环境)

b,至少三个且奇数个sentinel节点

c,通过以上我们知道,3个sentinel可同时监控一个主节点或多个主节点

监听N个主节点较多时,如果sentinel出现异常,会对多个主节点有影响,同时还会造成sentinel节点产生过多的网络连接,

一般线上建议还是, 3个sentinel监听一个主节点

也可以按照下面的方式在启动哨兵的时候启动:


哨兵模式的优缺点:


优点:

  1. 哨兵模式基于主从复制模式,所以主从复制模式有的优点,哨兵模式也有
  2. 哨兵模式下,master挂掉可以自动进行切换,系统可用性更高

缺点:

  1. 同样也继承了主从模式难以在线扩容的缺点,Redis的容量受限于单机配置
  2. 需要额外的资源来启动sentinel进程,实现相对复杂一点,同时slave节点作为备份节点不提供服务
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
存储 NoSQL Linux
centos7部署redis以及多实例
centos7部署redis以及多实例
63 0
|
1天前
|
存储 NoSQL Redis
深入浅出Redis(九):Redis的发布订阅模式
深入浅出Redis(九):Redis的发布订阅模式
|
1天前
|
NoSQL 算法 Java
深入浅出Redis(八):Redis的集群模式
深入浅出Redis(八):Redis的集群模式
|
9天前
|
监控 NoSQL 算法
Redis集群模式:高可用性与性能的完美结合!
小米探讨Redis集群模式,通过一致性哈希分散负载,主从节点确保高可用性。节点间健康检测、主备切换、数据复制与同步、分区策略和Majority选举机制保证服务可靠性。适合高可用性及性能需求场景,哨兵模式则适用于简单需求。一起学习技术的乐趣!关注小米微信公众号“软件求生”获取更多内容。
41 11
Redis集群模式:高可用性与性能的完美结合!
|
11天前
|
监控 NoSQL Redis
Redis分区容错秘诀:解密主从模式
Redis主从模式用于提高高可用性、负载均衡和数据备份。主节点处理写入,从节点复制数据并分担读取,实现故障切换和读写分离。配置主从关系后,从节点连接主节点进行全量和增量复制。当主节点故障,从节点可接管服务。然而,主从延迟和数据不一致性是挑战,可通过优化网络、使用Sentinel和Redis Cluster等解决。关注“软件求生”获取更多内容。
44 1
Redis分区容错秘诀:解密主从模式
|
1月前
|
NoSQL Java Redis
SpringBoot集成Redis并使用Redis发布订阅模式
SpringBoot集成Redis并使用Redis发布订阅模式
58 3
|
2月前
|
NoSQL 关系型数据库 MySQL
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
455 1
|
2月前
|
存储 NoSQL Java
【Redis】1、学习 Redis 的五大基本数据类型【String、Hash、List、Set、SortedSet】
【Redis】1、学习 Redis 的五大基本数据类型【String、Hash、List、Set、SortedSet】
57 0
|
3月前
|
存储 NoSQL 算法
学习 Redis 基础数据结构,不讲虚的。
职场中是这样使用 redis 的。
164 1
学习 Redis 基础数据结构,不讲虚的。
|
3月前
|
NoSQL Java API
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)
301 0