MySQL主从复制:半同步、异步

        MySQL主从复制:半同步、异步


mysql

    前言

    本篇我们介绍MySQL Replication的相关内容, 我们首先介绍MySQL CLuster的实现原理和如何一步步构建一个MySQL Replication Cluster

    看懂本文需要了解: MySQL基本操作,MySQL日志类型及其作用

    如何对MySQL进行扩展?

    大家之前应该了解; 在单台服务器性能不足时, 有两种方式进行扩展

    • Scale Up ; 垂直扩展

    • Scale Out ; 水平扩展

      垂直扩展: 指的是提升单台服务器的性能(硬件)来提升服务的性能 
      水平扩展: 指的是添加服务器通过负载均衡的方式来分担单台服务器的负载, 从而提升服务的性能

    我们可以通过LVS, HAProxy, Nginx等软件实现一些服务的负载均衡, 但是如果要用到MySQL上就会有一些问题, 如下

    • 如何保证多台MySQL服务器数据的一致性

    • 如何保证多台服务器同时提交事务导致数据的完整性

    • 如何保证一台服务器宕机时, 其的事务能够正常提交或ROLLBACK

    我们需要考虑的问题比扩展WEB服务多太多了, 毕竟大家都知道, 数据无价, 在很多重要场景中, 数据不能有半点闪失, 但是MySQL对这方面做得并不是很好, 而Oracle数据库在这方面特别的厉害, 所以众多的银行都采用Oracle数据库存储客户的账户信息等, 这么说, 难道我们就不用MySQL了么? 这显然不可能, 我们首先来介绍一下MySQL Replication Cluster的几种同步数据方式

    • Synchronous Replication 同步复制

    • Asynchronous Replication 异步复制

    • Semisynchronous Replication 半同步复制

      同步复制: 指的是客户端连接到MySQL主服务器写入一段数据, MySQL主服务器同步给MySQL从服务器需要等待从服务器发出同步完成的响应才返回客户端OK, 这其中等待同步的过程是阻塞的, 如果有N台从服务器, 效率极低 
      异步复制: 指的是客户端连接到
      MySQL主服务器写入一段数据, MySQL主服务器将写入的数据发送给MySQL从服务器, 然后直接返回客户端OK, 可能从服务器的数据会和主服务不一致 
      半同步复制:指的是客户端连接到
      MySQL主服务器写入一段数据, MySQL主服务器只将数据同步复制给其中一台从服务器, 半同步复制给其他的从服务器, 来达到其中一台从服务器完全同步的效果

    MySQL Replication WorkFlow

    Master/Slave工作流程

    blob.png

    建立主从关系后, 主服务器如果有数据修改之后, BINLOG会更新, 从服务通过IO-Thread读取主服务器的BINLOG到本地的Relay Log, 再通过SQL-Thread对其进行重放(replay), 从而同步到本地

    MySQL主从复制模式

    在不同的业务模型中我们可以采用不同的MySQL主从复制架构, 一般分为以下两种

    • Master/Slave

    • Master/Master

      Master/Slave: 指的是一主多从模式, 这种模式下可以有效的分担读请求, 但是写请求并不能完成负载分担、从节点可能数据不一致, 并且如果Master宕机了客户端就无法进行写操作了, 还是有很多问题的 
      Master/Master: 指的是多主模式, 这种模式中的多台
      MySQL服务器都是Master, 也就意味着都可以进行读写操作, 但是有着更为严重的问题, 多个客户端同时写入数据时由于复制延迟可能到导致数据冲突等严重问题

    常用的架构图

    我们可以使用keepalived实现Master高可用, 并且使用半同步模式实现数据的完全同步

    blob.png

    上面那种方式太占用Master的带宽, 我们可以让一台Slave扮演为Master, 为其他Slave同步数据

    blob.png

    实战演练

    MySQL异步复制实现

    实验拓扑

    blob.png

    环境部署

    我们需要在各台服务器上安装MySQL, 这里使用的是rpm包安装, 版本为5.1

    [root@node1 ~]# yum install mysql-server -y
    [root@node2 ~]# yum install mysql-server -y
    [root@node3 ~]# yum install mysql-server -y

    配置文件

    node1配置文件(master)

       [mysqld]
       datadir=/var/lib/mysql
       socket=/var/lib/mysql/mysql.sock
       user=mysql
       # Disabling symbolic-links is recommended to prevent assorted security risks
       symbolic-links=0
       innodb_file_per_table = 1
       log_bin=master-log    #开启二进制日志
       log_bin_index=1
       server_id=1           #设置serverid

       [mysqld_safe]
       log-error=/var/log/mysqld.log
       pid-file=/var/run/mysqld/mysqld.pid

    node2配置文件(slave1)

       [mysqld]
       datadir=/var/lib/mysql
       socket=/var/lib/mysql/mysql.sock
       user=mysql
       # Disabling symbolic-links is recommended to prevent assorted security risks
       symbolic-links=0
       relay-log=relay-log         #开启relay日志
       innodb_file_per_table = 1
       read-only = 1               #设置只读
       server_id = 2               #设置serverid

       [mysqld_safe]
       log-error=/var/log/mysqld.log
       pid-file=/var/run/mysqld/mysqld.pid

    node3配置文件(slave2)

       [mysqld]
       datadir=/var/lib/mysql
       socket=/var/lib/mysql/mysql.sock
       user=mysql
       # Disabling symbolic-links is recommended to prevent assorted security risks
       symbolic-links=0
       relay-log=relay-log
       innodb_file_per_table = 1
       read-only = 1
       server_id = 3

       [mysqld_safe]
       log-error=/var/log/mysqld.log
       pid-file=/var/run/mysqld/mysqld.pid


    ##启动mysql
    ##注意: serverid一定不能相同

    配置Master

    Slave节点进行同步需要通过一个特定的用户进行, 所以我们需要创建一个用户并赋予REPLICATION SLAVE, REPLICATION CLIENT权限

    mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'rpuser'@'%' IDENTIFIED BY 'passwd';
    Query OK, 0 rows affected (0.00 sec)

    mysql> FLUSH PRIVILEGES;
    Query OK, 0 rows affected (0.00 sec)

    mysql> SHOW MASTER STATUS;   我们要记录下pos的数值
    +-------------------+----------+--------------+------------------+

    | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +-------------------+----------+--------------+------------------+

    | master-log.000005 |      523 |              |                  |
    +-------------------+----------+--------------+------------------+

    1 row in set (0.00 sec)

    配置Slave(1)

    mysql> CHANGE MASTER TO
       -> MASTER_HOST='172.16.1.2',
       -> MASTER_USER='rpuser',
       -> MASTER_PASSWORD='passwd',
       -> MASTER_LOG_FILE='master-log.000005',
       -> MASTER_LOG_POS=523;
    Query OK, 0 rows affected (0.01 sec

    mysql> SHOW SLAVE STATUS\G;  #查看相应信息
    #########省略##################
    Master_Log_File: master-log.000005
    Read_Master_Log_Pos: 523
    Relay_Log_File: relay-log.000001
    Relay_Log_Pos: 4
    Relay_Master_Log_File: master-log.000005
    Slave_IO_Running: No    #IO-thread没有启动
    Slave_SQL_Running: No   #SQL-thread没有启动
    ###
    ######省略##################

    mysql> START SLAVE;  #启动sql-thread和io-thred

    mysql> SHOW SLAVE STATUS\G;  #查看相应信息
    Query OK, 0 rows affected (0.00 sec)
    #########省略##################
    Master_Log_File: master-log.000005
    Read_Master_Log_Pos: 523
    Relay_Log_File: relay-log.000002
    Relay_Log_Pos: 252
    Relay_Master_Log_File: master-log.000005
    Slave_IO_Running: Yes     #IO-thread启动
    Slave_SQL_Running: Yes    #SQL-thread启动
    ###
    ######省略##################

    配置slave(2)

    过程和配置slave(1)相同, 不做演示

    测试主从复制


    ##在主服务器上创建数据库和表

    [root@node1 ~]# mysql

    mysql> SHOW DATABASES;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | test               |
    +--------------------+
    3 rows in set (0.00 sec)

    mysql> CREATE DATABASE replication;

    Query OK, 1 row affected (0.00 sec)

    mysql> USE replication;
    Database changed
    mysql> CREATE TABLE t1 (id int unsigned auto_increment primary key, name char(30));
    Query OK, 0 rows affected (0.01 sec)

    mysql> DESC t1;
    +-------+------------------+------+-----+---------+----------------+
    | Field | Type             | Null | Key | Default | Extra          |
    +-------+------------------+------+-----+---------+----------------+
    | id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | name  | char(30)         | YES  |     | NULL    |                |
    +-------+------------------+------+-----+---------+----------------+
    2 rows in set (0.00 sec)

    mysql> SHOW MASTER STATUS;

    +-------------------+----------+--------------+------------------+
    | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +-------------------+----------+--------------+------------------+
    | master-log.000005 |      765 |              |                  |
    +-------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    ##在slave服务器测试

    [root@node2 ~]# mysql

    mysql> SHOW DATABASES;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | replication        |
    | test               |
    +--------------------+
    4 rows in set (0.00 sec)

    mysql> use replication;

    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A

    Database changed
    mysql> DESC t1;
    +-------+------------------+------+-----+---------+----------------+
    | Field | Type             | Null | Key | Default | Extra          |
    +-------+------------------+------+-----+---------+----------------+
    | id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | name  | char(30)         | YES  |     | NULL    |                |
    +-------+------------------+------+-----+---------+----------------+
    2 rows in set (0.00 sec)

    mysql> SHOW SLAVE STATUS\G;


    #########省略##################
    Master_Log_File: master-log.000005
    Read_Master_Log_Pos: 765   #已经同步
    Relay_Log_File: relay-log.000002
    Relay_Log_Pos: 494
    Relay_Master_Log_File: master-log.000005
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    #########省略##################

    MySQL半同步复制实现

    由于MySQL半同步复制在MySQL5.5以后才以插件的形式进行提供, 所以这里我们的MySQL要换成5.5版本的MariaDB

    由于很多步骤和上面重复,我就不写出来了,先配置成M/S然后再按照我下面操作

    实验拓扑

    blob.png

    配置master

    半同步的插件在/usr/lib64/mysql/plugin下, master用的semisync_master.so,slave用的semisync_slave.so

    MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
    Query OK, 0 rows affected (0.00 sec)

    MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_enabled = 1;
    Query OK, 0 rows affected (0.00 sec)

    MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_timeout = 2000;   #设置超时时间为2S
    Query OK, 0 rows affected (0.00 sec)

    配置slave

    MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
    Query OK, 0 rows affected (0.00 sec)

    MariaDB [(none)]> SET GLOBAL rpl_semi_sync_slave_enabled=1;
    Query OK, 0 rows affected (0.00 sec)

    验证

    因为在我的环境中,即使是半同步复制,也是直接就完成,看不出效果,所以我们故意将slave节点关闭
    [root@node2 ~]# service mysql stop



    ##master创建数据库
    MariaDB [(none)]> CREATE DATABASE TEST3;
    Query OK, 1 row affected (2.00 sec)        #等待2s, 超时不再等待,直接创建

    MariaDB [(none)]> CREATE DATABASE TEST4;
    Query OK, 1 row affected (0.00 sec)


    ##完成,这个可能不是特别直观,但是由于我这边环境实在做不出效果,望大家理解

    实验中的思考

    • 如果主从服务器数据相差较大, 最好先使用主服务器的二进制日志在从服务器上replay一篇, 然后再进行同步

    总结

    这篇其实还打算写SSL复制的,但是因为时间比较紧,就没有写了,总体来说不是特别的满意,有很多地方没有说明白,还望大家谅解。

    作者水平很低, 如果有错误及时指出, 如果你觉得本文写的好请点一波赞~(≧▽≦)/~ 
    作者: AnyISaIln QQ: 1449472454 
    感谢: MageEdu

    原创文章,作者:Net18-AnyISalIn,如若转载,请注明出处:http://www.178linux.com/15679

    (0)
    Net18-AnyISalInNet18-AnyISalIn
    上一篇 2016-04-28 09:50
    下一篇 2016-04-28 19:51

    相关推荐

    • 第三周作业

      1、列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。 2、取出最后登录到当前系统的用户的相关信息。 3、取出当前系统上被用户当作其默认shell的最多的那个shell。 4、将/etc/passwd中的第三个字段数值最大的后10个用户的信息全部改为大写后保存 至/tmp/maxusers.txt文件中。 5、取出当前主机…

      Linux干货 2016-11-21
    • vsftpd

      vsftpd:     程序环境:         配置文件:/etc/vsftpd/vsftpd.conf         主程序:/usr/sbin/vsf…

      Linux干货 2016-12-05
    • heartbeat实现高可用集群(1)

      环境 node1 192.168.1.35 node2 192.168.1.36 fip 192.168.1.80 daemon httpd nfs 192.168.1.15 配置HA集群的前提 1.节点时间必须同步,使用ntp协议实现 2.节点间需要通过主机互相通信,必须解析主机名至IP地址 a.建议名称解析功能能使用hosts文件实现 b.通信中使用的名…

      Linux干货 2017-11-03
    • httpd 高级应用

      回顾:httpd, lamp, mysql httpd:https, mod_deflate, … httpd+php:三种结合方式     Module:         prefork:libphp5.so  &n…

      Linux干货 2016-11-01
    • 马哥教育网络班22期+第6周课程练习

      请详细总结vim编辑器的使用并完成以下练习题 vim: 模式化的编辑器 基本模式:     编辑模式:命令模式     输入模式:     未行模式:内置的命令行接口 打开文件:      …

      Linux干货 2016-09-26
    • bash脚本初探

                                (注)$@和$*的区别,以及$0..$n [root@ _6_ ~]# cat weizhi.sh  #!/bin/bash e…

      Linux干货 2016-08-15