Mysql主从复制及读写分离

admin admin 2023-10-19 246 阅读 0 评论

一、为什么使用主从复制、读写分离?

二、主从复制的原理

三、 如何实现主从复制

四、 使用ShardingJDBC配置读写分离


一、为什么使用主从复制、读写分离?

  1. 读和写的压力都由一台数据库承担,压力大
  2. 数据库服务器磁盘损坏则数据丢失,单点故障
  3. 为了提高数据库的并发性能,
  4. 随着业务量的扩展、如果是单机部署的MySQL,会导致I/O频率过高。采用主从复制、读写分离可以提高数据库的可用性。

二、主从复制的原理

Mysql主从复制是一个异步的复制过程,底层是基于Myslq自带的二进制日志功能,就是一台或多台(从库)Mysql数据库从另一台数据库(主库)进行二进制日志的复制然后再解析应用于自身,最终实现从库的数据和主库数据一致。

2PC_SO{4M35D9}WXZ]C@S1K.png

在这里插入图片描述

  1. 当Master节点进行insert、update、delete操作时,会按顺序写入到binlog中。
  2. salve从库连接master主库,Master有多少个slave就会创建多少个binlog dump线程。
  3. 当Master节点的binlog发生变化时,binlog dump 线程会通知所有的salve节点,并将相应的binlog内容推送给slave节点。
  4. I/O线程接收到 binlog 内容后,将内容写入到本地的 relay-log(中继日志)。
  5. SQL线程读取I/O线程写入的relay-log,并且根据 relay-log 的内容对从数据库做对应的操作。

三、 如何实现主从复制

从库可以有多台,这里使用一主一从模式

数据库ip
Master192.168.100.101
Slave192.168.100.102

检查各自防火墙是否对数据库指定端口进行开放

3.1. Master配置

修改Mysql数据库的配置文件: /etc/my,cnf

# 开启binlog【必须】
log-bin=mysql-bin
# 服务器唯一ID,唯一即可【必须】
server-id=101 
# 需要同步的数据库,如果不配置则同步全部数据库
binlog-do-db=test_demo
# binlog日志保留的天数,清除超过10天的日志
# 防止日志文件过大,导致磁盘空间不足
expire-logs-days=10 

配置完成后,重启mysql:

systemctl restart mysqld

创建数据库同步用户并进行授权

注意:

上面语句的意思是创建了一个用户zhangsan,密码Java@123456,并授予了REPLICATION SLAVE权限,用于复制是所需要用到的用户权限,也就是slave必须被master授权的用户,才能复制,
目前mysql5.7默认密码等级为MEDIUM,该等级要求密码组成为:数字,大,小写字母,特殊字符,至少8位
使用命令行进入mysql:
mysql -u root -p
创建用户并授权
GRANT REPLICATION SLAVE ON *.* to 'zhangsan'@'%' identified by 'Java@123456';

登录数据库查看master状态

show master status;
FilePosition
mysql-bin.000001367

执行完后master不要执行任何操作(此时的Position 数值已经获取,从库要使用一旦操作Position 会改变)

3.2. Slave配置

修改Mysql数据库的配置文件: /etc/my,cnf

# 不要和其他mysql服务id重复即可
server-id=102

配置完成后,重启mysql:

systemctl restart mysqld

设置主库地址及同步位置

使用命令行进入mysql:

mysql -u root -p

执行以下语句

CHANGE MASTER TO 
MASTER_HOST='192.168.100.101',//主机IP
MASTER_USER='zhangsan',//之前创建的用户账号
MASTER_PASSWORD='Java@123456',//之前创建的用户密码
MASTER_LOG_FILE='mysql-bin.000001',//master主机的binlog日志名称
MASTER_LOG_POS=367,//binlog日志偏移量
master_port=3306;//端口

设置完之后需要启动:

start slave;

查看slave状态

show slave status\G;

\G:sql语句后加\G,表示将查询结果进行按列打印,也就是结构旋转90度变成纵向

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.100.101
                  Master_User: zhangsan
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 247
               Relay_Log_File: mysqld-relay-bin.000001
                Relay_Log_Pos: 374
        Relay_Master_Log_File: mysql-bin.000001 //binlog日志文件名称
             Slave_IO_Running: Yes //Slave_IO线程、SQL线程都在运行
            Slave_SQL_Running: Yes

Slave_IO_Running和Slave_SQL_Running都是Yes,则表示同步完成。

四、 使用ShardingJDBC配置读写分离

主从复制完成后,我们还需要实现读写分离,master负责写入数据,slave负责读取数据。

4.1. 添加sharding-jdbc的maven依赖:

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.1.1-RC1</version>
</dependency>

4.2. 然后在application.yml添加配置

这是使用druid连接池的配置

spring:
  shardingsphere:
    datasource:
      names:
        master,slave1   # 配置了几个则写几个,和下面名字一致即可
      # 主数据源
      master:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.100.101:3306/test_demo?characterEncoding=utf-8
        username: root
        password: 123456
      # 从数据源
      slave1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.100.102:3306/test_demo?characterEncoding=utf-8
        username: root
        password: 123456
 #       slave2:
  #        type: com.alibaba.druid.pool.DruidDataSource
  #        driver-class-name: com.mysql.jdbc.Driver
  #        url: jdbc:mysql://192.168.0.110:3306/test_demo?characterEncoding=utf-8
  #        username: root
  #        password: 123456
    masterslave:
      # 读写分离配置
      load-balance-algorithm-type: round_robin #轮询
      # 最终的数据源名称
      name: dataSource
      # 主库数据源名称
      master-data-source-name: master
      # 从库数据源名称列表,多个逗号分隔
      slave-data-source-names: slave1
    props:
      sql:
        show: true #开启SQL显示,默认false
  main:
    allow-bean-definition-overriding: true

load-balance-algorithm-type是路由策略,round_robin表示轮询策略。

4.3. 如果Bean定义冲突报错

可以添加如下添加配置

spring
  main:
    allow-bean-definition-overriding: true


上一篇 下一篇

相关阅读

发表评论

访客 访客
快捷回复: 表情:
评论列表 (有 0 条评论,246人围观)