程序笔记   发布时间:2022-07-15  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了一文把Redis主从复制(1),2021谈一下当下最合适的Java架构大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_489_0@allkeys->random -> 无差别随机删, 任何一个key。 @H_489_0@volatile-ttl -> 根据最近过期时间来删除(辅以TTL), 这是对于有过期时间的key @H_489_0@noeviction -> 谁也不删,直接在写操作时返回错误。 @H_865_6@maxmemory-policy volatile-lru

@H_489_0@AOF开启

appendonly no

@H_489_0@aof文件名

appendfilename "appendonly.aof"

@H_489_0@fsync() 系统调用告诉操作系统把数据写到磁盘上,而不是等更多的数据进入输出缓冲区。 @H_489_0@有些操作系统会真的把数据马上刷到磁盘上;有些则会尽快去尝试这么做。 @H_489_0@redis支持三种不同的模式: @H_489_0@no:不要立刻刷,只有在操作系统需要刷的时候再刷。比较快。 @H_489_0@always:每次写操作都立刻写入到aof文件。慢,但是最安全。 @H_489_0@everysec:每秒写一次。折中方案。

appendfsync everysec

@H_489_0@如果AOF的同步策略设置成 "always" 或者 "everysec",并且后台的存储进程(后台存储或写入AOF @H_489_0@日志)会产生很多磁盘I/O开销。某些Linux的配置下会使redis因为 fsync()系统调用而阻塞很久。 @H_489_0@注意,目前对这个情况还没有完美修正,甚至不同线程的 fsync() 会阻塞我们同步的write(2)调用。 @H_489_0@为了缓解这个问题,可以用下面这个选项。它可以在 BGSAVE 或 BGREWRITEAOF 处理时阻止主进程进行fsync()。 @H_489_0@这就意味着如果有子进程在进行保存操作,那么redis就处于"不可同步"的状态。 @H_489_0@这实际上是说,在最差的情况下可能会丢掉30秒钟的日志数据。(默认Linux设定) @H_489_0@如果你有延时问题把这个设置成"yes",否则就保持"no",这是保存持久数据的最安全的方式。

no-appendfsync-on-rewrite yes

@H_489_0@自动重写AOF文件

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

@H_489_0@AOF文件可能在尾部是不完整的(这跟system关闭有问题,尤其是mount ext4文件系统时 @H_489_0@没有加上data=ordered选项。只会发生在os死时,redis自己死不会不完整)。 @H_489_0@那redis重启时load进内存的时候就有问题了。 @H_489_0@发生的时候,可以选择redis启动报错,并且通知用户和写日志,或者load尽量多正常的数据。 @H_489_0@如果aof-load-truncated是yes,会自动发布一个log给客户端然后load(默认)。 @H_489_0@如果是no,用户必须手动redis-check-aof修复AOF文件才可以。 @H_489_0@注意,如果在读取的过程中,发现这个aof是损坏的,服务器也是会退出的, @H_489_0@这个选项仅仅用于当服务器尝试读取更多的数据但又找不到相应的数据时。

aof-load-truncated yes

@H_489_0@Lua 脚本的最大执行时间,毫秒为单位

lua-time-limit 5000

@H_489_0@redis慢查询日志可以记录超过指定时间的查询

slowlog-log-slower-than 10000

@H_489_0@这个长度没有限制。只是要主要会消耗内存。你可以通过 SLOWLOG RESET 来回收内存。

slowlog-max-len 128

@H_489_0@客户端的输出缓冲区的限制,可用于强制断开那些因为某种原因从服务器读取数据的速度不够快的客户端

client-output-buffer-limit normal 0 0 0

client-output-buffer-limit slave 256mb 64mb 60

client-output-buffer-limit pubsub 32mb 8mb 60

@H_489_0@当一个子进程重写AOF文件时,文件每生成32M数据会被同步

aof-rewrite-incremental-fsync yes

@H_675_95@


由于,单机版的redis在并发量比较大的时候,并且需要较高性能和可靠性的时候,单机版基本就不适合了,于是就出现了**「主从模式」****主从模式**

