国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

基于MySQL的數(shù)據(jù)庫集群系統(tǒng)的實現(xiàn)

2024-07-24 12:54:40
字體:
供稿:網(wǎng)友
您的webapp系統(tǒng)是否正在使用一個mysql的數(shù)據(jù)庫系統(tǒng)?您的客戶是不是總是抱怨頁面結(jié)果反饋的非常慢?您的mysql系統(tǒng)的負(fù)載是不是總是維持在一個非常高的狀態(tài)下?本文將為您提供一個分擔(dān)mysql系統(tǒng)的負(fù)載的方法,以及由此派生出來的一個mysql-ha-proxy的開發(fā)項目。使用本文提供的方法,您將以最小的源代碼改動,獲得mysql系統(tǒng)的高效運(yùn)轉(zhuǎn)。

第一節(jié) 數(shù)據(jù)庫集群技術(shù)的現(xiàn)狀

目前數(shù)據(jù)庫集群系統(tǒng)應(yīng)用得比較成功,應(yīng)用范圍比較廣泛的是:oracle公司的oracle9與ibm公司db2。oracle9采用shared-storage的技術(shù),db2選擇了shared-nothing的技術(shù),二者各有長短。

最新的數(shù)據(jù)庫集群系統(tǒng)的理論基礎(chǔ)是分布式計算,將數(shù)據(jù)分布到每個節(jié)點(diǎn),所有的計算節(jié)點(diǎn)并行處理數(shù)據(jù),將結(jié)果匯總。這樣的方式無疑是最完美的。但是目前仍然不能實現(xiàn)全部的功能。

對于shared-storage以及shared-nothing的技術(shù)請參考o(jì)racle以及ibm網(wǎng)站上的相關(guān)資料。

第二節(jié) 目前數(shù)據(jù)庫應(yīng)用狀況

目前數(shù)據(jù)庫應(yīng)用狀況大致分為兩類,第一類是數(shù)據(jù)量在100g以下,數(shù)據(jù)庫訪問頻繁,請求密集。主要是web app類型的應(yīng)用,例如:網(wǎng)站,論壇等。這些web app類型的應(yīng)用訪問數(shù)據(jù)庫的特點(diǎn)是:訪問頻繁,數(shù)據(jù)庫每秒鐘要接受幾千次以上的查詢,需要經(jīng)常追加數(shù)據(jù),同時對數(shù)據(jù)的響應(yīng)速度要求比較高。另一類是用于科學(xué)計算、存儲歷史數(shù)據(jù)的應(yīng)用,數(shù)據(jù)量往往達(dá)到幾百g。這些應(yīng)用訪問數(shù)據(jù)庫的特點(diǎn)是:多為查詢操作,數(shù)據(jù)都是分批、定時、集中倒入數(shù)據(jù)庫,數(shù)據(jù)庫的記錄非常多,積累了大量的數(shù)據(jù),對數(shù)據(jù)庫的響應(yīng)速度沒有太高要求。

第三節(jié) 暴露出來的問題

第一類應(yīng)用,由于訪問比較頻繁,而且為了支持更多的訪問,web server一般都使用了負(fù)載均衡的集群,但是對于數(shù)據(jù)庫來說,由于無法實現(xiàn)集群操作,每秒鐘的請求不斷增加,隨著服務(wù)器負(fù)載的增加,響應(yīng)單個請求的速度越來越慢,如果庫文件比較大,出現(xiàn)寫操作的時候還會出現(xiàn)鎖表時間過長等影響訪問效率的事情。

第二類應(yīng)用,主要是數(shù)據(jù)文件太大,每次處理數(shù)據(jù)都需要大量的時間,如果寫錯一個語句就需要花幾個小時來重做查詢。

第四節(jié) 如何解決

首先應(yīng)當(dāng)從硬件、軟件、程序、索引、sql語句這幾個方面進(jìn)行優(yōu)化,如果仍然不能解決問題,我們就要考慮數(shù)據(jù)庫系統(tǒng)的集群(并行處理)了。

