mysql5.6主从复制与基于amoeba实现读写分离

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:





Mysql5.6主从复制

1、特性分析说明:

mysql 5.6支持多线程复制的机制并且mysql 5.6还引用了GTID的概念,使得其复制功能的配置、监控及管理变得更加易于实现,且更加健壮。

TID:事务的ID号:也就是说在mysql复制中每一个事务都有自己的ID号(随机数)

GTID:全局事务ID,在整个事务架构中每一个事务ID号是唯一的,不止是在一个节点上而是整个主从复制架构中每任何两个事务的ID号都不会相同的,这就是全局事务ID。

全局事务ID是怎么生成的?简单来讲是由mysql服务器自动管理的,在mysql5.6以后每一个mysql服务器都有一个全局唯一的ID号叫做uuid,而GTID就是由当前节点的UUID(一个128位的随机数)和为当前节点生成的随机数(TID)组成的,因此只要UUID不同再在此基础上保证事务ID不同就保证全局不一样了。

全局事务ID有何用处?简单来讲GTID能够保证让一个从服务器到其他的从服务器哪里实现数据复制而且能够实现数据整合的。GTID在分布式架构中可以保证数据的一致性。从而也实现了mysql的高可用性。

GTID相关操作:默认情况下将一个事务记录进二进制文件时将首先记录它的GTID而且GTID和事务相关信息一并要发送给从服务器由从服务器在在本地应用认证但是绝对不会改变原来的事务ID号。

因此在GTID的架构上就算有了N层架构,复制是N级架构、事务ID依然不会改变;有效的保证了数据的完整和安全性。

小拓展

用于提升主从架构效率第三方工具

mysqlreplicate:用于实现快速启动从服务器的,就是若原来的主节点A出现故障了原来的从节点B会转换成主节点,而原来的从节点C会转移到主节点B上进行复制但是其中的二进制日志的内容有可能不同,所以这个软件会自己检测那些应用过哪些未应用然后在本地应用最后实现快速启动。

mysqlrplcheck:用来校验mysql主从复制架构中所有节点上数据是否一致、某些节点是否启动二进制日志的等等也就是说在将某个服务器提升为主节点时实现快速检测的功能的

mysqlrplshow:用来显示拓扑架构的,当前服务器中某一个从服务器是一个主服务器还是一个从服务器等等从而实现快速显示。

mysqlfailover:故障转移,快速的将一个从服务器提升为一个主服务器,可以手动提升也可以自动提升,在提升之前尽量先校验一下数据。

mysqlrpladmin:快速一个从服务器切换为主将原来主服务器下线进行维护备份操作。

2、配置基于GTID主从复制:

I、环境介绍:

主节点:[root@node1 ~]:172.16.18.1

从节点:[root@node2 ~]: 172.16.18.2

II、安装mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#############主节点安装mysql:###########
[root@node1 ~] #tar xf mysql-5.6.13-linux-glibc2.5-x86_64.tar.gz -C /usr/local
[root@node1 ~] #cd /usr/local
[root@node1 ~] #ln -sv mysql-5.6.13-linux-glibc2.5-x86_64 mysql
[root@node1 ~] #cd mysql
[root@node1 ~] #useradd mysql -r
[root@node1 ~] #chown root.mysql *
[root@node1 ~] #mkdir /mydata/data -pv
[root@node1 ~] #chown mysql.mysql /mydata/data
[root@node1 ~] #scp /etc/my.cnf 172.16.18.1:/etc/my.cnf    #由于mysql5.6上配置文件需要自动书写,但是为了节约时间笔者从安装了mysql-5.5.33的服务器上复制了。
[root@node1 ~] #scripts/mysql_install_db --user=mysql --datadir=/mydata/data
[root@node1 ~] #cp support-files/mysql.server /etc/rc.d/init.d/mysqld
[root@node1 ~] #chmod +x /etc/rc.d/init.d/mysqld
[root@node1 ~] #vim /etc/my.cnf
     datadir =  /mydata/data
[root@node1 ~] #vim /etc/profile.d/mysql.sh
     export  PATH= /usr/local/mysql/bin :$PATH
