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 mysqlstart
slave :
ps -ef|grepmysql
service mysqlstart
4. 在 Master 上建立一個專門用于複制的 賬号密碼 : repl repl
5. 啟動主從複制功能
需要檢視 Master 中的 Master status
mysql> showmaster 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;
//注意不要斷開,308數字前後無單引号。
Mysql>startslave; //啟動從伺服器複制功能
檢查從伺服器複制功能狀态:
mysql> show slavestatus\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 49264pts/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 *.* [email protected]'192.168.58.%' identified by '123456';
#使用者名密碼要和前面配置的意志
mysql>flush privileges;
從設定如下:
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