具備負(fù)載均衡功能MySQL服務(wù)器集群部署及實(shí)現(xiàn)
1. 引言
MySQL是一個(gè)高速度、高性能、多線程、開(kāi)放源代碼,建立在客戶/服務(wù)器(Client/Server)結(jié)構(gòu)上的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS)。它始于1979年,最初是Michael Widenius為瑞典TcX公司創(chuàng)建的UNIREG數(shù)據(jù)庫(kù)系統(tǒng),當(dāng)時(shí)的UNIREG沒(méi)有SQL(Structured Query Language結(jié)構(gòu)化查詢語(yǔ)言)接口,限制了它的應(yīng)用。1996年5月,Widenius開(kāi)發(fā)出了MySQL的最初版本,開(kāi)始在Internet上公開(kāi)發(fā)行。MySQL的開(kāi)發(fā)人員從一開(kāi)始就一直關(guān)注它的性能,為此不惜特性集,直到今天,MySQL依然保持本色,以高速度高性能為首要原則。
隨著時(shí)間的推移,MySQL也加入了大型數(shù)據(jù)庫(kù)產(chǎn)品的高級(jí)特性,如存儲(chǔ)過(guò)程、視圖、觸發(fā)器等,使其在企業(yè)級(jí)數(shù)據(jù)庫(kù)系統(tǒng)中開(kāi)始被部署應(yīng)用[1]。2008年10月,SUN公司收購(gòu)了MySQL AB公司,開(kāi)始進(jìn)入開(kāi)源領(lǐng)域。隨著重量級(jí)操作系統(tǒng)Solaris的開(kāi)源,SUN MySQL在數(shù)據(jù)庫(kù)市場(chǎng)占有的份額將會(huì)進(jìn)一步提高。因此,在生產(chǎn)環(huán)境中部署具有負(fù)載均衡功能的MySQL服務(wù)器集群,對(duì)于提高企業(yè)數(shù)據(jù)庫(kù)應(yīng)用系統(tǒng)的速度、穩(wěn)定性及可伸縮性具有很大的現(xiàn)實(shí)意義,也可以有效降低應(yīng)用系統(tǒng)的投資成本。本文將以FreeBSD 7.0-Release操作系統(tǒng)為例,利用MySQL數(shù)據(jù)庫(kù)的復(fù)制(Replication)特性,簡(jiǎn)要介紹部署MySQL服務(wù)器集群的實(shí)現(xiàn)方法和相關(guān)注意事項(xiàng)。
2. 系統(tǒng)模型
本集群的結(jié)構(gòu)為一個(gè)主MySQL服務(wù)器(Master)服務(wù)器與多個(gè)從屬M(fèi)ySQL服務(wù)器(Slave)建立復(fù)制(replication)連接,主服務(wù)器與從屬服務(wù)器實(shí)現(xiàn)一定程度上的數(shù)據(jù)同步,多個(gè)從屬服務(wù)器存儲(chǔ)相同的數(shù)據(jù)副本,實(shí)現(xiàn)數(shù)據(jù)冗余,提供容錯(cuò)功能。部署開(kāi)發(fā)應(yīng)用系統(tǒng)時(shí),對(duì)數(shù)據(jù)庫(kù)操作代碼進(jìn)行優(yōu)化,將寫(xiě)操作(如UPDATE、INSERT)定向到主服務(wù)器,把大量的查詢操作(SELECT)定向到從屬服務(wù)器,實(shí)現(xiàn)集群的負(fù)載均衡功能。如果主服務(wù)器發(fā)生故障,從屬服務(wù)器將轉(zhuǎn)換角色成為主服務(wù)器,使應(yīng)用系統(tǒng)為終端用戶提供不間斷的網(wǎng)絡(luò)服務(wù);主服務(wù)器恢復(fù)運(yùn)行后,將其轉(zhuǎn)換為從屬服務(wù)器,存儲(chǔ)數(shù)據(jù)庫(kù)副本,繼續(xù)對(duì)終端用戶提供數(shù)據(jù)查詢檢索服務(wù)。
3. 部署實(shí)現(xiàn)
本文以一臺(tái)主服務(wù)器帶三臺(tái)從屬服務(wù)器為例,簡(jiǎn)要介紹MySQL服務(wù)器集群的實(shí)現(xiàn)方案和具體方法步驟。
3.1 系統(tǒng)部署
由于FreeBSD系統(tǒng)對(duì)機(jī)器硬件要求較低,出于降低系統(tǒng)部署成本考慮,主服務(wù)器和從屬服務(wù)器操作系統(tǒng)均采用FreeBSD 7.0-Release,并采用最小化定制安裝,完成以后系統(tǒng)占用磁盤空間僅為254M(不計(jì)swap分區(qū)所占空間,它隨具體機(jī)器內(nèi)存容量的變化而變化)。為充分發(fā)揮系統(tǒng)硬件性能,MySQL數(shù)據(jù)庫(kù)采用源代碼編譯安裝。
3.1.1 安裝FreeBSD系統(tǒng)
在主服務(wù)器和從屬服務(wù)器上安裝FreeBSD 7.0-Release,具體安裝方法步驟不是本文主要內(nèi)容,在此略過(guò),如有疑問(wèn)可以參考FreeBSD系統(tǒng)手冊(cè)。需要說(shuō)明的是為方便用戶系統(tǒng)運(yùn)行期間的維護(hù)管理,要打開(kāi)系統(tǒng)的SSH服務(wù)功能,系統(tǒng)安裝配置期間允許root用戶遠(yuǎn)程登錄,正常運(yùn)行以后要關(guān)閉root用戶的遠(yuǎn)程登錄功能。在/etc/ssh/sshd_config配置文件中對(duì)PermitRootLogin設(shè)置為yes為允許root用戶遠(yuǎn)程登錄到系統(tǒng),設(shè)置為no即為不允許。修改保存文件后執(zhí)行kill –HUP `cat /var/run/sshd.pid`命令即可重啟sshd守護(hù)進(jìn)程,使設(shè)置生效[2]。上述操作需要root用戶權(quán)限。
3.1.2 編譯安裝MySQL
到MySQL的官方網(wǎng)站http://www.mysql.com下載MySQL數(shù)據(jù)庫(kù)的安裝源代碼壓縮包,本例下載的是mysql-5.1.30.tar.gz,以root用戶身份登錄到系統(tǒng),開(kāi)始安裝MySQL數(shù)據(jù)庫(kù)系統(tǒng)。
由于在對(duì)MySQL進(jìn)行源代碼編譯安裝時(shí)要求使用GNU的C編譯器,而FreeBSD系統(tǒng)本身提供的不是該編譯器,因此用戶必須下載安裝GNU C編譯器[3]。把下載的gnumake-3.81.tar.gz解壓安裝,按如下步驟即可安裝GNU C編譯器:
[root@FreebsdMaster/softwares]# tar –zxvf gnumake-3.81.tar.gz |
GNU C編譯器默認(rèn)安裝到/usr/local/bin,在安裝MySQL時(shí)按絕對(duì)路徑調(diào)用make命令即可,如# /usr/local/bin/make。
MySQL的編譯安裝比較復(fù)雜,具體操作及相關(guān)注意事項(xiàng)如下:
(1). 解壓mysql-5.1.30.tar.gz,并進(jìn)行配置
[root@FreebsdMaster /softwares]# tar –zxvf mysql-5.1.30.tar.gz |
說(shuō)明:MySQL默認(rèn)的安裝目錄是/usr/local/mysql,為了增強(qiáng)系統(tǒng)部署的靈活性,緊貼用戶應(yīng)用系統(tǒng)實(shí)際情況,可以用—-prefix參數(shù)定制安裝目錄。--with-charset參數(shù)是使MySQL數(shù)據(jù)庫(kù)支持中文gb2312字符集,如果需要支持其它字符集,使用--with-extra-charset參數(shù),格式為—-with-extra-charset=CHARSET1,CHARSET2, … 。
(2). 編譯安裝MySQL
[root@FreebsdMaster /softwares/mysql-5.1.30]# /usr/local/bin/make |
注意一定要按絕對(duì)路徑調(diào)用GNU C編譯器,否則編譯過(guò)程報(bào)錯(cuò)退出。
(3). 為系統(tǒng)添加mysql用戶組和用戶
[root@FreebsdMaster /]# pw group add mysql |
[root@FreebsdMaster /]# adduser
FreeBSD系統(tǒng)沒(méi)有g(shù)roupadd命令,其添加用戶組的命令是pw,添加用戶命令adduser按系統(tǒng)提示操作即可完成。當(dāng)然用 pw user add mysql命令也可以完成添加用戶mysql的功能,但不如adduser命令功能完善。
(4). 更改/app/mysql5目錄及文件屬性
[root@FreebsdMaster /app]# chmod –R mysql mysql5 |
說(shuō)明:/app/mysql5為MySQL數(shù)據(jù)庫(kù)系統(tǒng)所在目錄,如果用戶部署的應(yīng)用系統(tǒng)數(shù)據(jù)量極大,可以將數(shù)據(jù)庫(kù)系統(tǒng)目錄設(shè)在大容量磁盤陣列上。磁盤陣列設(shè)置與具體機(jī)器硬件相關(guān)性很大,具體操作設(shè)置參考具體硬件系統(tǒng)說(shuō)明和FreeBSD操作手冊(cè)。不借助第三方軟件,F(xiàn)reeBSD 7.0-Release系統(tǒng)可以配置RAID0、RAID1磁盤陣列。
(5). 安裝MySQL系統(tǒng)初始數(shù)據(jù)庫(kù)
[root@FreebsdMaster /softwares/ mysql-5.1.30]# ./scripts/mysql_install_db.sh --basedir=/app/mysql5 –-data-dir=/app/mysql5/data |
注意:必須考慮Unix系統(tǒng)的文件權(quán)限特性,首先給mysql_install_db.sh腳本添加可執(zhí)行屬性,否則安裝腳本無(wú)法執(zhí)行。執(zhí)行chmod +x ./scripts/mysql_install_db.sh命令即可。參數(shù)--basedir=/app/mysql5和--datadir=/app/msyql5/data為必加參數(shù),否則腳本運(yùn)行報(bào)錯(cuò)退出,無(wú)法安裝系統(tǒng)初始數(shù)據(jù)庫(kù)mysql和測(cè)試數(shù)據(jù)庫(kù)test,mysql數(shù)據(jù)庫(kù)包含系統(tǒng)權(quán)限設(shè)置表,沒(méi)有這些表數(shù)據(jù)庫(kù)服務(wù)進(jìn)程mysqld將無(wú)法啟動(dòng)。
(6). 再次更改/app/mysql5目錄及其文件屬性
[root@FreebsdMaster /app]# chmod –R root mysql5 |
這樣做是為了保證系統(tǒng)安全,防止通過(guò)MySQL系統(tǒng)漏洞的入侵行為。MySQL以mysql用戶身份運(yùn)行,對(duì)/data目錄具有完全訪問(wèn)權(quán)限,對(duì)其它目錄則只有系統(tǒng)管理員根據(jù)需要設(shè)置的訪問(wèn)權(quán)限,確保FreeBSD系統(tǒng)的安全。這里需要特別提醒用戶注意的是要確保mysqld文件(MySQL的守護(hù)進(jìn)程,位于/app/mysql5/libexec目錄下)沒(méi)有設(shè)置setuid標(biāo)志位,如果設(shè)置了該標(biāo)志位,入侵者對(duì)其它文件就具有其不應(yīng)有的權(quán)限。具體原因參考關(guān)于Unix系統(tǒng)安全的手冊(cè),本文對(duì)這個(gè)問(wèn)題不再贅述。
(7). 啟動(dòng)MySQL服務(wù)器
上述操作全部完成以后,輸入如下命令啟動(dòng)MySQL數(shù)據(jù)庫(kù)服務(wù)守護(hù)進(jìn)程:
[root@FreebsdMaster /]# /app/mysql5/bin/mysqld_safe –user=mysql & |
--user參數(shù)表示以mysql用戶身份運(yùn)行MySQL數(shù)據(jù)庫(kù)服務(wù)守護(hù)進(jìn)程,“&”符號(hào)表示以后臺(tái)方式運(yùn)行。輸入 netstat –an|grep 3306命令,如果看到下面的輸出則表示MySQL5.1.30已在用戶系統(tǒng)上編譯安裝成功。其中,3306是MySQL數(shù)據(jù)庫(kù)系統(tǒng)默認(rèn)的監(jiān)聽(tīng)端口號(hào)。
[root@FreebsdMaster /]# netstat –an|grep 3306 tcp4 0 0 *.3306 *.* LISTEN |
按照同樣方法與步驟在其它三臺(tái)機(jī)器上安裝FreeBSD 7.0-Release與MySQL5.1.30,為下面的MySQL服務(wù)器集群配置準(zhǔn)備好系統(tǒng)平臺(tái)基礎(chǔ)。
#p#
3.2 系統(tǒng)配置
所有系統(tǒng)安裝完畢之后,需要對(duì)它們做一些必要的配置方可按照用戶預(yù)先設(shè)計(jì)的結(jié)構(gòu)模型實(shí)現(xiàn)具有負(fù)載均衡功能的MySQL服務(wù)器集群。
3.2.1 FreeBSD操作系統(tǒng)配置
(1). 調(diào)整內(nèi)核參數(shù),優(yōu)化操作系統(tǒng)性能
因?yàn)槭翘幱谏a(chǎn)環(huán)境的服務(wù)器,投入正常運(yùn)行之前一定要對(duì)內(nèi)核參數(shù)進(jìn)行必要的調(diào)整,提升系統(tǒng)性能,加強(qiáng)穩(wěn)定性。簡(jiǎn)要說(shuō)就是去掉不必要的硬件支持選項(xiàng),使新內(nèi)核占用更少的內(nèi)存,加快啟動(dòng)速度。不同機(jī)器硬件系統(tǒng)差異很大,用戶可根據(jù)具體系統(tǒng)的硬件情況不斷調(diào)整試驗(yàn),最終定制出最優(yōu)化、最安全的FreeBSD系統(tǒng)。一定要屏蔽掉組合鍵Ctrl+Alt+Del的熱重啟功能,防止用戶誤按Ctrl+Alt+Del重啟系統(tǒng),引起數(shù)據(jù)庫(kù)系統(tǒng)服務(wù)意外中斷。在內(nèi)核配置文件如MYKERNEL中加入:
options SC_DISABLE_REBOOT
重新編譯系統(tǒng)內(nèi)核,重啟后即可屏蔽Ctrl+Alt+Del組合鍵的熱重啟功能。如何定制新內(nèi)核及重新編譯FreeBSD系統(tǒng),用于可參考FreeBSD系統(tǒng)手冊(cè),此不贅述。
(2). 進(jìn)行其它設(shè)置,增強(qiáng)系統(tǒng)安全性
用戶可根據(jù)以下一般安全準(zhǔn)則設(shè)置自己的FreeBSD系統(tǒng)。
◆選擇一個(gè)好的密碼并予以妥善保護(hù)。
◆對(duì)于敏感文件采用適當(dāng)安全等級(jí)的加密算法進(jìn)行加密。對(duì)于敏感級(jí)別不是很高的文件采用系統(tǒng)自帶的crypt工具加密;對(duì)于敏感度極高的文件則使用專用加密工具,如PGP、GPG進(jìn)行不對(duì)稱加密,提高加密文件的防攻擊能力。
◆仔細(xì)設(shè)置文件訪問(wèn)權(quán)限,達(dá)到保護(hù)文件目的。
◆保護(hù)好自己的.profile文件。恰當(dāng)設(shè)置.profile文件的訪問(wèn)權(quán)限,確保只有自己能訪問(wèn)。
◆仔細(xì)維護(hù)已設(shè)置setuid或setgid標(biāo)志位的任何程序。
◆禁止不加防范地離開(kāi)已注冊(cè)終端。任何時(shí)候都必須按常規(guī)正常退出系統(tǒng),先執(zhí)行clear清屏命令,防止其它用戶看到操作痕跡,再執(zhí)行exit命令退出終端。
◆防范特洛伊木馬程序。正確設(shè)置PATH變量的檢索順序,確保系統(tǒng)目錄位于當(dāng)前目錄的前面。
◆防范病毒的入侵。
◆監(jiān)控最近一次注冊(cè)時(shí)間,確保沒(méi)有他人盜用自己的帳號(hào)。
特別提示:對(duì)于生產(chǎn)環(huán)境的服務(wù)器,一定要保證服務(wù)器的物理安全,安全措施再完善的系統(tǒng),一旦被入侵者物理接觸,所有的安全措施將形同虛設(shè)!
Unix系統(tǒng)安全是一個(gè)很大的課題,本文只是提及了一些最膚淺的常識(shí),具體內(nèi)容用戶可以參考相關(guān)書(shū)籍或網(wǎng)上資源。為確保Unix系統(tǒng)的配置具有高度的安全性,可以使用Internet安全中心(Center for Internet Security,CIS)提供的安全測(cè)試工具Benchmarks或評(píng)估工具Scoring Tools,檢驗(yàn)和監(jiān)控系統(tǒng)配置的安全性 [4]。
3.2.2 MySQL數(shù)據(jù)庫(kù)系統(tǒng)配置
為了能使上述系統(tǒng)實(shí)現(xiàn)一對(duì)多的主從復(fù)制(replication)和冗余機(jī)制,還需要對(duì)以上四個(gè)MySQL服務(wù)器進(jìn)行一些必要的配置。
(1). 配置主機(jī)名和IP地址
本實(shí)現(xiàn)方案中把MySQL服務(wù)器Master主機(jī)名設(shè)為FreebsdMaster,IP地址配置為192.168.1.100,其它三臺(tái)Slave依次設(shè)為FreebsdSlave1,192.168.1.101;FreebsdSlave2,192.168.1.102;FreebsdSlave3,IP地址192.168.1.103。
(2). 設(shè)置root用戶密碼
MySQL的root用戶初始密碼為空,為保證系統(tǒng)安全必須為root用戶設(shè)置密碼:
[root@FreebsdMaster /]# /app/mysql5/bin/mysql –uroot –p |
同Unix系統(tǒng)一樣,輸入密碼時(shí)屏幕沒(méi)有任何回顯,進(jìn)入系統(tǒng)后執(zhí)行SET PASSWORD SQL語(yǔ)句設(shè)置或修改MySQL root用戶密碼。為使應(yīng)用系統(tǒng)服務(wù)器遠(yuǎn)程連接到MySQL數(shù)據(jù)庫(kù)服務(wù)器,除本地root用戶以外,還要設(shè)置一個(gè)能從用戶內(nèi)部網(wǎng)絡(luò)其它終端登錄的root用戶。具體操作如下:
mysql>USE mysql; |
完成上述操作后應(yīng)用系統(tǒng)服務(wù)器就可以連接到MySQL數(shù)據(jù)庫(kù)服務(wù)器進(jìn)行各種操作了,這個(gè)遠(yuǎn)程root用戶的初始密碼為空,用戶需要從遠(yuǎn)程終端登錄,為其設(shè)置密碼。
(3). 開(kāi)啟MySQL服務(wù)器的二進(jìn)制更新日志功能
上述MySQL服務(wù)器安裝完成后,安裝程序沒(méi)有生成my.cnf配置文件,為此用戶需要手工添加/etc/my.cnf文件。MySQL服務(wù)是由/app/myql5/libexec/mysqld提供的,其尋找my.cnf配置文件的默認(rèn)順序?yàn)?etc/my.cnf,~/.my.cnf,/usr/local/mysql/etc/my.cnf。啟動(dòng)ee編輯器,# ee /etc/my.cnf,在Master機(jī)器的配置文件寫(xiě)入如下內(nèi)容:
[mysqld] |
在其它三臺(tái)Slave機(jī)器的配置文件/etc/my.cnf文件寫(xiě)入如下內(nèi)容:
[mysqld] |
其中,int為一大于1且互不相等的正整數(shù),如2,3,4等。務(wù)必要正確設(shè)置每個(gè)機(jī)器上的/etc/my.cnf配置文件,尤其是server-id不能有重復(fù),這是一對(duì)多數(shù)據(jù)庫(kù)復(fù)制能否成功的關(guān)鍵[5]!
設(shè)定好上述/etc/my.cnf文件后啟動(dòng)Master上的MySQL數(shù)據(jù)庫(kù)服務(wù)時(shí)就自動(dòng)開(kāi)啟了二進(jìn)制更新日志功能。在Slave上啟動(dòng)MySQL時(shí)要加上--log-bin參數(shù),即可開(kāi)啟二進(jìn)制更新日志功能。在Slave機(jī)器上啟動(dòng)MySQL服務(wù)的命令如下:
# /app/mysql5/bin/mysqld_safe --user=mysql --log-bin & |
這樣做的目的為了實(shí)現(xiàn)冗余容錯(cuò)功能。當(dāng)主服務(wù)器Master出現(xiàn)故障停止服務(wù)時(shí),在預(yù)轉(zhuǎn)換角色成為Master的Slave上執(zhí)行STOP SLAVE; RESET MASTER SQL語(yǔ)句,在其它兩臺(tái)Slave上執(zhí)行CHANGE MASTER TO SQL語(yǔ)句,執(zhí)行STOP SLAVE; RESET MASTER SQL語(yǔ)句的Slave服務(wù)器即轉(zhuǎn)換成新的Master,其余兩臺(tái)機(jī)器則從新的Master復(fù)制數(shù)據(jù)庫(kù)數(shù)據(jù)(復(fù)制的是更新UPDATE、INSERT等操作,并不是簡(jiǎn)單的copy),從而實(shí)現(xiàn)冗余容錯(cuò)。
3.3 系統(tǒng)實(shí)現(xiàn)
完成上述準(zhǔn)備后可以開(kāi)始實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)的一對(duì)多復(fù)制,對(duì)應(yīng)用系統(tǒng)的數(shù)據(jù)庫(kù)訪問(wèn)代碼進(jìn)行優(yōu)化,使更新操作UPDATE、INSERT等SQL語(yǔ)句定向到Master服務(wù)器,查詢檢索SELECT語(yǔ)句定向到Slave服務(wù)器,從而實(shí)現(xiàn)負(fù)載均衡;當(dāng)主服務(wù)器Master出現(xiàn)故障停止服務(wù)時(shí),通過(guò)服務(wù)器角色轉(zhuǎn)換實(shí)現(xiàn)冗余容錯(cuò);上述所有服務(wù)器通過(guò)高速核心交換機(jī)連接在一起,協(xié)同工作,提供集群(Cluster)性能。下面,本文就此舉一簡(jiǎn)例,具體說(shuō)明實(shí)現(xiàn)(Implementation)步驟。
3.3.1 準(zhǔn)備主服務(wù)器
(1). 在主服務(wù)器上創(chuàng)建示例數(shù)據(jù)庫(kù)repl_db
從本地或遠(yuǎn)程終端登錄到Master服務(wù)器,執(zhí)行CREATE DATABASE repl_db;語(yǔ)句,創(chuàng)建示例數(shù)據(jù)庫(kù)repl_db。建立表repl_table:
mysql>CREATE TABLE repl_table (f1 INT, f2 VARCHAR(20)) ; |
向表中添加數(shù)據(jù):
mysql>INSERT INTO repl_table (f1, f2) VALUES(1, ‘first’); |
(2). 授予Slave復(fù)制(Replication)權(quán)限
授予從屬服務(wù)器Slave進(jìn)行復(fù)制的權(quán)限。假設(shè)從屬服務(wù)器連接到主服務(wù)器復(fù)制的用戶名為“repl”,密碼為“g00r002b”:
mysql>GRANT REPLICATION SLAVE ON *.* TO repl@’%’ IDENTIFIED BY ‘g00r002b’;
刷新系統(tǒng)權(quán)限表,鎖定寫(xiě)入語(yǔ)句操作:
mysql>FLUSH TABLES WITH READ LOCK; |
這時(shí)所有寫(xiě)入操作都被鎖定,包括支持事務(wù)(Transaction)特性的InnoDB類型表的提交(COMMIT)操作也被鎖定,為數(shù)據(jù)庫(kù)初始復(fù)制(copy)做好準(zhǔn)備。
(3). 簡(jiǎn)單備份repl_db
在此,通過(guò)tar命令把數(shù)據(jù)庫(kù)初始數(shù)據(jù)備份到/tmp目錄。
# tar –cvf /tmp/mysql-data.tar /app/mysql5/data/repl_db |
(4). 記錄主服務(wù)器狀態(tài)
執(zhí)行SHOW MASTER STATUS 語(yǔ)句:
mysql> SHOW MASTER STATUS; |
記下File和Position兩個(gè)參數(shù)的值,從屬服務(wù)器Slave為了復(fù)制(replication)連接到主服務(wù)器Master時(shí)要用到這兩個(gè)參數(shù),如果參數(shù)與此不符將導(dǎo)致復(fù)制(replication)失敗!
(5). 釋放主服務(wù)器表級(jí)寫(xiě)入鎖定
mysql>UNLOCK TABLES; |
至此,主服務(wù)器解除寫(xiě)入鎖定,一對(duì)多復(fù)制準(zhǔn)備工作已全部完成,準(zhǔn)備接受Slave的復(fù)制(replication)連接。
3.3.2 準(zhǔn)備從屬服務(wù)器
(1). 停止從屬服務(wù)器的MySQL數(shù)據(jù)庫(kù)服務(wù)
# /app/mysql5/bin/mysqladmin –uroot –p shutdown |
輸入MySQL系統(tǒng)root用戶密碼,MySQL服務(wù)停止。
(2). 簡(jiǎn)單copy數(shù)據(jù)庫(kù)初始數(shù)據(jù)
在從屬服務(wù)器上執(zhí)行ftp操作,訪問(wèn)主服務(wù)器,下載/tmp/mysql-data.tar文件,在/app/mysql5/data目錄下執(zhí)行如下操作,把初始數(shù)據(jù)copy到Slave服務(wù)器:
[root@FreebsdSlave1 /app/mysql5/data]# tar –xvf /tmp/msyql-data.tar |
其它兩臺(tái)Slave服務(wù)器執(zhí)行同樣操作,實(shí)現(xiàn)數(shù)據(jù)庫(kù)初始數(shù)據(jù)的簡(jiǎn)單copy。
(3). 重啟從屬服務(wù)器上的MySQL數(shù)據(jù)庫(kù)服務(wù)
# /app/mysql5/bin/mysqld_safe –-user=mysql –-log-bin & |
從屬服務(wù)器已啟動(dòng),同時(shí)啟動(dòng)二進(jìn)制更新日志功能,為角色轉(zhuǎn)換做好準(zhǔn)備。
(4). 登錄到從屬服務(wù)器Slave的MySQL客戶端
# /app/mysql/bin/msyql –uroot -p |
(5). 啟動(dòng)從屬服務(wù)器上的復(fù)制(replication)線程
mysql> CHANGE MASTER TO |
在所有從屬服務(wù)器上執(zhí)行相同的操作,自此從屬服務(wù)器已連接到主服務(wù)器,開(kāi)始真正意義上的replication工作。測(cè)試從屬服務(wù)器的復(fù)制工作是否正常:
mysql>show slave status\G |
看到上述信息說(shuō)明從屬服務(wù)器已啟動(dòng)了與replication相關(guān)的線程I/O和SQL,一對(duì)多的replication已經(jīng)開(kāi)始工作。
(6). 功能測(cè)試
在主服務(wù)器上寫(xiě)入新的數(shù)據(jù):
mysql>INSERT INTO repl_table (f1, f2) VALUES(2, ‘second’);
|
在Slave上執(zhí)行相同的查詢操作:
mysql>SELECT * FROM repl_table; |
得到相同的查詢結(jié)果,說(shuō)明復(fù)制(replication)機(jī)制已成功開(kāi)始工作!
3.3.3 配置網(wǎng)絡(luò)DNS服務(wù)器
在BIND DNS服務(wù)器中,為上述三臺(tái)從屬服務(wù)器Slave配置同一個(gè)名字,客戶端的查詢檢索操作將由DNS服務(wù)器定向到其中的一臺(tái)Slave。因此,對(duì)于同一名字,不同的客戶端會(huì)定向到不同的地址,訪問(wèn)不同的MySQL服務(wù)器,從而達(dá)到負(fù)載均衡的目的。假設(shè)用戶為三臺(tái)Slave分配的DNS名字為mysqlslave.yourdomain,DNS服務(wù)器區(qū)域文件/var/named/yourdomain.zone中應(yīng)包含如下數(shù)據(jù)項(xiàng)[6]:
sqlmaster.yourdomain. IN A 192.168.1.100 |
當(dāng)客戶端進(jìn)行查詢操作時(shí),提交給主機(jī)sqlslave.yourdomain的請(qǐng)求將由DNS服務(wù)器隨機(jī)定向到三臺(tái)Slave中的一臺(tái),由其執(zhí)行查詢作業(yè),返回結(jié)果。從而在三臺(tái)Slave之間實(shí)現(xiàn)查詢級(jí)別的負(fù)載均衡。
3.3.4 應(yīng)用系統(tǒng)程序代碼優(yōu)化
實(shí)際應(yīng)用中,對(duì)數(shù)據(jù)庫(kù)的寫(xiě)入操作相對(duì)查詢操作少得多,因此,優(yōu)化應(yīng)用程序的數(shù)據(jù)庫(kù)連接代碼,把寫(xiě)入操作定向到Master服務(wù)器,查詢操作定向到Slave服務(wù)器,提供主服務(wù)器和從屬服務(wù)器之間更新、查詢的負(fù)載均衡功能。本文以PHP數(shù)據(jù)庫(kù)連接代碼為例,簡(jiǎn)要介紹代碼優(yōu)化方法[7]。
(1). 準(zhǔn)備不同的數(shù)據(jù)庫(kù)連接配置文件
準(zhǔn)備兩個(gè)數(shù)據(jù)庫(kù)連接文件mysql_connect_master.php和mysql_connect_slave.php,其文件內(nèi)容如下:
mysql_connect_master.php文件的內(nèi)容: |
(2). 優(yōu)化程序SQL語(yǔ)句代碼
對(duì)應(yīng)用程序中訪問(wèn)數(shù)據(jù)庫(kù)的代碼段做出如下優(yōu)化:
|
說(shuō)明:每當(dāng)向MySQL服務(wù)器提交數(shù)據(jù)庫(kù)操作時(shí),加入一個(gè)if-else判斷語(yǔ)句對(duì)變量$sql進(jìn)行判斷定向,如果是SELECT查詢操作,將其定向到從屬服務(wù)器Slave中的一個(gè);如果是其它更新語(yǔ)句,則將其定向到主服務(wù)器Master。此處代碼段是應(yīng)用系統(tǒng)實(shí)現(xiàn)負(fù)載均衡的關(guān)鍵,用戶務(wù)必根據(jù)自己實(shí)際情況,寫(xiě)出準(zhǔn)確無(wú)誤的代碼。每次對(duì)數(shù)據(jù)庫(kù)操作完畢都要及時(shí)釋放數(shù)據(jù)庫(kù)連接,以免更新、查詢操作分別定向失敗,影響系統(tǒng)負(fù)載均衡功能。這樣做雖然在一定程度上增加Web服務(wù)器或應(yīng)用服務(wù)器的開(kāi)銷,但與MySQL服務(wù)器集群負(fù)載均衡功能帶來(lái)的大幅性能提升及冗余容錯(cuò)特性相比,這個(gè)開(kāi)銷絕對(duì)是物超所值!
3.4 注意事項(xiàng)
正確部署實(shí)現(xiàn)具有負(fù)載均衡功能的MySQL服務(wù)器集群必須注意以下事項(xiàng):
(1). MySQL數(shù)據(jù)庫(kù)復(fù)制(replication)特性是核心
此處的復(fù)制不是簡(jiǎn)單的copy,從屬服務(wù)器啟動(dòng)兩個(gè)線程(thread):I/O線程和SQL線程,I/O線程接收主服務(wù)器對(duì)參與復(fù)制數(shù)據(jù)庫(kù)的更新操作事件(event),并記入自己的中繼二進(jìn)制更新日志文件(hostname-relay-bin.00000n),由SQL線程將更新操作寫(xiě)入自己的數(shù)據(jù)庫(kù)表項(xiàng)。主從服務(wù)器之間復(fù)制的不是具體的數(shù)據(jù)內(nèi)容,而是具體的以二進(jìn)制格式記錄的操作事件,因而在一定程度上實(shí)現(xiàn)主從服務(wù)器之間的數(shù)據(jù)同步。(這種復(fù)制類似于生物學(xué)意義上的按基因復(fù)制,在英語(yǔ)中replication的主要詞義就是指該種復(fù)制。)
(2). 復(fù)制的復(fù)雜性
主從數(shù)據(jù)庫(kù)服務(wù)器間的replication要求Master與Slave上的MySQL版本最好一致,主從服務(wù)器必須設(shè)置相同的字符集,否則很容易造成復(fù)制失敗。主服務(wù)器上更新權(quán)限表內(nèi)容的FLUSH語(yǔ)句不會(huì)被復(fù)制[8]。
(3). 按照范式化要求設(shè)計(jì)數(shù)據(jù)庫(kù)
生產(chǎn)環(huán)境下基于MySQL服務(wù)器的應(yīng)用系統(tǒng)要想穩(wěn)定運(yùn)行,按范式化設(shè)計(jì)系統(tǒng)數(shù)據(jù)庫(kù)是基本要求,具體內(nèi)容可參考相關(guān)書(shū)籍。
(4). 打開(kāi)數(shù)據(jù)庫(kù)服務(wù)器的遠(yuǎn)程用戶連接功能
打開(kāi)主從服務(wù)器的遠(yuǎn)程用戶連接是實(shí)現(xiàn)更新、查詢操作分別定向的必要條件,否則,來(lái)自應(yīng)用服務(wù)器的連接請(qǐng)求失敗,影響系統(tǒng)應(yīng)用正常運(yùn)行。
(5). 負(fù)載均衡功能的實(shí)現(xiàn)需要良好的團(tuán)隊(duì)合作
BIND DNS服務(wù)器實(shí)現(xiàn)了從屬服務(wù)器Slave之間的負(fù)載均衡,Slave和Master之間的負(fù)載均衡則由應(yīng)用系統(tǒng)開(kāi)發(fā)人員在程序代碼級(jí)實(shí)現(xiàn)。整個(gè)系統(tǒng)的性能提升和冗余容錯(cuò)需要網(wǎng)絡(luò)管理和應(yīng)用系統(tǒng)開(kāi)發(fā)團(tuán)隊(duì)之間的良好合作,否則負(fù)載均衡功能的實(shí)現(xiàn)就會(huì)失敗。
4. 常見(jiàn)問(wèn)題
(1). 如何估算MySQL服務(wù)器集群的性能提升量?
針對(duì)本文采用的結(jié)構(gòu)模式,可對(duì)應(yīng)用系統(tǒng)整體性能提升做出大致估算。假設(shè)應(yīng)用系統(tǒng)寫(xiě)操作占10%,讀操作占90%,寫(xiě)操作耗時(shí)是讀操作的2倍,系統(tǒng)的吞吐量(throughput)為T(用reads/s讀操作次數(shù)/秒來(lái)衡量)。把寫(xiě)操作線性轉(zhuǎn)換為讀操作,則有:
T= 2Xwrites + 9Xwrites ==>writes=T/11① (不采用主從復(fù)制模式,讀寫(xiě)操作集中到一個(gè)服務(wù)器上)
T= 2Xwrites + 9Xwrites/N ==> writes=T/(2+9/N)② (采用一對(duì)多的主從復(fù)制模式,讀操作在從屬服務(wù)器,寫(xiě)操作在主服務(wù)器)
其中,writes為系統(tǒng)單位時(shí)間內(nèi)所能承受的最大寫(xiě)操作次數(shù),N為從屬服務(wù)器個(gè)數(shù),N大于等于2。在不采用主從復(fù)制模式時(shí),系統(tǒng)性能writes=T/11;采用本文一對(duì)三的復(fù)制模式時(shí),系統(tǒng)性能writes=T/5。采用負(fù)載均衡模式與不采用系統(tǒng)性能之比為11:5,即2.2:1,考慮到應(yīng)用服務(wù)器的額外開(kāi)銷,系統(tǒng)整體性能提升了整整1倍!從②式可以看出,系統(tǒng)整體性能理論極限為T/2,當(dāng)然在實(shí)際生產(chǎn)環(huán)境中不可能達(dá)到。具體部署時(shí)用戶可以根據(jù)自己的實(shí)際情況估算出合理的從屬服務(wù)器數(shù)量,主要影響因素是網(wǎng)絡(luò)帶寬和機(jī)器整體性能[9]。
(2). 如何應(yīng)對(duì)主從服務(wù)器崩潰?
當(dāng)某臺(tái)從屬服務(wù)器崩潰時(shí),修復(fù)故障重啟后重新連接到主服務(wù)器,根據(jù)其master.info文件更新其數(shù)據(jù),保持與主服務(wù)器的數(shù)據(jù)同步。如果主服務(wù)器崩潰,在某一從屬服務(wù)器上執(zhí)行STOP SLAVES; GRANT REPLICATION SLAVE ON *.* repl_db TO‘repl’@’%’IDENTIFIED BY ‘g00r002b’;RESET MASTER;這三個(gè)SQL語(yǔ)句,由于從屬服務(wù)器已啟動(dòng)了二進(jìn)制更新日志功能,因此具備了角色轉(zhuǎn)換的必要條件。更改其主機(jī)名、IP地址及server-id與Master一樣,重啟MySQL服務(wù)器,系統(tǒng)開(kāi)始正常對(duì)外提供服務(wù)。其它兩臺(tái)從屬服務(wù)器則不需執(zhí)行任何操作,繼續(xù)執(zhí)行replication過(guò)程。BIND DNS服務(wù)器和應(yīng)用程序也不需做任何調(diào)整,繼續(xù)對(duì)系統(tǒng)用戶提供不間斷服務(wù)。主服務(wù)器排除故障恢復(fù)正常后,將其網(wǎng)絡(luò)配置改為與現(xiàn)有Master轉(zhuǎn)換角色之前一樣的配置,重啟MySQL服務(wù),將其角色轉(zhuǎn)換為從屬服務(wù)器。也就是說(shuō),整個(gè)集群機(jī)器的角色可以相互循環(huán)轉(zhuǎn)換,提高系統(tǒng)的冗余性和可靠性。在此需要注意的是,在應(yīng)用系統(tǒng)調(diào)試運(yùn)行正常之后,在Slave角色服務(wù)器的/etc/my.cnf文件[mysqld]段加入slave-skip-errors=all,保證集群之間復(fù)制(replication)的正常運(yùn)行。
5. 結(jié)束語(yǔ)
部署與實(shí)現(xiàn)具有負(fù)載均衡功能的MySQL服務(wù)器集群是一項(xiàng)復(fù)雜的系統(tǒng)工程,需要多方面良好的協(xié)同合作才能做好。服務(wù)器的搭建配置、BIND DNS服務(wù)器的配置部署,以及應(yīng)用系統(tǒng)程序的開(kāi)發(fā)都要緊緊圍繞實(shí)現(xiàn)MySQL服務(wù)器集群負(fù)載均衡功能這個(gè)目標(biāo)。必須對(duì)主服務(wù)器的運(yùn)行狀態(tài)進(jìn)行動(dòng)態(tài)監(jiān)控,如果發(fā)生故障,立即執(zhí)行角色轉(zhuǎn)換過(guò)程,確保為終端用戶提供可靠、不間斷的服務(wù)??梢葬槍?duì)具體系統(tǒng)環(huán)境寫(xiě)出監(jiān)控腳本或程序,確保系統(tǒng)的可靠性與穩(wěn)定性。
【編輯推薦】