基於主從復制的Mysql雙機熱備+amoeba實現讀寫分離、均衡負載


讀寫分離指的是客戶只能在主服務器上寫,只能在從服務器上讀,當然了,這也是要看配置,你可以在主服務器配置讀的功能,但是在從服務器上只能讀不能寫,因為從服務器是基於binlog對主服務器的復制,如果在從服務器上寫的話,會造成主從不一致的結果。mysql實現讀寫分離,寫的壓力雖然沒有減少,但是讀的壓力瞬間就減少了一半。

Amoeba的中文意思是阿米巴、變型蟲
Amoeba是一個以MySQL為底層數據存儲,並對應用提供MySQL協議接口的proxy代理服務器。它集中地響應應用的請求,依據用戶事先設置的規則,將SQL請求發送到特定的數據庫上執行。基於此可以實現負載均衡、讀寫分離、高可用性等需求。與MySQL官方的MySQL Proxy相比,作者強調的是amoeba配置的方便(基於XML的配置文件,用SQLJEP語法書寫規則,比基於lua腳本的MySQL Proxy簡單)。
Amoeba相當於一個SQL請求的路由器, 目的是為負載均衡、讀寫分離、高可用性提供機制,而不是完全實現它們。用戶需要結合使用MySQL的 Replication等機制來實現副本同步等功能。amoeba對底層數據庫連接管理和路由實現也采用了可插撥的機制,第三方可以開發更高級的策略類來 替代作者的實現。這個程序總體上比較符合KISS原則的思想。

 

 

1、環境介紹

Master--IP:192.168.1.135(主服務器)
Slave---IP:192.168.1.136(從服務器)
Amoeba--IP:192.168.1.137(代理服務器)
Client--IP:192.168.1.138(客戶機)

2、安裝JDK

#mkdir /Amoeba
#tar –xvf jdk-7u40-linux-x64.tar.gz
# vim /etc/profile
JAVA_HOME=/Amoeba/jdk1.7.0_40
export JAVA_HOME

PATH=$JAVA_HOME/bin:$PATH
export PATH

CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH
export CLASSPATH

3、安裝Amoeba

#:mkdir /usr/local/amoeba
#:unzip amoeba-mysql-1.3.1-BETA.zip -d /usr/local/amoeba
#:chmod -R +x /usr/local/amoeba/bin/
# java -version java version "1.7.0_40"Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)

 

4、主從授權,增加用戶

mysql-->grant all privileges on *.* to amoeba@'%' identified by 'amoeba123';
mysql-->flush privileges;

 

5、amoeba相關的配置

<?xml version="1.0" encoding="gbk"?>

<!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">
<amoeba:configuration xmlns:amoeba="">http://amoeba.meidusa.com/">

<!--
amoeba開放接口相關配置
-->
<server>
<!-- proxy server綁定的端口 -->
<property name="port">9006</property>

<!-- proxy server綁定的IP -->

<property name="ipAddress">192.168.1.137</property>

<!-- 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>

<!-- 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">aixocm</property>


<!-- query timeout( default: 60 second , TimeUnit:second) -->
<property name="queryTimeout">60</property>
</server>

<!--
每個ConnectionManager都將作為一個線程啟動。
manager負責Connection IO讀寫/死亡檢測
-->
<connectionManagerList>
<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>

<dbServerList>
<!--
一台mysqlServer 需要配置一個pool,
如果多台 平等的mysql需要進行loadBalance,
平台已經提供一個具有負載均衡能力的objectPool:com.meidusa.amoeba.mysql.server.MultipleServerPool
簡單的配置是屬性加上 virtual="true",該Pool 不允許配置factoryConfig
或者自己寫一個ObjectPool。
-->



<!--
master授權相關設置
-->
<dbServer name="server1">

<!-- PoolableObjectFactory實現類 -->
<factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="manager">defaultManager</property>

<!-- 真實mysql數據庫端口 -->
<property name="port">3306</property>

<!-- 真實mysql數據庫IP -->
<property name="ipAddress">192.168.1.135</property>
<property name="schema">test</property>

<!-- 用於登陸mysql的用戶名 -->
<property name="user">amoeba</property>

<!-- 用於登陸mysql的密碼 -->
<property name="password">amoeba</property>


</factoryConfig>

<!-- ObjectPool實現類 -->
<poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
<property name="maxActive">200</property>
<property name="maxIdle">200</property>
<property name="minIdle">10</property>
<property name="minEvictableIdleTimeMillis">600000</property>
<property name="timeBetweenEvictionRunsMillis">600000</property>
<property name="testOnBorrow">true</property>
<property name="testWhileIdle">true</property>
</poolConfig>
</dbServer>




<!--
slave數據庫授權相關設置
-->
<dbServer name="server2">

<!-- PoolableObjectFactory實現類 -->
<factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
<property name="manager">defaultManager</property>

<!-- 真實mysql數據庫端口 -->
<property name="port">3306</property>

<!-- 真實mysql數據庫IP -->
<property name="ipAddress">192.168.1.136</property>

<property name="schema">test</property>

<!-- 用於登陸mysql的用戶名 -->
<property name="user">amoeba</property>

<!-- 用於登陸mysql的密碼 -->
<property name="password">amoeba</property>


</factoryConfig>

