mysql基於amoeba的讀寫分離
前文中有講到有關mysql的主從配置,如果單單就主從配置而言,僅能實現資料的及時備份與恢復,對於那些更新不頻繁,不需要時時備份資料的使用者來說意義不大,而且僅為了備份而再架設一臺資料庫伺服器有些浪費,因為使用免費的雲備份完全可以勝任,當然架設主從資料庫的意義當然不僅僅在於資料的備份與恢復,更大的意義在於實現mysql的讀寫分離,當然除了主從資料庫是必備的之外,我們還需要藉助一些工具,其中amoeba就是其中的佼佼者,配置簡單,使用方便,下面我們就來看看如何藉助amoeba來實現mysql的讀寫分離吧。
測試環境:
amoeba伺服器 :物理機 內網ip:192.168.1.103 amoeba版本3.0.5-RC 未安裝mysql java環境1.7.0_60 作業系統xp
master伺服器 :虛擬機器 橋接物理機 內網ip:192.168.1.116 mysql版本5. 5.32 作業系統xp
slave伺服器 :虛擬機器 橋接物理機 內網ip:192.168.1.110 mysql版本5.5.39 作業系統centos6.5
主從配置這裡不再複述,有需要的朋友可以參考小編的“mysql主從配置淺析”,下面的操作均建立在主從配置好的基礎上。
一、下載並安裝amoeba
我們可以在SourceForge (全球最大開源軟體開發平臺和倉庫)中搜索amoeba,裡面幾乎囊括了所有版本的amoeba,而我們需要的是amoeba for mysql,選擇最近最新的版本進行下載,如果實在找不到可以點選下面的參考資料“amoeba下載地址”進行下載。windows下的amoeba無需安裝,只需要安裝執行amoeba的java環境即可。
二、增加許可權
grant all on test.* to 'amoeba'@'192.168.1.103' identified by '123456'
master和slave伺服器中都需要為amoeba伺服器新增一個使用者,用於操作master和slave上的資料庫,master和slave伺服器上新增的使用者和密碼相同。
三、配置amoeba
我們在解壓縮的amoeba資料夾中找到conf資料夾,其中我們需要配置的僅有dbServers.xml和amoeba.xml。
dbServers.xml
首先我們來看下name為abstractServer的dbServer標籤,其中abstractive屬性為true,意味著這是一個抽象的dbServer定義,可以由其他dbServer定義拓展,
而abstractServer下方的dbServer就是我們實際中需要使用的,關於dbServer,可以根據自己的情況書寫,有幾個需要配置的資料庫,就填寫幾個,其中name可以自定義,最好書寫有含義的名稱,parent就填寫abstractServer,因為我們要繼承abstractServer,這樣我們就可以在abstractServer的基礎上進行擴充套件(繼承了port,schema,user和password等屬性),只需要新增獨有的屬性即可,例如新增屬於自己獨有的ip。這裡說下關於步驟二中的新增使用者問題,你可以在master和slave中為amoeba新增不同的使用者名稱和密碼,但是需要在獨立的dbServer中再進行特別的配置,為了方便起見,所以為amoeba設定相同的使用者名稱和密碼。下方我們可以看到有被<!-- -->註釋的地方,當主從資料庫超過兩個的時候,這個地方就有用了,舉例來說,一主兩從,主為master,從一為slave1,從二為slave2。除了各自的dbServer之外,我們還可以新建一個dbServer作為資料庫池,用於整合那些功能相同的資料庫,例如slave1和slave2都是從資料庫,負責讀取操作,我們就可以把它們集中在一起方便呼叫。其中屬性為loadbalance代表負載均衡,預設值是1,代表輪詢演算法。關於負載均衡小編知之甚少,無法做過多解釋,暫且就按照預設值來吧。poolNames屬性就是讓我們放置那些具有共同功能的dbServer,例如slave1,,slave2,其中不同的dbServer以英文逗號隔開。
amoeba.xml
配置完成dbSevers.xml之後,我們來配置amoeba.xml,首先我們來配置service標籤,需要配置的地方有三點,port,user和password。其中port預設是8066,可以自行更改,但是不要跟現有埠起衝突,如非必要不建議更改。user和password則可以自定義,無需跟master和slave建立的使用者一致。這裡的埠,使用者名稱和密碼其實就是為了虛擬出一個mysql連結做準備的(非真實,amoeba伺服器可以不安裝真實的mysql資料庫),具體應用可參考下面的測試。
特別說明:在service標籤中有一個被註釋的ipAddress屬性,該屬性用於繫結可以連結amoeba虛擬出來的mysql的具體ip,如果不繫結,則amoeba伺服器所在的網路環境(在同一個區域網下,非同一個區域網下未測試)的其他伺服器,可以通過amoeba的內網ip進行連結,如果綁定了127.0.0.1,那麼只有amoeba伺服器可以連結虛擬出來的mysql,這點需要注意。
埠,使用者名稱和密碼配置完之後,我們來配置queryRouter標籤,該標籤可以實現真正意義上的讀寫分離,以上配置均為該標籤做準備。其中我們需要手動修改的地方有三處,分別是defaultPool,writePool和readPool。defaultPool配置了預設的資料庫節點,一些除了SELECT\UPDATE\INSERT\DELETE的語句都會在defaultPool執行,一般設定為主庫。writePool顧名思義就是資料庫寫庫,insert,update和delete操作都將會在此庫中執行,一般設定為主庫。readPool就是寫庫,如果是單主單從,則readPool就寫從庫在dbServers.xml中設定的名稱,例如設定為slave,如果是一主多從,則readPool設定為從資料庫池,例如上述例子中的multiPool,就是從資料庫池,包含了slave1和salve2兩個從資料庫,這樣就完成了讀寫分離(主從)和負載均衡(從一和從二)。至此,amoeba的配置工作已完成。
四、測試讀寫分離
amoeba是否真的能夠實現讀寫分離呢?我們來測試一下,首先自然是開啟amoeba,啟動檔案在amoeba資料夾下的bin中,找到launcher.bat,雙擊開啟(如果使用的版本比較低的話,沒有該檔案,相應的啟動檔名稱應該為amoeba),出現如下介面證明啟動成功。
在操作資料庫之前,我們還需要做一件事情,就是開啟master和slave上的查詢日誌,預設情況下該日誌是關閉的,因為該日誌會記錄下使用者的所有操作,在實際執行中會產生大量的資訊,造成不必要的I/O開銷,但是對於我們驗證讀寫分離卻是有很大的幫助,因此在測試讀寫分離的時候可以開啟查詢日誌。開啟方法很簡單,找到mysql的配置檔案my.cnf或者my.ini,書寫log="日誌檔案目錄和名稱",在定義的檔案目錄下則可以找到該檔案,如果沒有設定檔案目錄,預設在mysql資料夾的data資料夾下,設定完成後別忘了重啟mysql。
開啟查詢日誌後,我們可以書寫連結mysql的程式了,以php連結mysql為例。
<?php
mysql_connect('127.0.0.1:8066','myuser','mypass');
mysql_select_db('test');
mysql_query("set names 'utf8'");
$createtable = "create table `amoeba`(
`id` int(10) not null,
`name` varchar(50) not null
)engine=myisam default character set utf8";
mysql_query($createtable);
mysql_query("insert into `amoeba`(`id`,`name`) values(1,'1')");
mysql_query("select `id`,`name` from `amoeba`");
其中連結mysql的host,user,password都是在amoeba.xml中定義的,不要隨意更改,否則會連結失敗,選擇的資料庫則是dbServers.xml中定義的schema屬性值,該資料庫必須是在master和slave中真實存在的,否則基於該庫的所有操作都會失敗。我們為該庫建立一個數據表amoeba,併為這個表插入一條資料,然後查詢該表資料。此時我們進行了三個操作,一個是create操作,一個是insert操作,一個是select操作,根據amoeba中關於應用池的定義,那麼create和insert操作應該在master資料庫中,select操作應該在slave中,到底是否真的如此呢?我們可以檢視剛才開啟的查詢日誌中的記錄,果然在master主庫中只記錄了create和insert操作,並沒有記錄select操作,那麼slave從庫中是否只記錄了select操作呢,開啟一看,居然有create和insert操作,難道沒有生效?其實不然,slave之所以有create和insert操作,是因為主從配置關係,它同步了主庫的create和insert操作,怎麼證明呢?其實很簡單,我們在mysql命令列下輸入stop slave,暫停從庫,然後再次插入一條資料,現在主庫的資料是不是比從庫中多了一條呢,此時的從庫的查詢日誌中是否已經沒有新插入的insert的記錄了呢。
總結:以上僅說到了用amoeba實現mysql讀寫分離的最小配置,amoeba還能實現資料的水平切分、垂直切分,關於amoeba更進一步的應用這裡就不在詳述,如果有興趣的朋友可以參考amoeba官方文件(參考資料2)。
注意事項:
1.amoeba使用java開發,因此使用之前需要安裝java環境,請使用java SE 1.5以上的版本,關於如何安裝java環境不是本文重點,這裡不再複述。
2.linux預設開啟的有防火牆,此時我們在其他伺服器上鍊接此伺服器的mysql的時候會無法連結,我們可以使用service iptables stop命令來關閉防火牆,切記使用root許可權來關閉防火牆,如果使用普通使用者許可權該命令無反應。
3.以上測試均建立在單一資料庫的基礎上,如果需要進行多資料庫的讀寫分離,則相應的許可權和配置資訊都需要調整。
4.amoeba伺服器無需安裝真實mysql資料庫,它可以虛擬出一個mysql例項,但是程式操作的資料庫必須在master和slave中真實存在。
參考資料
1.amoeba下載地址:http://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/
2.amoeba使用指南:http://docs.hexnova.com/amoeba/