Mysql主从复制及读写分离

简介:java系列技术分享(持续更新中…)
初衷:一起学习、一起进步、坚持不懈
如果文章内容有误与您的想法不一致,欢迎大家在评论区指正
希望这篇文章对你有所帮助,欢迎点赞 收藏 ⭐留言

更多文章请点击
在这里插入图片描述在这里插入图片描述

文章目录

  • 一、为什么使用主从复制、读写分离?
  • 二、主从复制的原理
  • 三、 如何实现主从复制
    • 3.1. Master配置
    • 3.2. Slave配置
  • 四、 使用ShardingJDBC配置读写分离
    • 4.1. 添加sharding-jdbc的maven依赖:
    • 4.2. 然后在application.yml添加配置
    • 4.3. 如果Bean定义冲突报错

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

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

二、主从复制的原理

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

Mysql主从复制及读写分离_第1张图片

  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
Master 192.168.100.101
Slave 192.168.100.102

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

3.1. Master配置

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

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

    systemctl restart mysqld
    
  3. 创建数据库同步用户并进行授权

    • 使用命令行进入mysql:
      mysql -u root -p
      
    • 创建用户并授权
      GRANT REPLICATION SLAVE ON *.* to 'zhangsan'@'%' identified by 'Java@123456';
      

    注意:

    • 上面语句的意思是创建了一个用户zhangsan,密码Java@123456,并授予了REPLICATION SLAVE权限,用于复制是所需要用到的用户权限,也就是slave必须被master授权的用户,才能复制,
    • 目前mysql5.7默认密码等级为MEDIUM,该等级要求密码组成为:数字,大,小写字母,特殊字符,至少8位
  4. 登录数据库查看master状态

    show master status;
    
    File Position
    mysql-bin.000001 367

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

3.2. Slave配置

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

    # 不要和其他mysql服务id重复即可
    server-id=102
    
  2. 配置完成后,重启mysql:

    systemctl restart mysqld
    
  3. 设置主库地址及同步位置

    • 使用命令行进入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;
      
  4. 查看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.shardingspheregroupId>
    <artifactId>sharding-jdbc-spring-boot-starterartifactId>
    <version>4.1.1-RC1version>
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

在这里插入图片描述在这里插入图片描述

你可能感兴趣的:(Mysql面试题,mysql,数据库,java)