對于第一類的應(yīng)用,在數(shù)據(jù)庫服務(wù)器正常運(yùn)行,負(fù)載不高的情況下,應(yīng)用對數(shù)據(jù)庫系統(tǒng)的狀況還是滿意的。但是數(shù)據(jù)庫系統(tǒng)負(fù)載過高之后,就會出現(xiàn)完成請求的時間加長,達(dá)不到系統(tǒng)的要求時間。既然負(fù)載是由于過多的請求造成的,我們就采取分擔(dān)請求的方式,讓一部分的請求去訪問另外一臺服務(wù)器,讓單臺服務(wù)器的負(fù)載降低,從而解決問題。

對于第二類的應(yīng)用,就需要分布式計算的系統(tǒng)來解決了,一般的系統(tǒng)是無能為力了。

第五節(jié) 針對于"linux+apache+php+mysql"的第一類應(yīng)用問題的解決方式

一個實際案例的解決:

我在工作當(dāng)中遇到了這樣的問題,我們的web server是linux+apache+php的三臺機(jī)器組成的集群,mysql運(yùn)行在sun450,2g內(nèi)存的平臺上。由于web的訪問量在高峰的時候幾乎滿負(fù)荷運(yùn)轉(zhuǎn),loadavg(就是一分鐘之內(nèi)處于running狀態(tài)的進(jìn)程數(shù)量)都在10-20之間,反映出來就是大量的請求都在訪問數(shù)據(jù)庫的時候被掛住了,導(dǎo)致一個請求沒有完成,下一個請求又進(jìn)來,最后惡性循環(huán)。loadavg會在瞬間飆升至800以上。數(shù)據(jù)庫那邊就更糟糕了,loadavg達(dá)到300多,數(shù)據(jù)庫的線程非常多,cpu忙于切換線程狀態(tài),這個時候除非restart mysql,否則怎么都不會好。在對sql語句優(yōu)化完成后還是不能很好的解決問題,我們增加了一臺數(shù)據(jù)庫服務(wù)器,通過mysql的數(shù)據(jù)同步機(jī)制,讓兩臺數(shù)據(jù)庫上的數(shù)據(jù)保持同步,修改了一部分只會發(fā)生讀取操作的php程序,讓這些程序連接另外一臺數(shù)據(jù)庫,算是把負(fù)載分離出去一部分,問題得到了初步的解決。但是后來業(yè)務(wù)做大,我們又增加了多臺服務(wù)器,修改了很多程序,分離他們對數(shù)據(jù)庫的讀取操作,訪問不同的服務(wù)器。

第六節(jié) mysql-ha-proxy方案的提出

通過修改程序的方式實現(xiàn)將系統(tǒng)的負(fù)載分離,是件很痛苦的事情,工程浩大,而且不能弄錯,因為除了主服務(wù)器可以寫入、修改數(shù)據(jù),而其它的服務(wù)器只能通過數(shù)據(jù)同步更新自身的數(shù)據(jù),所以如果你對那些數(shù)據(jù)庫進(jìn)行了寫操作,結(jié)果將是災(zāi)難性的。

如果我們能夠有一個程序分揀sql語句,根據(jù)他的類型(讀取/寫入),分別傳送給不同的服務(wù)器,然后再將結(jié)果返回。采用一種類似http的proxy的方式,這樣我們就不需要通過修改源程序的方式來分擔(dān)負(fù)載了,如果再能夠根據(jù)服務(wù)器的負(fù)載狀況,或者是表的狀態(tài)(可用/鎖定),來判斷應(yīng)該將這個請求分配到哪臺服務(wù)器,那就比我們修改源程序所能達(dá)到的效果還要好。

第七節(jié) mysql client與server之間如何通信

四處尋找,也沒有找到一篇關(guān)于mysql通訊協(xié)議的文章,看來只有分析mysql的源程序了。于是找來mysql 3.23.49的代碼,打開sniffer工具。mysql的通訊協(xié)議可能變更過多次,在3.23.49的版本里面,通訊協(xié)議的版本竟然是10。

簡單的分析了一下通訊協(xié)議,現(xiàn)在規(guī)整如下,有些地方還不是很完善,由于我實在沒有太多的時間仔細(xì)研讀mysql的代碼,目前我只了解到了這些。