[root@node1 ~] #. /etc/profile.d/mysql.sh
[root@node1 ~] #chkconfig --add mysqld
[root@node1 ~] #service mysqld start
#############从节点:###################
[root@node2 ~] #tar xf mysql-5.6.13-linux-glibc2.5-x86_64.tar.gz -C /usr/local
[root@node2 ~] #cd /usr/local
[root@node2 ~] #ln -sv mysql-5.6.13-linux-glibc2.5-x86_64 mysql
[root@node2 ~] #cd mysql
[root@node2 ~] #useradd mysql -r
[root@node2 ~] #chown root.mysql *
[root@node2 ~] #mkdir /mydata/data -pv
[root@node2 ~] #chown mysql.mysql /mydata/data
[root@node2 ~] #scripts/mysql_install_db --user=mysql --datadir=/mydata/data
[root@node2 ~] #cp support-files/mysql.server /etc/rc.d/init.d/mysqld
[root@node2 ~] #chmod +x /etc/rc.d/init.d/mysqld
[root@node2 ~] #vim /etc/my.cnf
   datadir =  /mydata/data
[root@node2 ~] #vim /etc/profile.d/mysql.sh
     export  PATH= /usr/local/mysql/bin :$PATH
[root@node2 ~] #. /etc/profile.d/mysql.sh
[root@node2 ~] #chkconfig --add mysqld
[root@node2 ~] #service mysqld start

III、配置读写分离:

(1)、主节点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@node1 ~] #vim /etc/my.cnf
  [mysqld]
    binlog_format=row                 #原配置文件中存在需改动
    server- id        = 1               #原配置文件中存在
    log-slave-updates= true            #添加以下这些选项
    gtid-mode=on     
    enforce-gtid-consistency= true
    master-info-repository=TABLE
    relay-log-info-repository=TABLE
    sync -master-info=1
    slave-parallel-workers=4
    binlog-checksum=CRC32
    master-verify-checksum=1
    slave-sql-verify-checksum=1
    binlog-rows-query-log_events=1
    report-port=3306
    report-host=node1.magedu.com
###########保存退出重启##########

选项解析

binlog-format:二进制日志的格式,有row、statement和mixed三种类型;需要注意的是:当设置隔离级别为READ-COMMITED必须设置二进制日志格式为ROW,现在MySQL官方认为STATEMENT这个已经不再适合继续使用;但mixed类型在默认的事务隔离级别下,可能会导致主从数据不一致;

log-bin:启用二进制日志

server-id:同一个复制拓扑中的所有服务器的id号必须惟一;

log-slave-updates:slave更新时是否记录到日志中;

gtid-mode:指定GTID的类型,否则就是普通的复制架构

enforce-gtid-consistency:是否强制GTID的一致性

report-port:产生复制报告时在哪个端口上提供相关功能

report-host:产生复制报告时在哪个主机上提供相关功能,一般为自己的主机名

master-info-repository和relay-log-info-repository:启用此两项,可用于实现在崩溃时保证二进制及从服务器安全的功能;

sync-master-info:启用之可确保服务器崩溃时无信息丢失;

slave-paralles-workers:设定从服务器启动几个SQL复制线程数;0表示关闭多线程复制功能;数字太大也无意义最好与要复制的数据库的数目相同

binlog-checksum:复制时是否校验二进制文件的完整性等相关功能;binlog的校验格式校验算法(CRC32:循环冗余校验码32位)

master-verify-checksum:检验主服务器二进制日志的相关功能

slave-sql-verify-checksum:校验从服务器中继日志的相关功能的

binlog-rows-query-log-events:启用之可用于在二进制日志详细记录事件相关的信息,可降低故障排除的复杂度;

1
2
3
4
5
6
7
8
9
10
11
12
##########复制配置文件至从节点######
[root@node1 ~] #scp /etc/my.cnf 172.16.18.2:/etc/my.cnf
##########创建复制用户##############
mysql> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO rpuser@ '%'  IDENTIFIED BY  'rppass' ;
mysql> FLUSH PRIVILEGES;
##########查看UUID##################
mysql> show global variables like  '%UUID%' ;
+---------------+--------------------------------------+
| Variable_name | Value                                |
+---------------+--------------------------------------+
| server_uuid   | 5f9e071b-3145-11e3-8426-000c2906a649 |
+---------------+--------------------------------------+

(2)、从节点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
############修改配置文件##########
[root@node2 ~] #vim /etc/my.cnf
    server- id        = 10
    report-host=node2.magedu.com
