Mysql主从复制和Redis主从复制、持久化

MySql主从复制

MySQL主从复制是一个异步的复制过程, 底层是基于MySQL数据库自带的二进制日志功能。就是一台或多台MySQL数据库(slave,即从库)从另一台MySQL数据库(master,即主库)进行日志的复制然后解析日志并应用到自身,最终实现从库的数据和主库的数据保持一致。MySQL主从复制是MySQL自带功能,无需借助第三方工具。

主库做增删改操作,从库做查操作。

MySQL复制过程分为三步:(master只能有一个,slave可以有多个)
1.master将记录改变到二进制日志(binary log)
2.slave将master的binary log 拷贝到它的中继日志(relay log)
3.slave重做中继日志中的事件,将改变应用到自己的数据库中

配置前置条件:

提前准备好两台服务器,分别安装mysql并启动服务成功
主库Master 192.168.138.100
从库slave 192.168.138.101

配置-主库master

第一步:修改MySql数据库的配置文件/etc/my.cnf
[mysql]
log-bin=mysql-bin #[必须]启用二进制文件
server-id=100 #[必须]服务器唯一ID

第二步:重启mysql服务
systemctl restart mysqld

第三步:登录mysql数据库,执行下面SQL
GRANT REPLICATION SLAVE ON . to ‘xiaoming’@‘%’ identified by ‘Root@123456’;
注:上面SQL的作用是创建一个用户xiaoming,密码为Root@123456,并且给xiaoming用户授予REPLICATION SLAVE权限。常用于
建立复制时所需要用到的用户权限,也就是slave必须被master授权具有该权限的用户,才能通过该用户复制。

第四步:登录mysql数据库,执行sql,记录下结果中File和Position的值
show master status;//File的值是slave第三步sql中的master_log_file,Position是slave第三步sql中的master_log_pos
注:上面SQL的作用是查看master的状态,执行完SQL后不要执行任何操作

配置-从库slave

第一步:修改MySql数据库的配置文件/etc/my.cnf
[mysql]
server-id=101 #[必须]服务器唯一ID

第二步:重启mysql服务
systemctl restart mysqld

第三步:登录mysql数据库,执行下面SQL
change master to
master_host=‘192.168.138.100’,master_user=‘xiaoming’,master_password=‘Root@123456’,master_log_file=‘mysql-bin.000001’,master_log_pos=439;

start slave;

第四步:登录mysql数据库,执行sql,查看从数据库的状态
show slave status;//很多,重点看Slave_IO_Running、Slave_SQL_Running的值是否是Yes

读写分离案例

主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性得到极大的改善。

Sharding-JDBC介绍
使用Sharding-JDBC可以轻松实现数据库读写分离。
1.适用于任何基于JDB的CORM框架。如:JPA、Hibernate、Mybatis;
2.支持任何第三方数据库连接池。如:DBCP、C3P0、Druid;
3.支持任何实现JDBC规范的数据库。

使用Sharding-JDBC实现读写分离步骤:

1.导入maven坐标
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.0.0-RC1</version>
</dependency>
2.在配置文件中配置读写分离规则
spring:
  shardingsphere:
    datasource:
      names:
        master,slave
      #主数据源
      master:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.138.100:3306/rw?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
        username: root
        password: root
      #从数据源
      slave:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.138.101:3306/rw?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
        username: root
        password: root
    masterslave:
      #读写分离配置
      load-balance-algorithm-type: round_robin #轮询
      #最终数据源名称
      name: dataSource
      #主数据源名称
      master-data-source-name: master
      #从数据源名称列表,多个逗号分隔
      slave-data-source-names: slave
    props:
      sql:
        show: true #开启sql显示,默认为false

3.在配置文件中配置运行bean定义覆盖配置项
spring:
  main:
    allow-bean-definition-overriding: true

Redis主从复制

主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主可以读,Slave只能读,不能写。

主要功能:读写分离,性能扩展;容灾快速恢复。

以一主二从为例:有三台服务器192.168.1.1(主) 192.168.1.2 192.168.1.3 分别装了redis。

如何搭建(一主二从):
redis.conf文件修改:
daemonize yes 开启后台启动
Appendonly no 关闭AOF持久化,只用RDB持久化
实现一主二从(不配主机只配从机):这种配置方式只在本次连接有效,如果redis断开连接就失效了。
分别启动redis并登录。
登录进入之后,查看其主机运行的情况:info replication。这个时候三台都是主机,没有从机。
登录从机输入:slaveof <主机ip> <主机端口> 就是服务器2和3 输入:slaveof 192.168.1.1 6379。

