使用MySQL-Proxy讀寫(xiě)分離時(shí)需要注意什么

這篇文章主要介紹“使用MySQL-Proxy讀寫(xiě)分離時(shí)需要注意什么”,在日常操作中,相信很多人在使用MySQL-Proxy讀寫(xiě)分離時(shí)需要注意什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”使用MySQL-Proxy讀寫(xiě)分離時(shí)需要注意什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

成都創(chuàng)新互聯(lián)專(zhuān)注于青山企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,商城建設(shè)。青山網(wǎng)站建設(shè)公司,為青山等地區(qū)提供建站服務(wù)。全流程按需定制,專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)


 
在動(dòng)手操作前最好先安裝好MySQL-Proxy,并配置好MySQL主從服務(wù)器。補(bǔ)充:新版MySQL已經(jīng)內(nèi)建支持
延遲問(wèn)題
讀寫(xiě)分離不能回避的問(wèn)題之一就是延遲,可以考慮Google提供的SemiSyncReplicationDesign補(bǔ)丁。
 
端口問(wèn)題
 
MySQL-Proxy缺省使用的是4040端口,如果你想透明的把3306端口的請(qǐng)求轉(zhuǎn)發(fā)給4040的話,那么可以:
 
iptables -t nat -I PREROUTING -s ! 127.0.0.1 -p tcp --dport 3306 -j REDIRECT --to-ports 4040
 
如果想刪除這條規(guī)則,可以把上面例子中的-I換成-D。
 
參考鏈接
 
密碼加密方式
 
MySQL-Proxy不支持老的密碼加密方式,所以如果你使用的是老版本的MySQL,或者啟用了old_passwords選項(xiàng)的話,則可能會(huì)出現(xiàn)錯(cuò)誤:
 
ERROR 2013: Lost connection to MySQL server
 
此時(shí)最好的修復(fù)方法就是使用新的密碼加密方式,如果你的用戶表是老式的,可能需要先運(yùn)行MySQL源代碼里scripts目錄下的mysql_fix_privilege_tables腳本升級(jí)表結(jié)構(gòu)。有時(shí)候客觀情況可能不允許立刻進(jìn)行升級(jí)操作,此時(shí)可以為MySQL-Proxy專(zhuān)門(mén)建立一個(gè)密碼為空的用戶(通過(guò)主機(jī)限制訪問(wèn),或者起一個(gè)很復(fù)雜的用戶名),因?yàn)椴还苁切碌拿艽a加密方式還是舊的密碼加密方式,空密碼都同樣是一個(gè)空字符串,這樣就規(guī)避了密碼加密的問(wèn)題。
  www.2cto.com  
查詢亂碼
 
連接上MySQL-Proxy后,執(zhí)行查詢時(shí),隨機(jī)出現(xiàn)亂碼。出現(xiàn)此問(wèn)題的原因是當(dāng)我們使用MySQL-Proxy讀寫(xiě)分離時(shí),通常會(huì)有多個(gè)后端服務(wù)器,客戶端發(fā)出查詢請(qǐng)求時(shí),一般會(huì)先發(fā)出一條類(lèi)似"SET NAME gbk"的語(yǔ)句來(lái)聲明客戶端編碼,然后再發(fā)出實(shí)際查詢的SQL語(yǔ)句,但MySQL-Proxy可能會(huì)把這兩條語(yǔ)句分發(fā)給不同的后端服務(wù)器,于是就出現(xiàn)了亂碼。
 
解決方法是強(qiáng)行指定后端服務(wù)器的字符編碼:
 
init-connect='SET NAME gbk'
 
default-character-set=gbk
skip-character-set-client-handshake
 
如果使用init-connect,則需要注意操作用戶不能有SUPER權(quán)限,否則此選項(xiàng)無(wú)效。
 
即便做好了以上的設(shè)置后,還有可能會(huì)出現(xiàn)亂碼,比如說(shuō)數(shù)據(jù)庫(kù)是gbk的,當(dāng)我們用PHPMyAdmin連接MySQL-Proxy時(shí),查詢還是會(huì)出現(xiàn)亂碼,不過(guò)這是正常的!因?yàn)镻HPMyAdmin使用的是utf8編碼,它發(fā)出的“SET NAMES utf8”語(yǔ)句被skip-character-set-client-handshake屏蔽了,所以出現(xiàn)亂碼。
 
進(jìn)程崩潰
  www.2cto.com  
MySQL-Proxy偶爾會(huì)出現(xiàn)進(jìn)程崩潰的情況,具體原因不明。
 
新版的MySQL-Proxy為了應(yīng)付這個(gè)問(wèn)題加入了一個(gè)keepalive選項(xiàng)(try to restart the proxy if it crashed),當(dāng)使用這個(gè)選項(xiàng)時(shí),會(huì)先后啟動(dòng)兩個(gè)mysql-proxy進(jìn)程,先啟動(dòng)的mysql-proxy進(jìn)程用來(lái)監(jiān)控后啟動(dòng)的mysql-proxy進(jìn)程,實(shí)際提供服務(wù)的是后啟動(dòng)的mysql-proxy進(jìn)程,一旦后啟動(dòng)的mysql-proxy進(jìn)程掛掉(你可以自己kill試試),先啟動(dòng)的mysql-proxy進(jìn)程會(huì)重新啟動(dòng)一個(gè)mysql-proxy提供服務(wù)。
 
不過(guò)現(xiàn)在很多人用的還是舊版的MySQL-Proxy,此時(shí)可以利用init來(lái)實(shí)現(xiàn)類(lèi)似keepalive的效果:
 
編寫(xiě)腳本/usr/local/sbin/mysql-proxy.sh,加入以下內(nèi)容(具體寫(xiě)法視安裝情況而定):
 
LUA_PATH="/usr/local/mysql-proxy/share/mysql-proxy/?.lua" \
/usr/local/mysql-proxy/sbin/mysql-proxy \
--proxy-backend-addresses=192.168.0.1:3306 \
--proxy-read-only-backend-addresses=192.168.0.2:3306 \
--proxy-lua-script=/usr/local/mysql-proxy/share/mysql-proxy/rw-splitting.lua
 
別忘了加上可執(zhí)行屬性:
 
chmod a+x /usr/local/sbin/mysql-proxy.sh
 
0.7.0版本有一個(gè)新的選項(xiàng):--defaults-file,可以把相關(guān)信息都寫(xiě)到配置文件里:
 
# MySQL Proxy's configuration file (mysql-proxy.cnf)
 
[mysql-proxy]
daemon = true
keepalive = true
proxy-backend-addresses = 192.168.0.1:3306
proxy-read-only-backend-addresses = 192.168.0.2:3306
proxy-lua-script = /usr/local/mysql-proxy/share/mysql-proxy/rw-splitting.lua
 
啟動(dòng)時(shí)可以使用:mysql-proxy --defaults-file=mysql-proxy.cnf
 
修改inittab:
  www.2cto.com  
vi /etc/inittab
 
加入以下內(nèi)容:
 
mp:12345:respawn:/usr/local/sbin/mysql-proxy.sh
 
然后讓init重新讀取inittab內(nèi)容:
 
kill -HUP 1
 
系統(tǒng)會(huì)自動(dòng)檢測(cè)/usr/local/sbin/mysql-proxy.sh是否正在運(yùn)行,如果沒(méi)有就自動(dòng)運(yùn)行。
 
需要注意的是在編寫(xiě)mysql-proxy.sh腳本的時(shí)候,不要加入--daemon選項(xiàng),否則/usr/local/sbin/mysql-proxy.sh一運(yùn)行就結(jié)束了,系統(tǒng)會(huì)不停的嘗試運(yùn)行腳本,從而在/var/log/message里留下大量的錯(cuò)誤信息(init: Id "mp" respawning too fast: disabled for 5 minutes)。
 
init的方法可能顯得有點(diǎn)另類(lèi)了,可以使用其他的工具,比如svscan。
 
有狀態(tài)的查詢
 
一些有狀態(tài)的特殊的查詢可能失效,比如說(shuō):
 
SELECT SQL_CALC_FOUND_ROWS ..
SELECT FOUND_ROWS()
 
這種查詢是有狀態(tài)的,應(yīng)該保證在同一個(gè)后端處理,查看rw-splitting.lua腳本可以看到MySQL-Proxy實(shí)際上已經(jīng)對(duì)這樣的查詢進(jìn)行了 判斷,但在實(shí)際應(yīng)用中發(fā)現(xiàn)還是存在問(wèn)題。估計(jì)是腳本寫(xiě)得不咋地,實(shí)際應(yīng)用中,建議大家不要使用這樣的查詢,一來(lái)沒(méi)有可移植性,而來(lái)效率也不見(jiàn)得好。
 
另一個(gè)可能會(huì)產(chǎn)生問(wèn)題的查詢是:
  www.2cto.com  
INSERT ... (AUTO_INCREMENT)
SELECT LAST_INSERT_ID()
 
當(dāng)系統(tǒng)執(zhí)行完INSERT后,再執(zhí)行SELECT時(shí),可能已經(jīng)被分發(fā)到了不同的后端服務(wù)器,如果你使用的編程語(yǔ)言是PHP的話,此時(shí)應(yīng)該通過(guò) mysql_insert_id()來(lái)得到最新插入的id,每次INSERT結(jié)束后,其實(shí)對(duì)應(yīng)的autoincrement值就已經(jīng)計(jì)算好返回給PHP 了,你無(wú)需再發(fā)出一次獨(dú)立的查詢,直接用mysql_insert_id()就可以了。不過(guò)很多PHP程序使用的都是SELECT LAST_INSERT_ID()的方式,如AdbDB,CakePHP等等,如果你正在使用它們的話需多加小心。(當(dāng)使用bigint 時(shí),mysql_insert_id()存在問(wèn)題,詳情見(jiàn)手冊(cè),不過(guò)對(duì)于大多數(shù)人而言,bigint基本不會(huì)遇到,所以你可以無(wú)視這個(gè)問(wèn)題)
 
注:對(duì)于這兩個(gè)問(wèn)題,官方BUG庫(kù)里有人給出了相應(yīng)的補(bǔ)丁。
 
腳本問(wèn)題
 
MySQL-Proxy讀寫(xiě)分離的功能是通過(guò)lua腳本(rw-splitting.lua)實(shí)現(xiàn)的,但是這個(gè)腳本年久失修,問(wèn)題多多,比如說(shuō)使用時(shí)可能會(huì)出現(xiàn):
 
ERROR 1105: can't change DB to on slave
 
出現(xiàn)這個(gè)問(wèn)題的原因在于當(dāng)客戶端發(fā)出查詢時(shí),MySQL-Proxy會(huì)比較當(dāng)前客戶端所處數(shù)據(jù)庫(kù)和服務(wù)器所處數(shù)據(jù)庫(kù)是否一致,如果不一致則會(huì)在服務(wù)端嘗試執(zhí)行一個(gè)"USE 數(shù)據(jù)庫(kù)"的操作,一個(gè)可能性是主從服務(wù)器的數(shù)據(jù)庫(kù)結(jié)構(gòu)不同,在USE一個(gè)不存在的數(shù)據(jù)庫(kù)的時(shí)候自然會(huì)出錯(cuò),還有一個(gè)原因有些查詢操作并沒(méi)有所處數(shù)據(jù)庫(kù)這個(gè)上下文,比如說(shuō)SHOW DATABASES這個(gè)查詢,并不需要事先“USE 數(shù)據(jù)庫(kù)”,只要連上服務(wù)器就可以執(zhí)行,這時(shí)候如果還嘗試同步客戶端和服務(wù)端所處的數(shù)據(jù)庫(kù),出錯(cuò)就是無(wú)法避免的事了。
 
rw-splitting.lua恰恰沒(méi)有屏蔽后者所描述的情況,修復(fù)方法如下,在合適的位置加入粗體代碼,
 
276         if cmd.type ~= proxy.COM_INIT_DB and
277            c.default_db and c.default_db ~= "" and c.default_db ~= s.default_db then
if is_debug
278                    print("    server default db: " .. s.default_db)
279                    print("    client default db: " .. c.default_db)
280                    print("    syncronizing")
end
281                 proxy.queries:prepend(2, string.char(proxy.COM_INIT_DB) .. c.default_db)  www.2cto.com  
282         end
 
在lua中,~=是不等于的意思,另外,lua里空字符串""用在if里被認(rèn)為是true,所以單靠c.default_db不夠。
 
順手加上is_debug的判斷,不然即使不是debug狀態(tài),服務(wù)器的命令行里也會(huì)偶爾冒出一些調(diào)試信息。
 
此外,新版MySQL-Proxy里,雖然源代碼包里有rw-splitting.lua腳本,但缺省并沒(méi)有安裝,你需要手動(dòng)拷貝,而且數(shù)據(jù)結(jié)構(gòu)發(fā)生了變化,腳本需要按照數(shù)據(jù)結(jié)構(gòu)的變化做出適當(dāng)?shù)男薷?,可以參考作者的描述操作,或者參考官方Bug管理或者直接。值得期待的是現(xiàn)在有了專(zhuān)門(mén)的MySQL-Proxy-Lua-Scripts項(xiàng)目,希望開(kāi)發(fā)進(jìn)度能跟上來(lái)。

到此,關(guān)于“使用MySQL-Proxy讀寫(xiě)分離時(shí)需要注意什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

網(wǎng)站標(biāo)題:使用MySQL-Proxy讀寫(xiě)分離時(shí)需要注意什么
本文鏈接:http://muchs.cn/article18/iepegp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、網(wǎng)站設(shè)計(jì)公司動(dòng)態(tài)網(wǎng)站、自適應(yīng)網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)公司、電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)