偏移區(qū)域類型長度(byte)說明0headdata length3 1 2 3 flag1=0普通信息
=1多段信息
=2認(rèn)證返回
>2段結(jié)束字
4datacmd code1 5 messagedatalength - 1 

當(dāng)flag=0 , 2的時候 cmd code 與 message 的定義

cmdcode類型message的結(jié)構(gòu)00狀態(tài)碼偏移類型length(byte)   0affect rows2 0a服務(wù)器版本號偏移類型length(byte)  只有在剛剛連接上server的時候有效,server會馬上返回一個數(shù)據(jù)節(jié)段的信息0versionstring8end of '/0' 8session id432bits 12unknown11      ff當(dāng)出現(xiàn)錯誤的時候返回信息偏移類型length(byte)   0errcode2   2errmsgend fe多段信息傳輸?shù)慕Y(jié)束

client對server提交數(shù)據(jù)的格式:

偏移區(qū)域類型length(byte)0headdata length31   2   3 compressed14datacommand id15command datadata length - 1

command id與command data的說明:

id 類型數(shù)據(jù)格式0com_sleep 1com_quitnull2com_init_dbdatabase name3com_querystand query string4com_field_listtable name [128] wildcard[128]5com_create_dbdatabase name6com_drop_dbdatabase name7com_refreshoptions(bits)8com_shutdownnull9com_statisticsnull10com_process_infonull11com_connect 12com_process_killsid[4]13com_debugnull14com_pingnull15com_time 16com_delayed_insert 17com_change_user[user][passwd][db]18 com_binlog_dump 19com_table_dump 20com_connect_out 
第八節(jié) client如何通過server的用戶認(rèn)證

協(xié)議分析完成了,我嘗試著讓它工作起來,可是認(rèn)證這個部分遇到了麻煩,mysql server在client連接上它的時候,會首先返回給client一個數(shù)據(jù)包,包含協(xié)議的版本號,版本信息,sessionid,一個8字節(jié)的key,就是這個key的原因。client會使用這個key來加密密碼,然后將用戶名,密碼,需要打開的數(shù)據(jù)庫等信息發(fā)送給server,這樣就完成認(rèn)證了。我不知道client是如何利用這個key來加密的,所以我打算跳過密碼,我將client的數(shù)據(jù)包重組,去掉password的信息之后,我成功了,但是集群里面的mysql用戶都是沒有密碼的,安全性多多少少有些問題,不過這些服務(wù)器都是放在ha后面的,沒有外部的ip地址,應(yīng)該問題不大,不過多多少少是個缺憾。


但是我總要知道用戶的密碼是否正確吧?怎么辦呢?使用一個專用的mysql來完成密碼認(rèn)證。安裝一個最小化資源的mysql server用來做mysqlauth(專用認(rèn)證服務(wù)器),當(dāng)client連接后,就將mysqlauth的第一個數(shù)據(jù)包返回給client,這里面當(dāng)然就包含著key,然后client會使用這個key,加密密碼之后,將認(rèn)證信息發(fā)回來,這個時候,mysqlha系統(tǒng)就會將這個信息轉(zhuǎn)發(fā)給mysqlauth,并且自己保留一份,如果認(rèn)證通過了,就把保留的那一份進(jìn)行重組,去掉密碼信息,然后用重組后的認(rèn)證信息去連接集群中的服務(wù)器。

  • 本文來源于網(wǎng)頁設(shè)計愛好者web開發(fā)社區(qū)http://www.html.org.cn收集整理,歡迎訪問。
  • 發(fā)表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發(fā)表
    主站蜘蛛池模板: 尼木县| 昭通市| 金昌市| 广昌县| 娱乐| 竹溪县| 南开区| 江源县| 吉安县| 永兴县| 高碑店市| 通江县| 全南县| 鄂尔多斯市| 文安县| 武冈市| 闽清县| 平远县| 长宁县| 灵石县| 壤塘县| 仁化县| 内乡县| 汝阳县| 含山县| 怀来县| 桃园县| 株洲市| 临江市| 河北省| 海丰县| 寻甸| 肃南| 海阳市| 定兴县| 周口市| 萝北县| 吉林省| 星子县| 北川| 揭东县|