--------



### **原理**



主从的原理还算是比较简单的,一主多从,**「主数据库(master)可以读也可以写(read/write),从数据库仅读(only read)」**。



但是,主从模式一般实现**「读写分离」****「主数据库仅写(only write)」**,减轻主数据库的压力,下面一张图搞懂主从模式的原理:



![](https://img-blog.csdnimg.cn/img_convert/60bb593ca1f41439b55b5f06195bd1c3.png)



主从模式原理就是那么简单,那他执行的过程(工作机制)又是怎么样的呢?再来一张图:



![](https://img-blog.csdnimg.cn/img_convert/bab5396b0953355939c1a3da1177d9ba.png)



当开启主从模式的时候,他的具体工作机制如下:



1.  当slave启动后会向master发送`SYNC`命令,master节后到从数据库的命令后通过`bgsave`保存快照(**「RDB持久化」**),并且期间的执行的些命令会被缓存起来。

2.  然后master会将保存的快照发送给slave,并且继续缓存期间的写命令。

3.  slave收到主数据库发送过来的快照就会加载到自己的数据库中。

4.  最后master讲缓存的命令同步给slave,slave收到命令后执行一遍,这样master与slave数据就保持一致了。



### **优点**



之所以运用主从,是因为主从一定程度上解决了单机版并发量大,导致请求延迟或者redis宕机服务停止的问题。



从数据库分担主数据库的读压力,若是主数据库是只写模式,那么实现读写分离,主数据库就没有了读压力了。



另一方面解决了单机版单点故障的问题,若是主数据库挂了,那么从数据库可以随时顶上来,综上来说,主从模式一定程度上提高了系统的可用性和性能,是实现哨兵和集群的基础。



主从同步以异步方式进行同步,期间redis仍然可以响应客户端提交的查询和更新的请求。



### **缺点**



主从模式好是好,他也有自己的缺点,比如数据的一致性问题,假如主数据库写操作完成,那么他的数据会被复制到从数据库,若是还没有即使复制到从数据库,读请求又来了,此时读取的数据就不是最新的数据。



若是从主同步的过程网络出故障了,导致主从同步失败,也会出现问题数据一致性的问题。



主从模式不具备自动容错和恢复的功能,一旦主数据库,从节点晋升未主数据库的过程需要人为操作,维护的成本就会升高,并且主节点的写能力、存储能力都会受到限制。



### **实操搭建**



下面的我们来实操搭建一下主从模式,主从模式的搭建还是比较简单的,我这里一台centos 7虚拟机,使用开启redis多实例的方法搭建主从。



redis中开启多实例的方法,首先创建一个文件夹,用于存放redis集群的配置文件:



@H_865_6@mkdir redis

@H_675_95@


然后粘贴复制`redis.conf`配置文件:



cp /root/redis-4.0.6/redis.conf /root/redis/redis-6379.conf

cp /root/redis-4.0.6/redis.conf /root/redis/redis-6380.conf

cp /root/redis-4.0.6/redis.conf /root/redis/redis-6381.conf

@H_675_95@


复制三份配置文件,一主两从,6379端口作为主数据库(master),6380、6381作为从数据库(slave)。



首先是配置主数据库的配置文件:`vi redis-6379.conf`:



bind 0.0.0.0 # 注释掉或配置成0.0.0.0表示任意IP均可访问。

protected-mode no # 关闭保护模式,使用密码访问。

port 6379 # 设置端口,6380、6381依次为6380、6381。

timeout 30 # 客户端连接空闲多久后断开连接,单位秒,0表示禁用

daemonize yes # 在后台运行

pidfile /var/run/redis_6379.pid # pid进程文件名,6380、6381依次为redis_6380.pid、redis_6381.pid

logfile /root/rEIDs/log/6379.log # 日志文件,6380、6381依次为6380.log、6381.log

save 900 1 # 900s内至少一次写操作则执行bgsave进行RDB持久化

save 300 10

save 60 10000

rdbcompression yes #是否对RDB文件进行压缩,建议设置为no,以(磁盘)空间换(CPU)时间

dbfilename dump.rdb # RDB文件名称

dir /root/redis/datas # RDB文件保存路径,AOF文件也保存在这里

appendonly yes # 表示使用AOF增量持久化的方式

appendfsync everysec # 可选值 always, everysec,no,建议设置为everysec

requirepass 123456 # 设置密码

@H_675_95@


然后,就是修改从数据库的配置文件,在从数据库的配置文件中假如以下的配置信息:



slaveof 127.0.0.1 6379 # 配置master的ip,port

@H_865_6@masterauth 123456 # 配置访问master的密码

slaveof-serve-stale-data no

@H_675_95@


接下来就是启动三个redis实例,启动的命令,先cd到redis的src目录下,然后执行:



./redis-server /root/redis/6379.conf

./redis-server /root/redis/6380.conf

./redis-server /root/redis/6381.conf

@H_675_95@


通过命令`ps -aux | grep redis`,查看启动的redis进程:



![](https://img-blog.csdnimg.cn/img_convert/6ed6f0425f9b22e23fea2746911d9e12.png)



如上图所示,表示启动成功,下面就开始进入测试阶段。



### **测试**



我这里使用SecureCRT作为redis连接的客户端,同时启动三个SecureCRT,分别连接redis1的三个实例,启动时指定端口以及密码:



./redis-cli -p 6379 -a 123456

@H_675_95@


![](https://img-blog.csdnimg.cn/img_convert/01df1d7bcf65eb109de971eb23238f75.png)



启动后,在master(6379),输入:set name 'ldc',在slave中通过get name,可以查看:



![](https://img-blog.csdnimg.cn/img_convert/5f583ffcde5e2cd91f33d76590944a3f.png)



数据同步成功,这有几个坑一个是redis.conf中没有设置对bind,会导致非本机的ip被过滤掉,一般配置0.0.0.0就可以了。



另一个是没有配置密码requirepass 123456,会导致IO一直连接异常,这个是我遇到的坑,后面配置密码后就成功了。



还有,就是查看redis的启动日志可以发现有两个warning,然不影响搭建主从同步,看着挺烦人的,但是有些人会遇到,有些人不会遇到。



但是,我这个人比较有强迫症,百度也是有解决方案的,这里就不讲了,交给你们自己解决,这里只是告诉你有这个问题,有些人看都不看日志的,看到启动成功就认为万事大吉了,也不看日志,这习惯并不好。



![](https://img-blog.csdnimg.cn/img_convert/ea808e190d3a885e7b671290172ee479.png)



**哨兵模式**

--------



### **原理**



哨兵模式是主从的升级版,因为主从的出现故障后,不会自动恢复,需要人为干预,这就很蛋疼啊。



在主从的基础上,实现哨兵模式就是为了监控主从的运行状况,对主从的健壮进行监控,就好像哨兵一样,只要有异常就发出警告,对异常状况进行处理。



![](https://img-blog.csdnimg.cn/img_convert/bbf7a4d05476788fbba7b5fdd2838e03.png)



所以,总的概括来说,哨兵模式有以下的优点(功能点):



1.  **「监控」**:监控Master和Slave是否正常运行,以及哨兵之间也会相互监控

2.  **「自动故障恢复」**:当master出现故障的时候,会自动选举一个slave作为master顶上去。



哨兵模式的监控配置信息,是通过配置从数据库的`senTinel monitor <master-name> <ip> <redis-port> <quorum>`?来指定的,比如:



// mymaster 表示给master数据库定义了一个名字,后面的是master的ip和端口,1表示至少需要一个SenTinel进程同意才能将master判断为失效,如果不满足这个条件,则自动@R_171_10772@(failover)不会执行

senTinel monitor mymaster 127.0.0.1 6379 1

@H_675_95@


### **节点通信**



当然还有其它的配置信息,其它配置信息,在环境搭建的时候再说。当哨兵启动后,会与master建立一条连接,用于订阅master的`_senTinel_:Hello`频道。



该频道用于获取监控该master的其它哨兵的信息。并且还会建立一条定时向master发送INFO命令获取master信息的连接。



**「当哨兵与master建立连接后,定期会向(10秒一次)Master和Slave发送INFO命令,若是master被标记为主观下线,频率就会变为1秒一次。」**



并且,定期向`_senTinel_:Hello`频道发送自己的信息,以便其它的哨兵能够订阅获取自己的信息,发送的内容包含**「哨兵的ip和端口、运行id、配置版本、master名字、master的ip端口还有master的配置版本」**等信息。



以及,**「定期的向master、slave和其它哨兵发送PING命令(每秒一次),以便检测对象是否存活」**,若是对方接收到了PING命令,无故障情况下,会回复PONG命令。



所以,哨兵通过建立这两条连接、通过定期发送INFO、PING命令来实现哨兵与哨兵、哨兵与master之间的通信。



这里涉及到一些概念需要理解,INFO、PING、PONG等命令,后面还会有MEET、FAIL命令,以及主观下线,当然还会有客观下线,这里主要说一下这几个概念的理解:



1.  INFO:该命令可以获取主从数据库的最新信息,可以实现新结点的发现

2.  PING:该命令被使用最频繁,该命令封装了自身节点和其它节点的状态数据。

3.  PONG:当节点收到MEET和PING,会回复PONG命令,也把自己的状态发送给对方。

4.  MEET:该命令在新结点加入集群的时候,会向老节点发送该命令,表示自己是个新人

5.  FAIL:当节点下线,会向集群中广播该消息。



### **上线和下线**



当哨兵与master相同之后就会定期一直保持联系,若是某一时刻哨兵发送的PING在指定时间内没有收到回复(`senTinel down-after-milliseconds master-name milliseconds`?配置),那么发送PING命令的哨兵就会认为该master**「主观下线」**(`Subjectively Down`)。



因为有可能是哨兵与该master之间的网络问题造成的,而不是master本身的原因,所以哨兵同时会询问其它的哨兵是否也认为该master下线,若是认为该节点下线的哨兵达到一定的数量(**「前面的quorum字段配置」**),就会认为该节点**「客观下线」**(`Objectively Down`)。



若是没有足够数量的senTinel同意该master下线,则该master客观下线的标识会被移除;若是master重新向哨兵的PING命令回复了客观下线的标识也会被移除。



### **选举算法**



当master被认为客观下线后,又是怎么进行故障恢复的呢?原来哨兵中首先选举出一个老大哨兵来进行故障恢复,选举老大哨兵的算法叫做**「Raft算法」**:



1.  发现master下线的哨兵(senTinelA)会向其它的哨兵发送命令进行拉票,要求选择自己为哨兵大佬。

2.  若是目标哨兵没有选择其它的哨兵,就会选择该哨兵(senTinelA)为大佬。

3.  若是选择senTinelA的哨兵超过半数(半数原则),该大佬非senTinelA莫属。

4.  如果有多个哨兵同时竞选,并且可能存在票数一致的情况,就会等待下次的一个随机时间再次发起竞选请求,进行新的一轮投票,直到大佬被选出来。



选出大佬哨兵后,大佬哨兵就会对故障进行自动回复,从slave中选出一名slave作为主数据库,选举的规则如下所示:



1.  所有的slave中`slave-priority`优先级最高的会被选中。

2.  若是优先级相同,会选择偏移量最大的,因为偏移量记录着数据的复制的增量,越大表示数据越完整。

3.  若是以上两者都相同,选择ID最小的。



通过以上的层层筛选最终实现故障恢复,当选的slave晋升为master,其它的slave会向新的master复制数据,若是down掉的master重新上线,会被当作slave角色运行。



### **优点**



哨兵模式是主从模式的升级版,所以在系统层面提高了系统的可用性和性能、稳定性。当master宕机的时候,能够自动进行故障恢复,需不要人为的干预。



哨兵于哨兵之间、哨兵与master之间能够进行及时的监控,心跳检测,及时发现系统的问题,这都是弥补了主从的缺点。



### **缺点**



哨兵一主多从的模式同样也会遇到写的瓶颈,已经存储瓶颈,若是master宕机了,故障恢复的时间比较长,写的业务就会受到影响。



增加了哨兵也增加了系统的复杂度,需要同时维护哨兵模式。



### **实操搭建**



最后,我们进行一下哨兵模式的搭建,配置哨兵模式还是比较简单的,在上面配置的主从模式的基础上,同时创建一个文件夹用于存放三个哨兵的配置文件:



@H_865_6@mkdir /root/redis-4.0.6/senTinel.conf /root/redis/senTinel/senTinel1.conf

@H_865_6@mkdir /root/redis-4.0.6/senTinel.conf /root/redis/senTinel/senTinel2.conf

@H_865_6@mkdir /root/redis-4.0.6/senTinel.conf /root/redis/senTinel/senTinel3.conf

@H_675_95@


分别在这三个文件中添加如下配置:



daemonize yes # 在后台运行

senTinel monitor mymaster 127.0.0.1 6379 1 # 给master起一个名字mymaster,并且配置master的ip和端口

senTinel auth-pass mymaster 123456 # master的密码

port 26379 #另外两个配置36379,46379端口

senTinel down-after-milliseconds mymaster 3000 # 3s未回复PING就认为master主观下线

senTinel parallel-syncs mymaster 2 # 执行@R_171_10772@时,最多可以有2个slave实例在同步新的master实例

senTinel failover-timeout mymaster 100000 # 如果在10s内未能完成@R_171_10772@操作认为@R_171_10772@失败

@H_675_95@


配置完后分别启动三台哨兵:



./redis-server senTinel1.conf --senTinel

./redis-server senTinel2.conf --senTinel

./redis-server senTinel3.conf --senTinel

@H_675_95@


然后通过:`ps -aux|grep redis`进行查看:



![](https://img-blog.csdnimg.cn/img_convert/75687964a39d22481e73dc2fdf094eed.png)



可以看到三台redis实例以及三个哨兵都已经正常启动,现登陆6379,通过INFO Repliaction查看master信息:



![](https://img-blog.csdnimg.cn/img_convert/d099ff090082e5e726a2f289158e4780.png)



当前master为6379,然后我们来测试一下哨兵的自动故障恢复,直接kill掉6379进程,然后通过登陆6380再次查看master的信息:



![](https://img-blog.csdnimg.cn/img_convert/016b6ea74c82915d3c2f1e2d405a192b.png)



可以看到当前的6380角色是master,并且6380可读可写,而不是只读模式,这说明我们的哨兵是起作用了,搭建成功,感兴趣的可以自行搭建,也有可能你会踩一堆的坑。



**Cluster模式**

-------------



## 结语

小编也是很有感触,如果一直都是在中小公司,没有接触过大型的互联网架构设计的话,只靠自己看书去提升可能一辈子都很难达到高级架构师的技术和认知高度。向厉害的人去学习是最有效减少时间摸索、精力浪费的方式。

我们选择的这个行业就一直要持续的学习,又很吃青春饭。

然大家可能经常见到说程序员年薪几十万,但这样的人毕竟不是大部份,要么是有名校光环,要么是在阿里华为这样的大企业。年龄一大,更有可能被裁。

小编整理的学习资料分享一波!

送给每一位想学习Java小伙伴,用来提升自己。**[想要资料的可以点击这里免费获取](https://gitee.com/vip204888/java-P7)**
![在这里插入图片描述](https://upload-images.jianshu.io/upload_images/24616006-d97e60b71731ed14?imageMogr2/auto-orient/Strip%7CimageView2/2/w/1240)

> 本文到这里就结束了,喜欢的朋友可以帮忙点赞和评论一下,感谢支持!

大佬总结

以上是大佬教程为你收集整理的一文把Redis主从复制(1),2021谈一下当下最合适的Java架构全部内容,希望文章能够帮你解决一文把Redis主从复制(1),2021谈一下当下最合适的Java架构所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。