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_IOSlave_SQL进程必须正常运行,即YES状态,否则都是错误的状态(如:其中一个NO均属错误)

以上操作过程,主从服务器配置完成。

 

 

下面开始配置:

读写分离     由于图片不能正常显示,在附件中有完整说明

JDK的安装

1)以root身份登录系统,将jdk-6u16-linux-x64.bin通过FTP工具上传到/usr/java目录,执行以下命令:    

[root@localhost java]#chmod +x jdk-6u16-linux-x64.bin

[root@ 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版本:

[root@ 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:配置路由规则中需要使用到的特定函数的实现类;

进入主配置文件目录:
[root@Management amoeba]# cd conf/
[root@Management 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 三个主要的配置文件,其它文件没有特殊需要默认就可以了。

[root@bb 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端口):

[root@Centos2 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

[root@Centos2 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 root@'192.168.58.%' identified by '123456';

#用户名密码要和前面配置的意志

mysql>flush privileges;


以后检查权限;

mysql>show grants for root@'192.168.58.%';

 

从设置如下:

mysql>grant select on *.* to root@'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      这个最好