保存退出重启
###########连接主服务器###########
mysql> CHANGE MASTER TO MASTER_HOST= '172.16.18.1' , MASTER_USER= 'rpuser' , MASTER_PASSWORD= 'rppass' , MASTER_AUTO_POSITION=1;
###########启动从服务器##########
mysql> start slave;
##########查看复制连接###########
mysql> show slave status\G
*************************** 1. row ***************************
                Slave_IO_State: Waiting  for  master to send event
                   Master_Host: 172.16.18.1
                   Master_User: rpuser
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: mysql-bin.000004
           Read_Master_Log_Pos: 546
                Relay_Log_File: node2-relay-bin.000002
                 Relay_Log_Pos: 756
         Relay_Master_Log_File: mysql-bin.000004
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
               Replicate_Do_DB:
           Replicate_Ignore_DB:
            Replicate_Do_Table:
        Replicate_Ignore_Table:
       Replicate_Wild_Do_Table:
   Replicate_Wild_Ignore_Table:
                    Last_Errno: 0
                    Last_Error:
                  Skip_Counter: 0
           Exec_Master_Log_Pos: 546
               Relay_Log_Space: 960
               Until_Condition: None
                Until_Log_File:
                 Until_Log_Pos: 0
            Master_SSL_Allowed: No
            Master_SSL_CA_File:
            Master_SSL_CA_Path:
               Master_SSL_Cert:
             Master_SSL_Cipher:
                Master_SSL_Key:
         Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                 Last_IO_Errno: 0
                 Last_IO_Error:
                Last_SQL_Errno: 0
                Last_SQL_Error:
   Replicate_Ignore_Server_Ids:
              Master_Server_Id: 1
                   Master_UUID: 5f9e071b-3145-11e3-8426-000c2906a649
              Master_Info_File: mysql.slave_master_info
                     SQL_Delay: 0
           SQL_Remaining_Delay: NULL
       Slave_SQL_Running_State: Slave has  read  all relay log; waiting  for  the slave I /O  thread to update it
            Master_Retry_Count: 86400
                   Master_Bind:
       Last_IO_Error_Timestamp:
      Last_SQL_Error_Timestamp:
                Master_SSL_Crl:
            Master_SSL_Crlpath:
            Retrieved_Gtid_Set: 5f9e071b-3145-11e3-8426-000c2906a649:1-2
             Executed_Gtid_Set: 5f9e071b-3145-11e3-8426-000c2906a649:1-2
                 Auto_Position: 1

IV、查看基于GTID复制连接状况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
###########主节点:################
mysql> show processlist;
+----+--------+-------------------+------+------------------+------+-----------------------------------------------------------------------+------------------+
| Id | User   | Host              | db   | Command          | Time | State                                                                 | Info             |
+----+--------+-------------------+------+------------------+------+-----------------------------------------------------------------------+------------------+
|  4 | root   | localhost         | NULL | Query            |    0 | init                                                                  | show processlist |
|  5 | rpuser | 172.16.18.2:40574 | NULL | Binlog Dump GTID | 1201 | Master has sent all binlog to slave; waiting  for  binlog to be updated | NULL             |
+----+--------+-------------------+------+------------------+------+-----------------------------------------------------------------------+------------------+
#############从节点:#################
mysql> show processlist;
+----+-------------+-----------+------+---------+-------+-----------------------------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time  | State                                                                       | Info             |
+----+-------------+-----------+------+---------+-------+-----------------------------------------------------------------------------+------------------+
|  1 | root        | localhost | NULL | Sleep   | 45572 |                                                                             | NULL             |
|  8 | root        | localhost | NULL | Query   |     0 | init                                                                        | show processlist |
|  9 | system user |           | NULL | Connect |  1394 | Waiting  for  master to send event                                            | NULL             |
| 10 | system user |           | NULL | Connect |  1392 | Slave has  read  all relay log; waiting  for  the slave I /O  thread to update it | NULL             |
| 11 | system user |           | NULL | Connect |  1394 | Waiting  for  an event from Coordinator                                       | NULL             |
| 12 | system user |           | NULL | Connect |  1394 | Waiting  for  an event from Coordinator                                       | NULL             |
| 13 | system user |           | NULL | Connect |  1394 | Waiting  for  an event from Coordinator                                       | NULL             |
| 14 | system user |           | NULL | Connect |  1433 | Waiting  for  an event from Coordinator                                       | NULL             |
+----+-------------+-----------+------+---------+-------+-----------------------------------------------------------------------------+------------------+

V、测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
###########主节点:#############
mysql> create database hellodb;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hellodb            |
| mysql              |
| performance_schema |
test                |
+--------------------+
###########从节点:#############
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hellodb            |
| mysql              |
| performance_schema |
test                |
+--------------------+


至此基于GTID的主从复制配置就完成了,关于单点故障模拟实现转移这里就不演示了,若有需要请参考:http://dev.mysql.com/doc/workbench/en/mysqlfailover.html


