美文网首页
mysql主从复制架构

mysql主从复制架构

作者: sunpy | 来源:发表于2022-08-18 21:20 被阅读0次

    为什么要设计mysql主从复制架构


    为了解决mysql中出现单点故障的问题,进而设计了mysql主从架构,保障整体服务性能和稳定。mysql提供的复制也是一种高性能高可用方案,实现最终一致性。而且主从架构的设计,往往是一主库,一从库,主从库之间异步同步数据。可以让主服务器写,让从服务器读,这样可以实现读写分离。

    主从复制原理


    1. master将数据更改记录到二进制日志binlog。
    2. slave将主服务器的二进制日志复制到自己的中继日志relay log。
    3. 服务器重做中继日志中的日志,把更改应用到自己的数据库,达到数据最终一致性。

    docker-compose搭建主从复制架构


    镜像名称 内外端口 容器名称
    mysql:8.0.29 3389:3306 mysql-master
    mysql:8.0.29 3379:3306 mysql-slave
    1. 编写docker-compose文件:
    version: "3"
    services:
       mysql-master:
         image: mysql:8.0.29
         ports:
           - 3389:3306
         volumes:
           - /home/mysql/master-slave/master/conf/:/etc/mysql/conf.d 
           - /home/mysql/master-slave/master/data/:/var/lib/mysql
           - /home/mysql/master-slave/master/log/:/var/log/mysql
         environment:
           MYSQL_ROOT_PASSWORD: spy1679358426
           MYSQL_DATABASE: sunpy-mysql
           MYSQL_USER: sunpy
           MYSQL_PASSWORD: spy1679358426
         restart: always
         container_name: mysql-master
       mysql-slave:
         image: mysql:8.0.29
         ports:
           - 3379:3306
         volumes:
           - /home/mysql/master-slave/slave/conf/:/etc/mysql/conf.d 
           - /home/mysql/master-slave/slave/data/:/var/lib/mysql
           - /home/mysql/master-slave/slave/log/:/var/log/mysql
         environment:
           MYSQL_ROOT_PASSWORD: spy1679358426
           MYSQL_DATABASE: sunpy-mysql
           MYSQL_USER: sunpy
           MYSQL_PASSWORD: spy1679358426
         restart: always
         container_name: mysql-slave
    
    1. 启动mysql编排容器:
    docker-compose -f mysql.yml up -d
    
    1. 配置my.cnf文件:
      这部分在我们的外部conf目录下配置就行了,因为我们挂载了外部文件夹。

    主:

    [mysqld]
    
    server-id=1
    log-bin=mysql-bin
    binlog_format=MIXED
    max_binlog_size = 124M
    expire_logs_days = 3
    binlog_ignore_db = mysql,performance_schema,information_schema,sys
    

    从:

    [mysqld]
    
    server_id = 2
    log_bin = mysql-bin
    binlog_format=MIXED
    max_binlog_size = 124M
    expire_logs_days = 3
    replicate-ignore-db=mysql,performance_schema,information_schema,sys
    relay_log_recovery = 1
    log_slave_updates = 1
    
    1. 查看主从状态:
    mysql> show master status;
    +------------------+----------+--------------+-------------------------------------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                                | Executed_Gtid_Set |
    +------------------+----------+--------------+-------------------------------------------------+-------------------+
    | mysql-bin.000068 |      157 |              | mysql,performance_schema,information_schema,sys |                   |
    +------------------+----------+--------------+-------------------------------------------------+-------------------+
    1 row in set (2.33 sec)
    
    1. change命令同步主从数据
    change master to 
    master_host='xxx.xx.xxx.xxx', 
    master_user='root', 
    master_password='xxxxx', 
    master_port=3389, 
    master_log_file='mysql-bin.000068',
    master_log_pos= 0, 
    master_connect_retry=30;
    
    1. 开启从库
    mysql> start slave;
    Query OK, 0 rows affected (0.44 sec)
    

    查看是否开启:

    验证:
    master库新增一条记录,slave库也会新增一条记录。

    问题思考:主从复制延迟


    思考:在测试的时候发现,主从复制并不是很快的,不会马上同步数据。
    问题:如果我们采取读写分离方式,那么主库数据写了一条记录。如果我们写完后,再从库去刷新数据列表记录,会发现记录还未同步过来。这种实时性要求比较高的时候该怎么办?

    • 第一种方案(消息队列替代从库查询):
      插入数据向消息队列生产消息的时候,将消息全部内容直接同步到消费者,消费者直接从消息队列获取消息,不用再重新查询从库了。
    • 第二种方案(存放到缓存):
      消费者直接从缓存查询,不查询从库了。注意:缓存与数据库可能存在数据不一致的情况
    • 第三种方案:
      直接查主库,那么主从复制也没啥意义了。

    问题思考:主从库数据不一致


    思考:主库新增数据成功,然后主库数据通过binlog同步的时候,发现binlog无法同步,造成主从库结果不一致。
    答:
    GTID方案,就是主库生成一个GTID标识,同当前记录一同写入到binlog中。从库将binlog日志写入到relay-log中。从relay-log中获取GTID,通过GTID获取从库中的binlog,如果有记录,说明GTID事务已执行。没有记录,那么从库会从 relay-log 中执行该 GTID 的事务,并记录到 binlog 中。

    mysql开启GTID:

    
    [mysqld]
    # 启用GTID
    gtid-mode=on        
    # 强制GTID的一致性                
    enforce-gtid-consistency=true       
    # slave更新是否记入日志(1表示记入、0表示不记入)
    log-slave-updates=1                 
    

    参考:
    https://blog.csdn.net/JohnnyG2000/article/details/124701214

    https://time.geekbang.org/column/article/145095?screen=full

    相关文章

      网友评论

          本文标题:mysql主从复制架构

          本文链接:https://www.haomeiwen.com/subject/nthegrtx.html