永久的配置方式:修改从机(2、3)的配置文件,找到主从配置部分,配置文件搜索replication,大概在配置文件的第386行 replicaof 把注释去掉,这是配置主机的地址和端口。
如果主机有密码,大概在配置文件393行,注释去掉,masterauth 这是配置主机的password。

一主二从

1.当主机断电宕机(可以手动执行shutdown来模拟),默认情况下从机的角色不会发生改变(从机2、3的主机仍然是1),当主机恢复之后,又会连接上从机恢复原状(可以多使用info replication来查看状态)。
2.当从机断电宕机,若不是使用配置文件配置的从机,再次启动后作为主机(从机变成了主机)是无法获取之前主机的数据的,若此时重新配置成为从机,又可以获取到主机的所有数据。

复制原理

slave启动成功后给master发送一个sync(同步)命令。
主数据收到命令之后会开始在后台保存快照(即RDB持久化过程)。并将保存快照期间接受到的修改命令缓存起来,当快照完成后,redis会将快照文件(rdb文件)发给从服务器,从服务器读rdb文件执行命令。
全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。(刚开始从机连接主机,主机一次给,是全量复制的过程)。
增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步 (主机修改了数据会给予从机修改的数据同步,叫做增量复制)。

薪火相传

上一个Slave(2)可以是下一个slave(3)的Master,Slave(2)同样可以接收其他 slave(3)的连接和同步请求,那么该slave(2)作为了链条中下一个的master, 可以有效减轻master(1)的写压力,去中心化降低风险。

slave(3)用 slaveof ,(slaveof 192.168.1.2)中途变更转向:会清除之前的数据,重新建立拷贝最新的。
风险是一旦中间链条某个slave宕机,后面的slave都没法备份,主机挂了,从机还是从机,无法写数据了。

反客为主(默认情况下使用slaveof命令配置)

(薪火相传模式下)当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。
可以使用命令:slaveof no one 将从机变为主机。
(一主二从模式下),master宕机,一台主机(2)执行slaveof no one 变为主机,其他主机(3)执行命令重新连接主机(2)。

哨兵模式

主要是为了监控主机宕机之后,从机可以立马变为主机,就和上面的反客为主一样(但是是在一主多从里使用),不用手动设置。
能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。

如何实现:
在redis的配置文件所在的文件夹下,创建一个哨兵文件sentinel.conf。
sentinel.conf:

# 哨兵 监视 【名称】 监视的主机地址 端口 ; 
# 最后一位 11 为至少有多少个哨兵同意迁移的数量
sentinel monitor mysentinel 127.0.0.1 6379 1

在 Redis 启动目录有一个哨兵文件redis-sentinel
启动命令:redis-sentinel /sentinel.conf

具体哪个从机会变成主机,其判定规则主要为:(优先级>偏移量>runid)
优先级在redis.conf中默认:slave-priority 100,值越小优先级越高;
偏移量是指获得原主机数据最全的,也就是数据越多,变主机的机会越大;
每个redis实例启动后都会随机生成一个40位的runid.

哨兵模式的优缺点:
哨兵集群,基于主从复制模式,所有主从复制的优点,它都有;主从可以切换,故障可以转移,系统的可用性更好;哨兵模式是主从模式的升级,手动到自动,更加健壮。
Redis不好在线扩容,集群容量一旦达到上限,在线扩容就十分麻烦;实现哨兵模式的配置其实是很麻烦的,里面有很多配置项。

完整的哨兵模式配置文件 sentinel.conf

# Example sentinel.conf
 
# 哨兵sentinel实例运行的端口 默认26379
port 26379
 
# 哨兵sentinel的工作目录
dir /tmp
 
# 哨兵sentinel监控的redis主节点的 ip port 
# master-name  可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。
# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 1
 
# 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提供密码
# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
 
 
# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000
 
# 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,
这个数字越小,完成failover所需的时间就越长,
但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。
可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
 
 
 
# 故障转移的超时时间 failover-timeout 可以用在以下这些方面: 
#1. 同一个sentinel对同一个master两次failover之间的间隔时间。
#2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
#3.当想要取消一个正在进行的failover所需要的时间。  
#4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了
# 默认三分钟
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
 
# SCRIPTS EXECUTION
 
#配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。
#对于脚本的运行结果有以下规则:
#若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
#若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
#如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
#一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。
 
#通知型脚本:当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本,
#这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传给脚本两个参数,
#一个是事件的类型,
#一个是事件的描述。
#如果sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentinel无法正常启动成功。
#通知脚本
# sentinel notification-script <master-name> <script-path>
  sentinel notification-script mymaster /var/redis/notify.sh
 