利用amoeba实现mysql读写分离

1、基本知识概述

Amoeba(变形虫):该开源框架于2008年 开始发布一款 Amoeba for Mysql软件。这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的 时候充当SQL路由功能,专注于分布式数据库代理层(Database Proxy)开发。座落与 Client、DB Server(s)之间,对客户端透明。具有负载均衡、高可用性、SQL 过滤、读写分离、可路由相关的到目标数据库、可并发请求多台数据库合并结果。它运行于JVM上,是淘宝公司前期的一个工程师研发的。国人也非常喜欢,其受人拥戴的原因是部署简单并且由于是java开发也可以运行在windows平台上,其缺点就是对事务功能支持很差,尤其是不支持分布式事务。默认监听在8066端口上。

2、模拟部署amoeba实现读写分离:

思路:假设有两台Mysql服务器一主一从都工作在内网中,而用户可以通过amoeba实现对数据的访问和写入,简单架构如下:

194258131.jpg

I、环境介绍:

系统:CentOS6.4_x86_64

amoebaamoeba2.2

mysqlmysql-5.6.13

JDKjdk 1.6

II、部署过程:

(1)、配置IP地址:

1
2
3
4
5
6
7
8
9
#########前端amoeba服务器############
[root@node ~] #ifconfig eth0 172.16.18.6
[root@node ~] # ifconfig eth1 192.168.18.254/24
#########Mysql A(写服务器)#########
Ifconfig eth0 192.168.18.1 /24
route add default gw 192.168.18.254
#########Mysql B(读服务器)#########
Ifconfig eth0 192.168.18.2 /24
route add default gw 192.168.18.254

(2)、安装JAVA程序:

由于amoeba是基于JVM运行的所以要想配置JAVA程序:

官方amoeba2.2的版本只测试与java1.6的程序包完美结合实现稳定工作

1
2
3
4
5
6
7
8
9
10
[root@node ~] # chmod +xjdk-6u31-linux-x64-rpm.bin     #赋予执行权限
[root@node ~] # ./jdk-6u31-linux-x64-rpm.bin           #执行此文件安装
[root@node ~] # vim/etc/profile.d/java.sh              #编辑执行脚本
    export  JAVA_HOME= /usr/java/latest
    export  PATH=$JAVA_HOME /bin :$PATH
[root@node ~] # . /etc/profile.d/java.sh                #读取执行脚本
[root@node ~] # java –version                          #查看安装信息
java version  "1.6.0_31"
Java(TM) SE Runtime Environment (build1.6.0_31-b04)
Java HotSpot(TM) 64-Bit Server VM (build20.6-b01, mixed mode)

(3)、解压安装amoeba

1
2
3
4
5
6
7
8
9
10
11
12
###########创建目录############
[root@node ~] # mkdir -pv/usr/local/amoeba-2.2.0          #保留版本信息便于后期识别
###########解压################
[root@node ~] # tar xfamoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba-2.2.0
###########链接################
[root@node  local ] # ln -sv amoeba-2.2.0/ amoeba
###########编辑执行脚本########
[root@node conf] # vim /etc/profile.d/amoeba.sh
export  AMOEBA_HOME= /usr/local/amoeba
export  PATH=$AMOEBA_HOME /bin :$PATH
###########读取执行脚本服务####
[root@node conf] # . /etc/profile.d/amoeba.sh

(4)、配置mysql服务器:

这里依然使用上面的主从复制环境:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
##########停止复制#######
mysql> stop slave;
##########连接主服务器###########
mysql> CHANGE MASTER TO MASTER_HOST= '192.168.18.1' , MASTER_USER= 'rpuser' , MASTER_PASSWORD= 'rppass' , MASTER_AUTO_POSITION=1;
##########启动###########
mysql> start slave;
##########查看###########
mysql> show slave status\G
*************************** 1. row ***************************
                Slave_IO_State: Waiting  for  master to send event
                   Master_Host: 192.168.18.1
                   Master_User: rpuser
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: mysql-bin.000005
           Read_Master_Log_Pos: 694
                Relay_Log_File: node2-relay-bin.000002
                 Relay_Log_Pos: 778
         Relay_Master_Log_File: mysql-bin.000005
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
               Replicate_Do_DB:
           Replicate_Ignore_DB:
            Replicate_Do_Table:
        Replicate_Ignore_Table:
       Replicate_Wild_Do_Table:
   Replicate_Wild_Ignore_Table:
                    Last_Errno: 0
                    Last_Error: