高可用性、負(fù)載均衡的mysql集群解決方案
一、mysql的市場占有率 二、mysql為什么受到如此的歡迎 三、mysql數(shù)據(jù)庫系統(tǒng)的優(yōu)缺點 四、網(wǎng)絡(luò)服務(wù)器的需求 五、什么是mysql的集群 六、什么是負(fù)載均衡 七、mysql集群部署和實現(xiàn)方法 八、負(fù)載均衡的配置和測試 九、Mysql集群系統(tǒng)的測試(測試方案+測試腳本+測試結(jié)果分析)
l mysql的市場占有率
MySQL是世界上最流行的開源數(shù)據(jù)庫,已有1100多萬的擊活安裝,每天超過五萬的下 載。MySQL為全球開發(fā)者、DBA和IT管理者在可靠性、性能、易用性方面提供了選 擇。
第三方市場調(diào)查機構(gòu)Evans Data Corporation調(diào)查顯示,過去兩年內(nèi)在開發(fā)者使用 的所有數(shù)據(jù)庫中,MySQL已經(jīng)擁有了25%的市場占有率。開源已經(jīng)成為當(dāng)今IT結(jié)構(gòu)中 不可或缺的重要部分,而且開源的市場占有率將繼續(xù)增加。如下圖所示:
l mysql為什么受到如此的歡迎
Sun公司今天1月份花了10億美元將mysql收購,準(zhǔn)備進軍開源和數(shù)據(jù)庫。
數(shù)據(jù)庫系統(tǒng) | Oracle | SQL Server | MySQL | DB2 | 是否免費 | 收費 | 收費 | 免費 | 收費 | 存儲過程 | 支持 | 支持 | 支持 | 支持 | 視圖 | 支持 | 支持 | 支持 | 支持 | 快照 | 支持 | 支持 | 不支持 | 支持 | 觸發(fā)器 | 支持 | 支持 | 支持 | 支持 | 安全 | 強 | 中 | 中 | 強 | 復(fù)雜查詢 | 強 | 中 | 弱 | 中 | 索引 | 豐富 | 一般 | 弱 | 中 | 數(shù)據(jù)類型 | 多 | 多 | 多 | 多 | 事務(wù)處理 | 強 | 強 | 弱 | 中 |
l mysql數(shù)據(jù)庫系統(tǒng)的優(yōu)缺點
每個系統(tǒng)都有自身的不足和發(fā)展歷程,mysql也一樣。
優(yōu)點 | 缺點 | 1. 源碼公開,免費 2. 跨平臺 3. 為多種開發(fā)語言和包提供了API 4. 支持多線程 5. 小巧、靈活、速度較快 6. 支持各種字符集 7. 提供各種連接、優(yōu)化的工具包
| 1. 不完善,很多數(shù)據(jù)庫特性不支持 2. 只適合中小型應(yīng)用,對于大型應(yīng)用,可以跟其他數(shù)據(jù)庫互補; 3. 數(shù)據(jù)庫系統(tǒng)數(shù)據(jù)量只能達到千萬級別;
|
l 網(wǎng)絡(luò)服務(wù)的需求
隨著Internet的飛速發(fā)展和對我們生活的深入影響,越來越多的個人在互聯(lián)網(wǎng)上購物、娛 樂、休閑、與人溝通、獲取信息;越來越多的企業(yè)把他們與顧客和業(yè)務(wù)伙伴之間的聯(lián)絡(luò) 搬到互聯(lián)網(wǎng)上,通過網(wǎng)絡(luò)來完成交易,建立與客戶之間的聯(lián)系;ヂ(lián)網(wǎng)的用戶數(shù)和網(wǎng)絡(luò) 流量正以幾何級數(shù)增長,這對網(wǎng)絡(luò)服務(wù)的可伸縮性提出很高的要求。例如,比較熱門的Web 站點會因為被訪問次數(shù)急劇增長而不能及時處理用戶的請求,導(dǎo)致用戶進行長時間的等待 ,大大降低了服務(wù)質(zhì)量。另外,隨著電子商務(wù)等關(guān)鍵性應(yīng)用在網(wǎng)上運行,任何例外的服務(wù) 中斷都將造成不可估量的損失,服務(wù)的高可用性也越來越重要。所以,對用硬件和軟件方 法實現(xiàn)高可伸縮、高可用網(wǎng)絡(luò)服務(wù)的需求不斷增長,這種需求可以歸結(jié)以下幾點:
1) 可伸縮性(Scalability),當(dāng)服務(wù)的負(fù)載增長時,系統(tǒng)能被擴展來滿足需求,且不降 低服務(wù)質(zhì)量。 2) 高可用性(Availability),盡管部分硬件和軟件會發(fā)生故障,整個系統(tǒng)的服務(wù)必須是 每天24小時每星期7天可用的。 3) 可管理性(Manageability),整個系統(tǒng)可能在物理上很大,但應(yīng)該容易管理。 4) 價格有效性(Cost-effectiveness),整個系統(tǒng)實現(xiàn)是經(jīng)濟的、易支付的。
單服務(wù)器顯然不能處理不斷增長的負(fù)載。這種服務(wù)器升級方法有下列不足:一是升級過 程繁瑣,機器切換會使服務(wù)暫時中斷,并造成原有計算資源的浪費;二是越往高端的服務(wù) 器,所花費的代價越大;三是一旦該服務(wù)器或應(yīng)用軟件失效,會導(dǎo)致整個服務(wù)的中斷。
通過高性能網(wǎng)絡(luò)或局域網(wǎng)互聯(lián)的服務(wù)器集群正成為實現(xiàn)高可伸縮的、高可用網(wǎng)絡(luò)服務(wù)的有 效結(jié)構(gòu)。這種松耦合結(jié)構(gòu)比緊耦合的多處理器系統(tǒng)具有更好的伸縮性和性能價格比,組成 集群的PC服務(wù)器或RISC服務(wù)器和標(biāo)準(zhǔn)網(wǎng)絡(luò)設(shè)備因為大規(guī)模生產(chǎn),價格低,具有很高的性能 價格比。但是,這里有很多挑戰(zhàn)性的工作,如何在集群系統(tǒng)實現(xiàn)并行網(wǎng)絡(luò)服務(wù),它對外是 透明的,它具有良好的可伸縮性和可用性。
針對上述需求,我們給出了基于IP層和基于內(nèi)容請求分發(fā)的負(fù)載平衡調(diào)度解決方法,并在 Linux內(nèi)核中實現(xiàn)了這些方法,將一組服務(wù)器構(gòu)成一個實現(xiàn)可伸縮的、高可用網(wǎng)絡(luò)服務(wù)的服 務(wù)器集群,我們稱之為Linux虛擬服務(wù)器(Linux Virtual Server)。在LVS集群中,使得 服務(wù)器集群的結(jié)構(gòu)對客戶是透明的,客戶訪問集群提供的網(wǎng)絡(luò)服務(wù)就像訪問一臺高性能、 高可用的服務(wù)器一樣?蛻舫绦虿皇芊⻊(wù)器集群的影響不需作任何修改。系統(tǒng)的伸縮性通 過在服務(wù)機群中透明地加入和刪除一個節(jié)點來達到,通過檢測節(jié)點或服務(wù)進程故障和正 確地重置系統(tǒng)達到高可用性。
l 什么是mysql集群
分為同步集群和異步集群。
同步集群(mysql cluster) 結(jié)構(gòu):(data + sql + mgm節(jié)點) 特點: 1) 內(nèi)存級別的,對硬件要求較低,但是對內(nèi)存要求較大。換算比例為:1:1.1; 2) 數(shù)據(jù)同時放在幾臺服務(wù)器上,冗余較好; 3) 速度一般; 4) 建表需要聲明為engine=ndbcluster 5) 擴展性強; 6) 可以實現(xiàn)高可用性和負(fù)載均衡,實現(xiàn)對大型應(yīng)用的支持; 7) 必須是特定的mysql版本,如:已經(jīng)編譯好的max版本; 8) 配置和管理方便,不會丟失數(shù)據(jù);
異步集群(mysql replication) 結(jié)構(gòu):(master + slave) 特點: 1) 主從數(shù)據(jù)庫異步數(shù)據(jù); 2) 數(shù)據(jù)放在幾臺服務(wù)器上,冗余一般; 3) 速度較快; 4) 擴展性差; 5) 無法實現(xiàn)高可用性和負(fù)載均衡(只能在程序級別實現(xiàn)讀寫分離,減輕對主數(shù)據(jù)庫的壓力); 6) 配置和管理較差,可能會丟失數(shù)據(jù);
l 什么是負(fù)載均衡
通過director,將用戶的請求分發(fā)到real server服務(wù)器上,然后返回給用戶。 負(fù)載均衡部署靈活、能夠滿足各種需求。
實現(xiàn)方式: 硬件:BIG/IP、Cisco、IBM(昂貴)
軟件:LVS(免費) LVS系統(tǒng)將用戶的請求的數(shù)據(jù)包在數(shù)據(jù)層和網(wǎng)絡(luò)層進行了封裝和轉(zhuǎn)發(fā),由三種方式滿足各種需求。
1) DR:直接路由 2) Tuning:tcp/ip隧道 3) NAT:網(wǎng)絡(luò)地址轉(zhuǎn)換
需求: 免費的軟件包 1) 2臺低端的director(active和standby) 2) 心跳線:連接2臺director,檢測活動情況 3) 2臺以上的real servers
通用結(jié)構(gòu):
有興趣的可以分別研究上面的三種LVS結(jié)構(gòu)。
l mysql集群部署和實現(xiàn)方法
1) 假設(shè)現(xiàn)在有4臺服務(wù)器(mysql官方推薦的最小配置)
服務(wù)器 | 開啟的服務(wù) | 角色 | 192.168.131.164 Ndb1 | Mysqld | Mysql API | Ndb_mgmd | 管理節(jié)點(master) | Heartbeat | Director(master) | 192.168.131.26 Ndb2 | Mysqld | Mysql API | Ndb_mgmd | 管理節(jié)點(backup) | Heartbeat | Director(standby) | 192.168.131.77 Sql1 | Mysqld | Mysql API(realserver) | Ndbd | 存儲節(jié)點 | Arptables | 訪問路由 | 192.168.131.101 Sql2 | Mysqld | Mysql API(realserver) | Ndbd | 存儲節(jié)點 | Arptables | 訪問路由 |
2)服務(wù)器安裝配置和網(wǎng)絡(luò)連接 (以下為所有服務(wù)器各操作一遍,共4遍) 安裝: 將4臺服務(wù)器安裝CentOS 5.2,選擇下面的包: Clustering Storage Clustering mysql不需要安裝,但perl-mysql-xxx的所有包需要安裝 開發(fā)工具包和類庫 sshd服務(wù) SElinux ==>disable 語言支持包不安裝,默認(rèn)美國英語
設(shè)定主機名: Vi /etc/sysconfig/network Hostname=xxx :wq
檢查主機名: Uname -a 必須和上表中的一一對應(yīng)。否則有問題。
Vi /etc/hosts Ndb1 192.168.131.164 Ndb2 192.168.131.26 Sql1 192.168.131.77 Sql2 192.168.131.101
更新: #rpm --import http://dries.ulyssis.org/rpm/RPM-GPG-KEY.dries.txt #yum update -y && yum -y install lynx libawt xorg-x11-deprecated-libs nx freenx arptables_jf httpd-devel
下載: Mysql cluster版本(我下載的5.0.67社區(qū)版本): [root@ndb1 RHEL5]# ls -lh MySQL* | awk '{print $9}' MySQL-client-community-5.0.67-0.rhel5.i386.rpm MySQL-clusterextra-community-5.0.67-0.rhel5.i386.rpm MySQL-clustermanagement-community-5.0.67-0.rhel5.i386.rpm MySQL-clusterstorage-community-5.0.67-0.rhel5.i386.rpm MySQL-clustertools-community-5.0.67-0.rhel5.i386.rpm MySQL-devel-community-5.0.67-0.rhel5.i386.rpm MySQL-server-community-5.0.67-0.rhel5.i386.rpm MySQL-shared-community-5.0.67-0.rhel5.i386.rpm MySQL-shared-compat-5.0.67-0.rhel4.i386.rpm MySQL-shared-compat-5.0.67-0.rhel5.i386.rpm MySQL-test-community-5.0.67-0.rhel5.i386.rpm perl-HTML-Template-2.9-1.el5.rf.noarch.rpm [root@ndb1 RHEL5]#
在服務(wù)器上安裝以上包,在安裝的過程中如果缺少包或者庫,采用: yum install xxxx自行安裝。
建立目錄: #mkdir /var/lib/mysql-cluster -p
以下分別操作: 安裝cluster組件: #Rpm -Uvh MySQL-xx-xx.rpm,根據(jù)不同,可以少安裝部分組件。根據(jù)你需要而定。
163、26上,我安裝了: [root@ndb1 RHEL5]# rpm -aq | grep MySQL MySQL-clusterstorage-community-5.0.67-0.rhel5 MySQL-clustertools-community-5.0.67-0.rhel5 MySQL-clustermanagement-community-5.0.67-0.rhel5 MySQL-shared-community-5.0.67-0.rhel5 perl-DBD-MySQL-3.0007-1.fc6 MySQL-server-community-5.0.67-0.rhel5 [root@ndb1 RHEL5]#
101、77上,我安裝了: [root@sql1 ~]# rpm -aq | grep MySQL MySQL-clusterstorage-community-5.0.67-0.rhel4 MySQL-devel-community-5.0.67-0.rhel4 MySQL-server-community-5.0.67-0.rhel4 MySQL-client-community-5.0.67-0.rhel4 MySQL-shared-community-5.0.67-0.rhel4 [root@sql1 ~]#
以下在ndb1(164)和ndb2(26)上操作 [root@ndb1 ~]# vi /var/lib/mysql-cluster/config.ini [NDBD DEFAULT] NoOfReplicas=2 DataMemory=800M IndexMemory=400M
[MYSQLD DEFAULT]
[NDB_MGMD DEFAULT]
[TCP DEFAULT]
# Section for the cluster management node [NDB_MGMD] # IP address of the management node (this system) ID=1 HostName=192.168.131.164
[NDB_MGMD] # IP address of the management node (this system) ID=2 HostName=192.168.131.26
# Section for the storage nodes [NDBD] # IP address of the first storage node HostName=192.168.131.77 DataDir= /var/lib/mysql-cluster
[NDBD] # IP address of the second storage node HostName=192.168.131.101 DataDir=/var/lib/mysql-cluster
# one [MYSQLD] per storage node [MYSQLD] [MYSQLD] [MYSQLD] [MYSQLD] [MYSQLD] [MYSQLD] [MYSQLD] :wq
以下在mysql API上操作(這里,我設(shè)定了7個API,以后可以隨時加入)
Mysqld API的配置文件: Vi /etc/my.cnf [root@ndb1 ~]# cat /etc/my.cnf [mysqld] ndbcluster ndb-connectstring = "host=192.168.131.164,host=192.168.131.26"
[ndb_mgm] connect-string = "host=192.168.131.164,host=192.168.131.26"
[ndbd] connect-string = "host=192.168.131.164,host=192.168.131.26" :wq
分別啟動ndb_mgmd/ndbd/mysqld 164/26: ndb_mgmd -f /var/lib/mysql-cluster/config.ini
77/101: Ndbd --initial
164/26/77/101: /etc/rc.d/init.d/mysql start
在管理節(jié)點ndb1(164)和ndb2(26)上查看各節(jié)點的情況: [root@ndb1 ~]# ndb_mgm -- NDB Cluster -- Management Client -- ndb_mgm> show Connected to Management Server at: 192.168.131.164:1186 Cluster Configuration --------------------- [ndbd(NDB)] 2 node(s) id=3 @192.168.131.77 (Version: 5.0.67, Nodegroup: 0, Master) id=4 @192.168.131.101 (Version: 5.0.67, Nodegroup: 0)
[ndb_mgmd(MGM)] 2 node(s) id=1 @192.168.131.164 (Version: 5.0.67) id=2 @192.168.131.26 (Version: 5.0.67)
[mysqld(API)] 7 node(s) id=5 @192.168.131.101 (Version: 5.0.67) id=6 @192.168.131.26 (Version: 5.0.67) id=7 @192.168.131.164 (Version: 5.0.67) id=8 @192.168.131.77 (Version: 5.0.67) id=9 (not connected, accepting connect from any host) id=10 (not connected, accepting connect from any host) id=11 (not connected, accepting connect from any host)
ndb_mgm>
以上說明一切正常。
將服務(wù)增加到開機啟動服務(wù)項中: 164/26: echo 'ndb_mgmd -f /var/lib/mysql-cluster/config.ini' > /etc/rc.d/init.d/ndb_mgmd chmod 755 /etc/rc.d/init.d/ndb_mgmd
77/101: Echo 'ndbd' > /etc/rc.d/init.d/ndbd Chmod 755 /etc/rc.d/init.d/ndbd Chkconfig --level 2345 ndbd on
OK,到此mysql cluster 配置完成。
強調(diào): 1)由于數(shù)據(jù)放在內(nèi)存中,需要在ndb節(jié)點上加大內(nèi)存的數(shù)量。按照1:1.1的比例,如果數(shù)據(jù)量達到3.6GB,需要4GB的內(nèi)存。 2)由于NDB和mysqld(API)都很耗費內(nèi)存,所以建議將NDB放在164和26上。可能啟動的時候會有警告,但是沒關(guān)系的。
查看數(shù)據(jù)和內(nèi)存情況: 77: [root@sql2 ~]# top top - 16:39:36 up 1:59, 1 user, load average: 1.37, 0.76, 0.60 Tasks: 80 total, 2 running, 78 sleeping, 0 stopped, 0 zombie Cpu(s): 4.0%us, 4.0%sy, 0.0%ni, 87.3%id, 2.9%wa, 0.2%hi, 1.5%si, 0.0%st Mem: 2075600k total, 2005868k used, 69732k free, 68256k buffers Swap: 2031608k total, 0k used, 2031608k free, 1400812k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2306 mysql 25 0 119m 15m 3952 S 22 0.8 10:20.94 mysqld 23791 root 15 0 1587m 484m 31m R 20 23.9 9:34.97 ndbd
由于77只有2GB的內(nèi)存,而在config.ini中,把1.2GB的內(nèi)存分配給了NDB,所以,加上mysqld用掉的,2GB的內(nèi)存似乎已經(jīng)所剩無幾了。
查看77上的數(shù)據(jù)大。 [root@sql2 ~]# cd /var/lib/mysql-cluster/ndb_4_fs/ [root@sql2 ndb_4_fs]# du -lh 1.3GB
連接API創(chuàng)建數(shù)據(jù)庫: 由于上面4臺都做為mysqld 的API,所以創(chuàng)建數(shù)據(jù)庫的時候,都需要創(chuàng)建一遍。 以下操作在4臺API上都需要操作: # Mysql -uroot -pxxxxxxxxxxxx -A Mysql> create database testdatabase; Mysql> grant all on *.testdatabase to root@'192.168.131.%' identified by 'xxxxxxxxxxxxxxx'; Mysql> flush privileges; Mysql> create table test(int (1)); Mysql> insert into test(1); Mysql> quit;
以上做完以后,可以通過任意一臺API上創(chuàng)建表,并寫數(shù)據(jù)到表中,其他數(shù)據(jù)庫都會同步寫入。
分別連接每臺服務(wù)器進行檢查: # Mysql -uroot -pxxxxxxxxxxxx -A Mysql> use testdatabase; Mysql> select * from test; 如果輸出結(jié)果完全相同,表明mysql cluster已經(jīng)可以正常工作了。
在2臺API上設(shè)置LVS
Mysql cluster做好以后,數(shù)據(jù)庫分別建立同名的數(shù)據(jù)庫以后,權(quán)限分配好,然后只要在一臺上寫入數(shù)據(jù),其他的NDB就存儲了相同的數(shù)據(jù)。
用
程序連接任意一臺API寫數(shù)據(jù),如果程序中未設(shè)置API的選擇和判斷,只使用了其中一個API,一旦API當(dāng)機,則無法寫入數(shù)據(jù),必須修改程序。即便做了
API的判斷和選擇,因為沒有實現(xiàn)負(fù)載均衡,服務(wù)器的性能沒有充分利用。高可用性也沒有達到目標(biāo)。所以,我們現(xiàn)在在2臺API之間做LVS。
LVS采用 ultramonkey(http://www.ultramonkey.org)
首先在NDB1(164)和NDB2(26)上下載heartbeat的軟件包: 下載所有的rpm包: Cd /usr/local/src Mkdir heartbeat Cd heartbeat #Wget xxx.xxx.rpm
我下載了如下的軟件包: [root@ndb1 heartbeat]# ls -lh *.rpm | awk '{print $9}'; arptables-noarp-addr-0.99.2-1.rh.el.um.1.noarch.rpm heartbeat-1.2.3.cvs.20050927-1.rh.el.um.4.i386.rpm heartbeat-ldirectord-1.2.3.cvs.20050927-1.rh.el.um.4.i386.rpm heartbeat-pils-1.2.3.cvs.20050927-1.rh.el.um.4.i386.rpm heartbeat-stonith-1.2.3.cvs.20050927-1.rh.el.um.4.i386.rpm ipvsadm-1.21-1.rh.el.1.um.1.i386.rpm libnet-1.1.2.1-1.rh.el.um.1.i386.rpm perl-Authen-SASL-2.08-1.rh.el.um.1.noarch.rpm perl-Convert-ASN1-0.18-1.rh.el.um.1.noarch.rpm perl-IO-Socket-SSL-0.96-1.rh.el.um.1.noarch.rpm perl-ldap-0.3202-1.rh.el.um.1.noarch.rpm perl-Mail-IMAPClient-2.2.9-1.rh.el.um.1.noarch.rpm perl-Net-SSLeay-1.25-1.rh.el.um.1.i386.rpm perl-Parse-RecDescent-1.94-1.el5.rf.noarch.rpm perl-Parse-RecDescent-1.94-1.rh.el.um.1.noarch.rpm perl-XML-NamespaceSupport-1.08-1.rh.el.um.1.noarch.rpm perl-XML-SAX-0.12-1.rh.el.um.1.noarch.rpm [root@ndb1 heartbeat]#
Heartbeat中包含以下幾部分: 1) Master Director(分發(fā)器)-- MD 2) Backup Director(備份分發(fā)器)-- BD 3) Real server (真實服務(wù)器,可以有2個以上)--RS
IP設(shè)置并確認(rèn): MD: Eth0:192.168.131.164/24/GW:192.168.131.1 Eth1:10.9.30.1/24
MD: Eth0:192.168.131.26/24/GW:192.168.131.1 Eth1:10.9.30.2
VIP:192.168.131.105/24/GW:192.168.131.1 -- 用戶訪問的統(tǒng)一虛擬IP
RS1:192.168.131.101/24/GW:192.168.131.1 RS2:192.168.131.77/24/GW:192.168.131.1 。。。 等等
以下操作在所有服務(wù)器上執(zhí)行:
主機名確認(rèn): 分別執(zhí)行: #uname -a 主機名對應(yīng)表中所列。
在MD和BD修改IP轉(zhuǎn)發(fā): #vi modprobe.sh modprobe ip_vs_dh modprobe ip_vs_ftp modprobe ip_vs modprobe ip_vs_lblc modprobe ip_vs_lblcr modprobe ip_vs_lc modprobe ip_vs_nq modprobe ip_vs_rr modprobe ip_vs_sed modprobe ip_vs_sh modprobe ip_vs_wlc modprobe ip_vs_wrr :wq |