# 客户端重新配置主节点参数脚本
# 当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。
# 以下参数将会在调用脚本时传给脚本:
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
# 目前<state>总是“failover”,
# <role>是“leader”或者“observer”中的一个。 
# 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的slave)通信的
# 这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentinel client-reconfig-script <master-name> <script-path>
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

Redis持久化,默认是不开启AOF,开启RDB

持久化 默认是不开启AOF,开启RDB。

RDB(Redis DataBase)

在指定的时间间隔内将内存中的数据集快照写入磁盘。
具体的备份流程如下
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。

redis.conf中的配置:
1.save 20 3 意思是如果在20s内有3个key发生改变,那么就将其写入临时文件dump.rdb中去。
2.stop-writes-on-bgsave-error yes 关闭写入磁盘操作。比如当Redis无法写入磁盘的话,直接关掉Redis的写操作。
3.rdbcompression yes 对于存储到磁盘中的快照,可以设置是否进行压缩存储,如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。推荐yes.
4.rdbchecksum yes 增加数据校验,增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
5.dbfilename dump.rdb 在redis.conf中配置文件名称,默认为dump.rdb
6.dir ./ 默认为Redis启动时命令行所在的目录下。

优/缺点:
适合大规模的数据恢复;对数据完整性和一致性要求不高更适合使用;节省磁盘空间;恢复速度快。
Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑。
虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。

AOF(Append of File)

日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录), 只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

AOF的备份机制和性能虽然和RDB不同, 但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。

redis.conf配置:
appendonly no,改为yes,开启AOF持久化方式。
appendonly.aof 默认临时文件名称,路径和RDB一样。
如果遇到AOF文件损坏,可以通过/usr/local/bin/redis-check-aof–fix appendonly.aof进行恢复。

AOF频率同步机制:
appendfsync always 始终同步,每次Redis的写入都会立刻记入日志;性能较差但数据完整性比较好。
appendfsync everysec 每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
appendfsync no redis不主动进行同步,把同步时机交给操作系统。

Rewrite重写机制:
AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制, 当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩, 只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof

重写的原理,如何重写
AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename。
redis4.0版本后的重写,是指上就是把rdb 的快照,以二级制的形式附在新的aof头部,作为已有的历史数据,替换掉原来的流水账操作。

触发条件,何时重写
Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。
auto-aof-rewrite-percentage:设置重写的基准值,文件达到100%时开始重写(文件是原来重写后文件的2倍时触发)。
auto-aof-rewrite-min-size:设置重写的基准值,最小文件64MB。达到这个值开始重写。

优缺点:
备份机制更稳健,丢失数据概率更低;可读的日志文本,通过操作AOF稳健,可以处理误操作。
比起RDB占用更多的磁盘空间;恢复备份速度要慢;每次读写都同步的话,有一定的性能压力;存在个别Bug,造成恢复不能。

如果同时开启两个持久化方式,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据, 因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RedisMySQL主从复制的架构中,读写过程通常包括以下步骤: 1. 客户端连接Redis主服务器。客户端通过TCP/IP协议连接Redis主服务器,并进行身份验证。 2. 客户端发送Redis命令。客户端向Redis主服务器发送命令,包括读取和写入操作。 3. Redis主服务器执行命令。Redis主服务器根据接收到的命令执行相应的操作,包括读取和写入数据。 4. Redis主服务器将写入操作同步到MySQL主服务器。Redis主服务器将写入操作同步到MySQL主服务器上,保证数据的持久化。 5. MySQL主服务器将写入操作同步到MySQL从服务器。MySQL主服务器将写入操作同步到MySQL从服务器上,保证数据的复制和备份。 6. 客户端连接Redis从服务器或MySQL从服务器。客户端可以选择连接Redis从服务器或MySQL从服务器进行读取操作。如果连接Redis从服务器,则可以充分利用Redis从服务器的读取性能;如果连接MySQL从服务器,则可以保证数据的一致性和可靠性。 7. 客户端发送读取命令。客户端向Redis从服务器或MySQL从服务器发送读取命令。 8. Redis从服务器或MySQL从服务器执行读取命令。Redis从服务器或MySQL从服务器根据接收到的读取命令执行相应的操作,包括读取数据并返回结果。 9. Redis从服务器或MySQL从服务器将结果返回给客户端。Redis从服务器或MySQL从服务器将执行结果返回给客户端,客户端进行相应的处理。 在RedisMySQL主从复制的架构中,主服务器负责写操作和数据同步,从服务器负责读操作和数据复制。这样可以充分利用RedisMySQL各自的优势,同时保证数据的一致性和可靠性。但是需要注意的是,主从复制架构中可能存在数据同步延迟和数据不一致等问题,需要根据实际需求进行相应的优化和调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值