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实现对数据的访问和写入,简单架构如下:
I、环境介绍:
系统:CentOS6.4_x86_64
amoeba:amoeba2.2
mysql:mysql-5.6.13
JDK:jdk 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:
Skip_Counter: 0
Exec_Master_Log_Pos: 694
Relay_Log_Space: 982
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:6-7
Executed_Gtid_Set: 5f9e071b-3145-11e3-8426-000c2906a649:1-7
Auto_Position: 1
|
(5)、授权Mysql用户,用于实现前端amoeba连接
1
|
mysql> GRANT ALL ON *.* TO 'root' @ '%' IDENTIFIED BY 'mypass' ;
|
(6)、配置amoeba服务
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
#############配置文件############## [root@node ~] # cd /usr/local/amoeba/conf/
#############定义数据库读写分离及节点管理信息######## [root@node conf] # vim amoeba.xml
?xml version= "1.0" encoding= "gbk" ?>
<!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd" >
<amoeba:configuration xmlns:amoeba= "http://amoeba.meidusa.com/" >
<proxy> #定义代理
<!-- service class must implements com.meidusa.amoeba.service.Service --> <service name= "Amoeba for Mysql" class= "com.meidusa.amoeba.net.ServerableConnectionManager" > #定义服务,由类实现
<!-- port --> #定义连接池
<property name= "port" >3306< /property > #定义监听端口,将默认改动为3306
<!-- bind ipAddress --> #定义代理服务器对外连接的监听IP
<!--
<property name= "ipAddress" >127.0.0.1< /property >
-->
<property name= "ipAddress" >0.0.0.0< /property > #定义监听IP地址,这里定义为监听所有IP
<property name= "manager" >${clientConnectioneManager}< /property >
<property name= "connectionFactory" > #连接池
<bean class= "com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory" >
<property name= "sendBufferSize" >128< /property > #定义发送缓冲大小(可根据主机内存可调整)
<property name= "receiveBufferSize" >64< /property > #定义接受缓冲的大小(可根据主机内存可调整)
< /bean >
< /property >
<property name= "authenticator" > #认证器
<bean class= "com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator" >
<property name= "user" >root< /property > #通过客户端连接后端时的用户名
<property name= "password" >mypass< /property > #通过客户端连接后端时的密码
<property name= "filter" >
<bean class= "com.meidusa.amoeba.server.IPAccessController" >
<property name= "ipFile" >${amoeba.home} /conf/access_list .conf< /property > #只允许哪些客户端访问,基于文件实现访问控制
< /bean >
< /property >
< /bean >
< /property >
< /service >
<!-- server class must implements com.meidusa.amoeba.service.Service --> <service name= "Amoeba Monitor Server" class= "com.meidusa.amoeba.monitor.MonitorServer" > #amoeba的监控服务器,监测每一个后端的工作状态
<!-- port --> <!-- default value: random number <property name= "port" >3306< /property > #监控服务器监听的端口,默认注释表示使用随机端口
-->
<!-- bind ipAddress --> <property name= "ipAddress" >127.0.0.1< /property > #定义监控服务器监听的地址
<property name= "daemon" > true < /property >
<property name= "manager" >${clientConnectioneManager}< /property >
<property name= "connectionFactory" >
<bean class= "com.meidusa.amoeba.monitor.net.MonitorClientConnectionFactory" >< /bean >
< /property >
< /service >
<runtime class= "com.meidusa.amoeba.mysql.context.MysqlRuntimeContext" >
<!-- proxy server net IO Read thread size --> <property name= "readThreadPoolSize" >20< /property >
<!-- proxy server client process thread size -->
<property name= "clientSideThreadPoolSize" >30< /property >
<!-- mysql server data packet process thread size -->
<property name= "serverSideThreadPoolSize" >30< /property >
<!-- per connection cache prepared statement size -->
<property name= "statementCacheSize" >500< /property >
<!-- query timeout( default: 60 second , TimeUnit:second) -->
<property name= "queryTimeout" >60< /property >
< /runtime >
< /proxy >
<!-- Each ConnectionManager will start as thread
manager responsible for the Connection IO read , Death Detection
--> <connectionManagerList> #定义连接池的列表
<connectionManager name= "clientConnectioneManager" class= "com.meidusa.amoeba.net.MultiConnectionManagerWrapper" >
<property name= "subManagerClassName" >com.meidusa.amoeba.net.ConnectionManager< /property >
<!-- default value is avaliable Processors <property name= "processors" >5< /property >
-->
< /connectionManager >
<connectionManager name= "defaultManager" class= "com.meidusa.amoeba.net.MultiConnectionManagerWrapper" >
<property name= "subManagerClassName" >com.meidusa.amoeba.net.AuthingableConnectionManager< /property >
<!--
default value is avaliable Processors
<property name= "processors" >5< /property >
-->
< /connectionManager >
< /connectionManagerList > #连接池的列表
<!-- default using file loader -->
<dbServerLoader class= "com.meidusa.amoeba.context.DBServerConfigFileLoader" >
<property name= "configFile" >${amoeba.home} /conf/dbServers .xml< /property >
< /dbServerLoader >
<queryRouter class= "com.meidusa.amoeba.mysql.parser.MysqlQueryRouter" > #定义查询路由
<property name= "ruleLoader" >
<bean class= "com.meidusa.amoeba.route.TableRuleFileLoader" >
<property name= "ruleFile" >${amoeba.home} /conf/rule .xml< /property >
<property name= "functionFile" >${amoeba.home} /conf/ruleFunctionMap .xml< /property >
< /bean >
< /property >
<property name= "sqlFunctionFile" >${amoeba.home} /conf/functionMap .xml< /property >
<property name= "LRUMapSize" >1500< /property >
<property name= "defaultPool" >node1< /property > #定义读写服务器,这里默认定义到主服务器上
<property name= "writePool" >node1< /property > #定义写服务器,若有多个用逗号隔开,这些服务器名来自于dbservers.xml
<property name= "readPool" >node2< /property > #定义读服务器
<property name= "needParse" > true < /property >
< /queryRouter >
< /amoeba :configuration>
###############定义连接后端Mysql服务器信息############ [root@node conf] # vim dbServers.xml
<?xml version= "1.0" encoding= "gbk" ?>
<!DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd" >
<amoeba:dbServers xmlns:amoeba= "http://amoeba.meidusa.com/" >
<!--
Each dbServer needs to be configured into a Pool,
If you need to configure multiple dbServer with load balancing that can be simplified by the following configuration:add attribute with name virtual = "true" in dbServer, but the configuration does not allow the element with name factoryConfig
such as 'multiPool' dbServer
-->
<dbServer name= "abstractServer" abstractive= "true" > #定义服务器,名字叫抽象服务器,支持抽象功能:公共属性的定义
<factoryConfig class= "com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory" >
<property name= "manager" >${defaultManager}< /property >
<property name= "sendBufferSize" >64< /property > #定义发送缓冲大小
<property name= "receiveBufferSize" >128< /property > #接受缓冲的大小
<!-- mysql port --> <property name= "port" >3306< /property > #监听的端口
<!-- mysql schema -->
<property name= "schema" > test < /property > #默认连接的数据库服务器
<!-- mysql user --> <property name= "user" >root< /property > #用户名
<!-- mysql password
<property name= "password" >redhat< /property > #后端服务器的密码,授权用户密码
-->
< /factoryConfig >
<poolConfig class= "com.meidusa.amoeba.net.poolable.PoolableObjectPool" >
<property name= "maxActive" >500< /property > #定义最大活动连接数
<property name= "maxIdle" >500< /property > #空闲连接数
<property name= "minIdle" >10< /property > #最少空闲连接数
<property name= "minEvictableIdleTimeMillis" >600000< /property >
<property name= "timeBetweenEvictionRunsMillis" >600000< /property >
<property name= "testOnBorrow" > true < /property >
<property name= "testOnReturn" > true < /property >
<property name= "testWhileIdle" > true < /property >
< /poolConfig >
< /dbServer >
<dbServer name= "node1" parent= "abstractServer" > #定义服务器,其父服务器就是上面的"abstractServer"继承其属性,若不想请添加属性实现定义
<factoryConfig>
<!-- mysql ip -->
<property name= "ipAddress" >192.168.18.1< /property > #server1的IP地址
< /factoryConfig >
< /dbServer >
<factoryConfig>
<!-- mysql ip -->
<property name= "ipAddress" >192.168.18.2< /property >
< /factoryConfig >
< /dbServer >
<dbServer name= "multiPool" virtual= "true" > #定义虚拟服务器组
<poolConfig class= "com.meidusa.amoeba.server.MultipleServerPool" >
<!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> #算法:1表示轮询,2:基于权重做轮询,3:高可用效果
<property name= "loadbalance" >1< /property > #还可以实现负载均衡,算法为1
<!-- Separated by commas,such as: server1,server2,server1 -->
<property name= "poolNames" >node1,node2< /property > #此处一定是定义的dbname
< /poolConfig >
< /dbServer >
< /amoeba :dbServers>
|
(7)、启动amoeba服务:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
###########启动############# [root@node conf] # amoeba start
log4j:WARN log4j config load completed from file : /usr/local/amoeba/conf/log4j .xml
2013-09-27 10:01:48,419 INFO context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.2.0 #检测后端mysql服务器兼容版本
log4j:WARN ip access config load completed from file : /usr/local/amoeba/conf/access_list .conf
2013-09-27 10:01:49,622 INFO net.ServerableConnectionManager - Amoeba for Mysql listening on /0 .0.0.0:3306. #监听地址及端口
2013-09-27 10:01:49,701 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on /127 .0.0.1:10540. #管理地址及端口(随机)
##########停止amoeba########### ctrl+C #########使用后端启动########## [root@node conf] # amoeba start &
#########后端启动服务时停止#### [root@node conf] # amoeba stop
###########查看监听端口######## [root@node ~] # ss -tanl
State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 ::ffff:127.0.0.1:10540 :::* LISTEN 0 128 :::111 :::* LISTEN 0 128 :::3306 :::* |
(8)、连接测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[root@node ~] # yum -y install mysql
[root@node ~] # mysql -uroot -h172.16.18.6 -pmypass
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1516725303 #mysql随机ID号
Server version: 5.1.45-mysql-amoeba-proxy-2.2.0 MySQL Community Server (GPL) #代理服务器amoeba
Copyright (c) 2000, 2012, Oracle and /or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and /or its
affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> #连接成功
mysql> select version(); #查看Mysql版本
+------------+ | version() | +------------+ | 5.6.13-log | #显示为后端Mysql版本,说明已发往后端服务器执行了
+------------+ |
(9)、使用抓包工具辨别读写分离:
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
|
############使用客户端登陆############ [root@node ~] # mysql -uroot -h172.16.18.6 -pmypass
mysql> select User,Host from mysql.user;
+--------+------------------+ | User | Host | +--------+------------------+ | root | % | | rpuser | % | | root | 127.0.0.1 | | root | ::1 | | | localhost | | root | localhost | | | node2.magedu.com | | root | node2.magedu.com | +--------+------------------+ mysql> create database yong; ##################写服务器抓包######### [root@node1 ~] # tcpdump -i eth0 -s0 -nn -A tcp dst port 3306 and dst host 192.168.18.1
tcpdump: verbose output suppressed, use - v or -vv for full protocol decode
listening on eth0, link- type EN10MB (Ethernet), capture size 65535 bytes
22:26:40.881799 IP 192.168.18.254.55994 > 192.168.18.1.3306: Flags [P.], seq 107527731:107527750, ack 3858840995, win 601, options [nop,nop,TS val 71049923 ecr 84850364], length 19
E..G..@.@................h.3..=....Y....... .<"..........show databases #也是可以默认简单收到读请求
22:26:40.913496 IP 192.168.18.254.55994 > 192.168.18.1.3306: Flags [.], ack 189, win 638, options [nop,nop,TS val 71049955 ecr 84875929], length 0 E..4..@.@................h.F..>_...~.s..... .<"..... 22:28:03.775063 IP 192.168.18.254.55994 > 192.168.18.1.3306: Flags [P.], seq 19:44, ack 189, win 638, options [nop,nop,TS val 71132817 ecr 84875929], length 25
E..M..@.@................h.F..>_...~{...... .=f..........create database yong #抓取的写命令
22:28:03.858065 IP 192.168.18.254.55994 > 192.168.18.1.3306: Flags [.], ack 200, win 638, options [nop,nop,TS val 71132900 ecr 84958874], length 0 E..4..@.@................h._..>j...~.K..... .=f...^. 22:28:03.862318 IP 192.168.18.2.48893 > 192.168.18.1.3306: Flags [.], ack 3171025205, win 758, options [nop,nop,TS val 84900440 ecr 84958875], length 0 E..4.*@.@.~>...............`...5.....K..... ..zX..^. ##################读服务器上############## [root@node2 ~] # tcpdump -i eth0 -s0 -nn -A tcp dst port 3306 and dst host 192.168.18.2
tcpdump: verbose output suppressed, use - v or -vv for full protocol decode
listening on eth0, link- type EN10MB (Ethernet), capture size 65535 bytes
22:26:32.621522 IP 192.168.18.254.34032 > 192.168.18.2.3306: Flags [P.], seq 174032882:174032919, ack 3891257330, win 457, options [nop,nop,TS val 71041301 ecr 84656394], length 37
E..Y.2@.@............... _...........V..... .<..... !.... select @@version_comment limit 1
22:26:32.622271 IP 192.168.18.254.34032 > 192.168.18.2.3306: Flags [.], ack 100, win 457, options [nop,nop,TS val 71041302 ecr 84808840], length 0 E..4.3@.@..?............ _.....U.....$..... .<...... 22:27:28.160838 IP 192.168.18.254.34032 > 192.168.18.2.3306: Flags [P.], seq 37:74, ack 100, win 457, options [nop,nop,TS val 71096840 ecr 84808840], length 37
E..Y.4@.@............... _.....U........... .<......!.... select User,Host from mysql.user #抓取的查询命令
22:27:28.384028 IP 192.168.18.254.34032 > 192.168.18.2.3306: Flags [.], ack 355, win 490, options [nop,nop,TS val 71097064 ecr 84864602], length 0 E..4.5@.@..=............ _.<...T.....:..... .<.....Z |
至此,使用amoeba实现读写分离试验就结束了,有错误不足之处欢迎指正留言,笔者将尽最大努力帮你排忧解惑。更多其他内容请关注后续博文,更多关于amoeba的内容请参考http://docs.hexnova.com/amoeba/,谢谢!!
本文转自 z永 51CTO博客,原文链接:http://blog.51cto.com/pangge/1308235