<!-- ObjectPool實現類 -->
<poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
<property name="maxActive">200</property>
<property name="maxIdle">200</property>
<property name="minIdle">10</property>
<property name="minEvictableIdleTimeMillis">600000</property>
<property name="timeBetweenEvictionRunsMillis">600000</property>
<property name="testOnBorrow">true</property>
<property name="testWhileIdle">true</property>
</poolConfig>
</dbServer>




<!--
master均衡負載
-->
<dbServer name="master" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<!-- 負載均衡參數 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
<property name="loadbalance">1</property>

<!-- 參與該pool負載均衡的poolName列表以逗號分割 -->
<property name="poolNames">server1</property>
</poolConfig>
</dbServer>



<!--
slave均衡負載
-->
<dbServer name="slave" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<!-- 負載均衡參數 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
<property name="loadbalance">1</property>

<!-- 參與該pool負載均衡的poolName列表以逗號分割 -->
<property name="poolNames">server1,server2</property>
</poolConfig>
</dbServer>



<!--
讀寫分離配置
-->
</dbServerList>

<queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
<property name="ruleConfig">${amoeba.home}/conf/rule.xml</property>
<property name="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>
<property name="writePool">master</property>
<property name="readPool">slave</property>

<property name="needParse">true</property>
</queryRouter>
</amoeba:configuration>

 

6、啟動Amoeba

# cd /usr/local/amoeba/bin
這種啟動方便看nohup.log日志.防止提示溢出
#:nohup bash -x amoeba &
#:重啟amoeba要先殺死amoeba進程

#ps -ef|grep amoeba|awk '{print $2}'|xargs kill -9

#echo >nohup.out

#nohup bash -x amoeba &

常見錯誤:1
The stack size specified is too small, Specify at least 228k
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
解決辦法:
# vim /usr/local/amoeba/bin/amoeba
#DEFAULT_OPTS="-server -Xms256m -Xmx256m -Xss128k"  注釋
DEFAULT_OPTS="-server -Xms256m -Xmx256m -Xss256k"   增加

 

7、測試是否讀寫分離

1、在(master)主上的test庫建立一個alvin的表
Mysql->use test;
Mysql->create table alvin(id int,name char(10));

2、在(slave)從上查看test庫是否同步了alvin表
Mysql-> use test;
Mysql->show tables;

3、在主(master)操作.插入一條數據.
mysql-->insert into alvin values(1,'master');
 

4、在從(slave)操作,插入一條數據.
mysql-->insert into alvin values(2,'slave');


注意因為從同步主的數據。所以這里有2條數據,在slave上插入2條數據目的是為了和主服務器內容上存在差異,這樣更好的顯示輪詢均衡負載的查看效果,

5、在Amoeba機器上操作
在192.168.1.138上面測試(能夠連接到安裝了amoeba的主機都可以充當客戶機),這個密碼就是配置文件里面對外的驗證密碼root 和密碼,對外開放的密碼,一定要街上端口號,端口號可以自己定義


#mysql –uroot –paixocm -h192.168.1.137 -P9006
(1) 先驗證讀。我們配置文件是用的是DR輪詢,注意這個IP地址要寫:amoeba的IP地址,不是master也不是slave ,是通過amoeba代理登陸。
Mysql->use test;

測試輪詢成功。主和從各查詢一次。
(2) 驗證寫,正常來說。如果只有全部寫到主里面,兩邊的數據才會以致。如果其中有一個
不一致的話。那么說明寫到從里面去了。因為主不會同步從的數據。都是單向數據傳輸。

先關閉從服務器136的同步功能

#stop slave;

 

然后通過客戶端138插入一條數據

再到主服務器上來查詢,可以看到剛剛插入的數據

最后到從服務器上來查詢,並沒有看到插入的數據,也就是說數據只寫入到了主服務器中,你可以開啟從服務器的復制功能,start slave;再次查詢你就可以看到從服務器同步的數據了,不信你試試!!



常見配置:
八:常用配置寫法.
(1)如果負載多個庫,軟件會根據你用戶授權來決定對哪些庫有權限.
grant all privileges on *.* to amoeba@'%' identified by 'amoeba123'; 這里寫的是all 那么就是對所有的庫有權限(會自動負載所有的庫).
上面配置文件的庫名test.根據這個語句來決定.如果是all.那么直接用寫test來測試.方便一點.



(2)一主一從的負載寫法一:
主只寫.<property name="poolNames">server1</property>(主的均衡負載配置)
從只讀.<property name="poolNames">server2</property>(從的均衡負載配置)


(3)一主一從的負載寫法:
主負寫:<property name="poolNames">server1</property>
主也負責讀,從也負責讀.比例1:1 第一讀.從.第二次讀住.循環 寫的話,只能寫主.<property name="poolNames">server1,server2</property>


(4)一主多從的負載寫法:
比如.一台主.3台從.在最上面定義了.server1(master)  server2(slave1) server3(slave2) server4(slave3)
1主只寫:<property name="poolNames">server1</property>
3從負載讀 <property name="poolNames">server2,server3,server4</property>   
權重:1:1    3台輪詢各一次.持續循環

(5)比如我想要.slave1 權重高一點.其它的.2台從.每次讀一次.slave1讀.2次.
<property name="poolNames">server2,server2,server3,server4</property>  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM