Mysql 主从复制及读写分离
特别推荐看:amoeba.xml 的配置部分,在百度上看了很多配置都不完整,是我测试时的痛点
实验的目的:
有两部分:第一实现Mysql主从复制,第二实现读写分离。
下面是实验的环境:
192.168.58.11 安装了amoeba 的节点
192.168.58.16 master 系统:rhel 5.4
192.168.58.12 slave 系统: rhel 5.4
192.168.58.11 代理 系统:rhel 5.4
192.168.58.15 外部机器 系统:Centos7
. Mysql 数据库安装 见附件
安装过程省
见《Linux下安装和迁移MySQL5.6指南》
下面开始配置:
主从复制 由于图片无法正常显示,在附件中有完整图文模式
服务器 Master :192.168.58.16
Mysql 安装目录: /home/mysql/mysql
vi /etc/my.cnf
datadir=/home/mysql
socket=/var/lib/mysql/mysql.socket
服务器 Slave :192.168.58.12
Mysql 安装目录:/home/mysql/mysql
vi /etc/my.cnf
datadir= /home/mysql
socket=/home/mysql/mysql.socket
2. 修改配置文件
vi /etc/my.cnf
(官方说明:为了使用事务的InnoDB在复制中最大的持久性和一致性,你应该指定innodb_flush_log_at_trx_commit=1,sync_binlog=1选项。)
修改master:
/etc/my.cnf
1. log-bin=mysql-bin #slave会基于此log-bin来做replication
2. server-id=1 #master的标示
3.
4. innodb_flush_log_at_trx_commit=1
5.
6. sync_binlog=1
修改 slave
/etc/my.cnf
1. [mysqld]
2.
3. server-id=2 #slave的标示
master
ps -ef|grep mysql
service mysql start
slave :
ps -ef|grepmysql
service mysql start
4. 在 Master 上创建一个专门用于复制的账号密码: repl repl
mysql>create user ‘repl‘@‘%‘ identified by ‘repl‘;
mysql>grant replication slave on *.* to ‘repl‘;
mysql>flush privileges;
5. 启动主从复制功能
需要查看 Master 中的 Master status
mysql> show master status;
配置从服务器Slave:
mysql>change master tomaster_host=‘192.168.58.16‘,master_user=‘root‘,master_password=‘123456‘,
master_log_file=‘mysql-bin.000001‘,master_log_pos=120;
//注意不要断开,120数字前后无单引号。
Mysql>startslave; //启动从服务器复制功能
检查从服务器复制功能状态:
mysql> show slave status\G;
*************************** 1. row***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.58.16 //主服务器地址
Master_User: root //授权帐户名,尽量避免使用root
Master_Port: 3306 //数据库端口,部分版本没有此行
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 120 //#同步读取二进制日志的位置,大于等于Exec_Master_Log_Pos
Relay_Log_File: ddte-relay-bin.000003
Relay_Log_Pos: 251
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes //此状态必须YES
Slave_SQL_Running: Yes //此状态必须YES
......
注:Slave_IO及Slave_SQL进程必须正常运行,即YES状态,否则都是错误的状态(如:其中一个NO均属错误)。
以上操作过程,主从服务器配置完成。
下面开始配置:
读写分离 由于图片不能正常显示,在附件中有完整说明
JDK的安装
1)以root身份登录系统,将jdk-6u16-linux-x64.bin通过FTP工具上传到/usr/java目录,执行以下命令:
[[email protected] java]#chmod +x jdk-6u16-linux-x64.bin
[[email protected] localhost java]# ./jdk-6u16-linux-x64.bin
2)使用vi/etc/profile命令进入环境变量文件,设置环境变量(此处为所有用户创建统一的JDK,如果需要分别安装不同的版本,请修改当前用户目录下的.bash_profile):
JAVA_HOME=/usr/java/jdk1.6.0_16(其中jdk1.6.0_16是安装JDK后自动生成的)
PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$CLASSPATH
export PATH JAVA_HOME CLASSPATH
3)使配置生效:source /etc/profile
4) 到此,JDK安装完成,可键入命令查看JAVA版本:
[[email protected] localhost ~]# java–version
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) 64-Bit Server VM (build 14.2-b01, mixed mode)
出现上述信息表示安装完成。
4、 安装amoeba-mysql
下载amoeba-mysql,目前最新版本为amoeba-mysql-1.3.1-BETA.zip
mkdir /usr/local/amoeba/
wget http://blogimg.chinaunix.net/blog/upfile2/101027160252.zip
unzip 101027160252.zip
配置文件位于conf目录下,执行文件位于bin目录下,解压后发现bin目录下的启动文件没有可执行权限,请执行:chmod -R +x /usr/local/amoeba/bin/
Amoeba For MySQL 的使用非常简单,所有的配置文件都是标准的XML 文件,总共有四个配置文件。分别为:
◆ amoeba.xml:主配置文件,配置所有数据源以及Amoeba 自身的参数设置;实现主从的话配置这个文件就可以了;
◆ rule.xml:配置所有Query 路由规则的信息;
◆ functionMap.xml:配置用于解析Query 中的函数所对应的Java 实现类;
◆ rullFunctionMap.xml:配置路由规则中需要使用到的特定函数的实现类;
进入主配置文件目录:
[[email protected] amoeba]# cd conf/
[[email protected] conf]# ls
access_list.conf amoeba.xml dbServers.xml functionMap.xml log4j.xml ruleFunctionMap.xml
amoeba.dtd dbserver.dtd function.dtd log4j.dtd rule.dtd rule.xml
在这里我主要介绍配置 amoeba.xml、 dbServers.xml、 log4j.xml 三个主要的配置文件,其它文件没有特殊需要默认就可以了。
[[email protected] conf]# vi amoeba.xml
<?xml version="1.0"encoding="gbk"?>
<!DOCTYPE amoeba:configuration SYSTEM"amoeba.dtd">
<amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">
<server>
<!-- proxy server 绑定端口 -->
<property name="port">8066</property>
<!-- proxy server 绑定的IP(amoeba服务器) -->
<property name="ipAddress">192.168.58.11</property>
<!-- proxy server net IO Read thread size -->
<property name="readThreadPoolSize">200</property>
<!-- proxy server client process thread size -->
<property name="clientSideThreadPoolSize">300</property>
<!--mysql server client packet process thread size -->
<property name="clientSideThreadPoolSize">300</property>
<!-- mysql server data packet process thread size -->
<property name="serverSideThreadPoolSize">300</property>
<!-- socket Send and receive BufferSize(unit:K) -->
<property name="netBufferSize">128</property>
<!-- Enable/disable TCP_NODELAY (disable/enable Nagle‘s algorithm).-->
<property name="tcpNoDelay">true</property>
<!-- 对外验证用户名-->
<property name="user">root</property>
<!-- 对外验证密码-->
<property name="password">123456</property>
<!-- query timeout( default: 60 second , TimeUnit:second) -->
<property name="queryTimeout">60</property>
</server>
<!--
每个ConnectionManager都将作为一个线程启动。
manager负责ConnectionIO 读写/死亡检测
-->
<connectionManagerList>
<connectionManager name="defaultManager"class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">
<propertyname="subManagerClassName">com.meidusa.amoeba.net.AuthingableConnectionManager</property>
<!--
default value is avaliable Processors
<propertyname="processors">5</property>
-->
</connectionManager>
</connectionManagerList>
<dbServerList>
<!--
一台mysqlServer 需要配置一个pool,
如果多台平底的mysql需要进行LoadBalance,
平台已经提供一个具有负载均衡能力的ObjectPool:
com.meidusa.amoeba.mysql.server.MultipleServerPool
简单的配置是属性加上 virtual="true",该Pool 不允许配置FactoryConfig
或者自己写一个ObjectPool
-->
<dbServername="server1">
<!-- PoolableObjectFactory 实现类 -->
<factoryConfigclass="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="manager">defaultManager</property>
<!-- 真实 mysql数据库端口-->
<propertyname="port">3306</property>
<!-- 真实mysql 数据库IP-->
<propertyname="ipAddress">192.168.58.16</property>
<propertyname="schema">test</property>
<!-- 用于登录 mysql 的用户名-->
<propertyname="user">root</property>
<!-- 用于登录 mysql 的密码-->
<propertyname="password">123456</property>
</factoryConfig>
<!-- ObjectPool 实现类 -->
<poolConfigclass="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
<propertyname="maxActive">200</property>
<propertyname="maxIdle">200</property>
<propertyname="minIdle">10</property>
<propertyname="minEvictableIdleTimeMillis">600000</property>
<propertyname="timeBetweenEvictionRunsMillis">600000</property>
<propertyname="testOnBorrow">true</property>
<propertyname="testWhileIdle">true</property>
</poolConfig>
</dbServer>
<!-- 以下内容 复制server1 -->
<dbServer name="server2">
<!-- PoolableObjectFactory 实现类 -->
<factoryConfigclass="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="manager">defaultManager</property>
<!-- 真实 mysql数据库端口 -->
<propertyname="port">3306</property>
<!-- 真实mysql 数据库IP -->
<propertyname="ipAddress">192.168.58.12</property>
<propertyname="schema">test</property>
<!-- 用于登录 mysql 的用户名-->
<propertyname="user">root</property>
<!-- 用于登录 mysql 的密码 -->
<propertyname="password">123456</property>
</factoryConfig>
<!-- ObjectPool 实现类 -->
<poolConfigclass="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
<propertyname="maxActive">200</property>
<propertyname="maxIdle">200</property>
<propertyname="minIdle">10</property>
<propertyname="minEvictableIdleTimeMillis">600000</property>
<propertyname="timeBetweenEvictionRunsMillis">600000</property>
<propertyname="testOnBorrow">true</property>
<propertyname="testWhileIdle">true</property>
</poolConfig>
</dbServer>
<dbServer name="master"virtual="true">
<poolConfigclass="com.meidusa.amoeba.server.MultipleServerPool">
<!-- 负载均衡参数 1=ROUNDROBIN , 2=W 3=HA-->
<property name="loadbalance">1</property>
<!-- 参与该 pool 负载均衡的poolName 列表以逗号分割 -->
<propertyname="poolNames">server1</property>
</poolConfig>
</dbServer>
<dbServer name="slave" virtual="true">
<poolConfigclass="com.meidusa.amoeba.server.MultipleServerPool">
<!-- 负载均衡参数 1=ROUNDROBIN , 2=W 3=HA-->
<propertyname="loadbalance">1</property>
<!-- 参与该 pool 负载均衡的poolName 列表以逗号分割 -->
<propertyname="poolNames">server2</property>
</poolConfig>
</dbServer>
</dbServerList>
<queryRouterclass="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
<propertyname="ruleConfig">${amoeba.home}/conf/rule.xml</property>
<propertyname="functionConfig">${amoeba.home}/conf/functionMap.xml</property>
<property name="ruleFunctionConfig">${amoeba.home}/conf/ruleFunctionMap.xml</property>
<property name="LRUMapSize">1500</property>
<property name="defaultPool">master</property>
<propertyname="writePool">master</property>
<property name="readPool">slave</property>
<property name="needParse">true</property>
</queryRouter>
</amoeba:configuration>
启动amoeba
/usr/local/amoeba/bin/amoeba &
检验启动是否成功(使用的是默认的8066端口):
[[email protected] amoeba]# ps aux | grep amoeba
root 24580 0.219.2 408912 65685pxs/1 Sl 12:52 0:11/usr/java/jdk1.6/bin/java -server -Xms256m -Xmx256m -Xss128k-Damoeba.home=/usr/local/amoeba-Dclassworlds.conf=/usr/local/amoeba/bin/amoeba.classworlds -classpath/usr/local/amoeba/lib/classworlds-1.0.jar org.codehaus.classworlds.Launcher
[[email protected] amoeba]# netstat -lnp | grep java
tcp 0 0::ffff:192.168.1.159:8066 :::* LISTEN 24580/java
测试
主设置如下:
mysql>grant select,insert,update,delete on *.* to [email protected]‘192.168.58.%‘ identified by ‘123456‘;
#用户名密码要和前面配置的意志
mysql>flush privileges;
以后检查权限;
mysql>show grants for [email protected]‘192.168.58.%‘;
从设置如下:
mysql>grant select on *.* to [email protected]‘192.168.58.%‘identified by ‘123456‘;
#用户名密码要和前面配置的意志
mysql>flush privileges;
在从服务器上
#stop slave;
class 为表 ,主从都创建了:
create table class(id int (3),name varchar(6));
insert into class values (001,‘aaa‘);
insert into class values (002,‘bbb‘);
insert into class values (003,‘ccc‘);
1.在主上
mysql>insert into class values(004,‘master‘)
2.在从上
msyql>insert into class values(004,‘slave‘)
在代理上:(192.168.58.15)
#mysql -uroot -p123456 -h192.168.58.11 -P8066
######## 端口号是大写P,登录分离服务器。
测试读取是在从库还是主库?
mysql>select * from class;
测试写入数据是在从库还是主库?
mysql>insert into class values(005,‘eee‘);
接下来查询,说明没有发现数据写入数据。
mysql>select * from class;
查看写入数据
主服务器:说明写入了数据。
mysql>select * from class;
从服务器:说明从服务器上没有写入数据
mysql>select * from class;
在从上:
# start slave
参考:
主从复制:
http://pengranxiang.iteye.com/blog/1141118 理论不错,实践全是错的
http://369369.blog.51cto.com/319630/790921 实践不错
读写分离:
http://blog.chinaunix.net/uid-20639775-id-154600.html amoeba.xml 看不懂
http://docs.hexnova.com/amoeba/ amoeba 手册
http://wenku.baidu.com/link?url=1sbgL2yxmBcdjHGZz7S19RE-OCU5jFwBC7NUI9CF_FqieOn3vrvijqotG88fAV_U6isMZtoiRAMrjx_aaW1dLPdzeWjQG8eu9o-MLEIBaPG 这个最好