怎樣解決MySQL數(shù)據(jù)庫(kù)主從復(fù)制延遲的問(wèn)題
像Facebook、開(kāi)心001、人人網(wǎng)、優(yōu)酷、豆瓣、淘寶等高流量、高并發(fā)的網(wǎng)站,單點(diǎn)數(shù)據(jù)庫(kù)很難支撐得住,WEB2.0類型的網(wǎng)站中使用MySQL的居多,要么用MySQL自帶的MySQL NDB Cluster(MySQL5.0及以上版本支持MySQL NDB Cluster功能),或者用MySQL自帶的分區(qū)功能(MySQL5.1及以上版本支持分區(qū)功能),我所知道的使用這兩種方案的很少,一般使用主從復(fù)制,再加上MySQL Proxy實(shí)現(xiàn)負(fù)載均衡、讀寫(xiě)分離等功能,在使用主從復(fù)制的基礎(chǔ)上,再使用垂直切分及水平切分;或者不使用主從復(fù)制,完全使用垂直切分加上水平切分再加上類似Memcached的系統(tǒng)也可以解決問(wèn)題。
1.優(yōu)酷的經(jīng)驗(yàn)
數(shù)據(jù)庫(kù)采用水平擴(kuò)展,主從復(fù)制,隨著從數(shù)據(jù)庫(kù)的增多,復(fù)制延遲越來(lái)越厲害,最終無(wú)法忍受。
最終還是采用數(shù)據(jù)庫(kù)的sharding,把一組用戶相關(guān)的表和數(shù)據(jù)放到一組數(shù)據(jù)庫(kù)上。
使用SSD來(lái)優(yōu)化mysql的I/O,性能提升明顯,每塊16G,6塊SSD做RAID。
數(shù)據(jù)庫(kù)的類型選用MYISAM
數(shù)據(jù)庫(kù)的拆分策略,先縱向按照業(yè)務(wù)或者模塊拆分。對(duì)于一些特別大的表,再采用垂直拆分
根據(jù)用戶進(jìn)行分片,盡可能不要跨篇查詢。如果確實(shí)要跨片查詢,可以考慮搜索的方案,先索引再搜索。
分布式的數(shù)據(jù)庫(kù)方案太復(fù)雜,否掉。
優(yōu)酷使用的是數(shù)據(jù)庫(kù)分片技術(shù),而拋棄了由于數(shù)據(jù)量的越來(lái)越多導(dǎo)致復(fù)制延遲的問(wèn)題。按照user_id進(jìn)行分片,這樣必須有一個(gè)全局的表來(lái)管理用戶與shard的關(guān)系,根據(jù)user_id可以得到share_id,然后根據(jù)share_id去指定的分片查詢指定的數(shù)據(jù)。
假如此表的表名為sharding_manager,如果網(wǎng)站的用戶數(shù)太多,比如千萬(wàn)級(jí)的或甚至更大比如億級(jí)的用戶,此時(shí)此表也許也會(huì)成為一個(gè)瓶頸,因?yàn)椴樵儠?huì)非常頻繁,所有的動(dòng)態(tài)請(qǐng)求都要讀此表,這時(shí)可以用其它的解決方案,比如用Memcached、Tokyo Cabinet、Berkeley DB或其它的性能更高的方案來(lái)解決。
具體怎么定位到哪臺(tái)db服務(wù)器,定位到哪個(gè)數(shù)據(jù)庫(kù),定位到哪個(gè)shard(就是userN,msgN,videoN),優(yōu)酷網(wǎng)的架構(gòu)文檔中說(shuō)得不是很仔細(xì),這里只能猜測(cè)一下了。
根據(jù)優(yōu)酷的架構(gòu)圖,一共有2臺(tái)db服務(wù)器,每臺(tái)db服務(wù)器有2個(gè)數(shù)據(jù)庫(kù),每個(gè)數(shù)據(jù)庫(kù)有3個(gè)shard,這樣一共是2 * 2 * 3 = 12個(gè)shard。
user_id一般是自增型字段,用戶注冊(cè)的時(shí)候可以自動(dòng)生成,然后看有幾臺(tái)db服務(wù)器,假如有m臺(tái)db服務(wù)器,則用 user_id % m便可以分配一臺(tái)db服務(wù)器(例如0對(duì)應(yīng)100,1對(duì)應(yīng)101,以此類推,字段mysql_server_ip的值確定),假設(shè)每臺(tái)服務(wù)器有n個(gè)數(shù)據(jù)庫(kù),則用user_id % n可以定位到哪個(gè)數(shù)據(jù)庫(kù)(字段database_name的值確定),假設(shè)每個(gè)數(shù)據(jù)庫(kù)有i個(gè)shard,則用user_id % i可以定位到哪個(gè)shard(字段shard_id的值確定),這樣就可以進(jìn)行具體的數(shù)據(jù)庫(kù)操作了。
user_id share_id mysql_server_ip database_name
101 2 192.168.1.100 shard_db1
105 0 192.168.1.100 shard_db2
108 0 192.168.1.101 shard_db3(或shard_db1)
110 1 192.168.1.101 shard_db4(或shard_db2)
如上述user_id為101的用戶,連接數(shù)據(jù)庫(kù)服務(wù)器192.168.1.100,使用其中的數(shù)據(jù)庫(kù)為shard_db1,使用其中的表系列為user2,msg2,video2
如果上述的m,n,i發(fā)生變化,比如網(wǎng)站的用戶不斷增長(zhǎng),需要增加db服務(wù)器,此時(shí)則需要進(jìn)行數(shù)據(jù)庫(kù)遷移。
因?yàn)楸砦挥诓煌臄?shù)據(jù)庫(kù)中,所以不同的數(shù)據(jù)庫(kù)中表名可以相同
server1(192.168.1.100)
shard_db1
user0
msg0
video0
user1
msg1
video1
...
userN
msgN
videoN
shard_db2
user0
msg0
video0
user1
msg1
video1
...
userN
msgN
videoN
因?yàn)楸砦挥诓煌臄?shù)據(jù)庫(kù)服務(wù)器中,所以不同的數(shù)據(jù)庫(kù)服務(wù)器中的數(shù)據(jù)庫(kù)名可以相同
server2(192.168.1.101)
shard_db3(這里也可以用shard_db1)
user0
msg0
video0
user1
msg1
video1
...
userN
msgN
videoN
shard_db4(這里也可以用shard_db2)
user0
msg0
video0
user1
msg1
video1
...
userN
msgN
videoN
2.豆瓣的經(jīng)驗(yàn)
由于從主庫(kù)到輔庫(kù)的復(fù)制需要時(shí)間
更新主庫(kù)后,下一個(gè)請(qǐng)求往往就是要讀數(shù)據(jù)(更新數(shù)據(jù)后刷新頁(yè)面)
從輔庫(kù)讀會(huì)導(dǎo)致cache里存放的是舊數(shù)據(jù)(不知道這個(gè)cache具體指的是什么,如果是Memcached的話,如果更新的數(shù)據(jù)的量很大,難道把所有更新過(guò)的數(shù)據(jù)都保存在Memcached里面嗎?)
解決方法:更新數(shù)據(jù)庫(kù)后,在預(yù)期可能會(huì)馬上用到的情況下,主動(dòng)刷新緩存
不完美,but it works
豆瓣后來(lái)改為雙MySQL Master+Slave說(shuō)是能解決Replication Delay的問(wèn)題,不知道是怎么解決的,具體不太清楚。
3.Facebook的經(jīng)驗(yàn)
下面一段內(nèi)容引用自www.dbanotes.net
大量的 MySQL + Memcached 服務(wù)器,布署簡(jiǎn)示:
California (主 Write/Read)............. Virginia (Read Only)
主數(shù)據(jù)中心在 California ,遠(yuǎn)程中心在 Virginia 。這兩個(gè)中心網(wǎng)絡(luò)延遲就有 70ms,MySQL 數(shù)據(jù)復(fù)制延遲有的時(shí)候會(huì)達(dá)到 20ms. 如果要讓只讀的信息從 Virginia 端發(fā)起,Memcached 的 Cache 數(shù)據(jù)一致性就是個(gè)問(wèn)題。
1 用戶發(fā)起更新操作,更名 "Jason" 到 "Monkey" ;
2 主數(shù)據(jù)庫(kù)寫(xiě)入 "Monkey",刪除主端 Memcached 中的名字值,但Virginia 端 Memcached 不刪;(這地方在 SQL 解析上作了一點(diǎn)手腳,把更新的操作"示意"給遠(yuǎn)程);
3 在 Virginia 有人查看該用戶 Profile ;
4 在 Memcached 中找到鍵值,返回值 "Jason";
5 復(fù)制追上更新 Slave 數(shù)據(jù)庫(kù)用戶名字為 "Monkey",刪除 Virginia Memcached 中的鍵值;
6 在 Virginia 有人查看該用戶 Profile ;
7 Memcache 中沒(méi)找到鍵值,所以從 Slave 中讀取,然后得到正確的 "Monkey" 。
Via
從上面3可以看出,也仍然存在數(shù)據(jù)延遲的問(wèn)題。同時(shí)master中數(shù)據(jù)庫(kù)更新的時(shí)候不更新slave中的memcached,只是給slave發(fā)個(gè)通知,說(shuō)數(shù)據(jù)已經(jīng)改變了。
那是不是可以這樣,當(dāng)主服務(wù)器有數(shù)據(jù)更新時(shí),立即更新從服務(wù)器中的Memcached中的數(shù)據(jù),這樣即使有延遲,但延遲的時(shí)間應(yīng)該更短了,基本上可以忽略不計(jì)了。
4.Netlog的經(jīng)驗(yàn)
對(duì)于比較重要且必須實(shí)時(shí)的數(shù)據(jù),比如用戶剛換密碼(密碼寫(xiě)入 Master),然后用新密碼登錄(從 Slaves 讀取密碼),會(huì)造成密碼不一致,導(dǎo)致用戶短時(shí)間內(nèi)登錄出錯(cuò)。所以在這種需要讀取實(shí)時(shí)數(shù)據(jù)的時(shí)候最好從 Master 直接讀取,避免 Slaves 數(shù)據(jù)滯后現(xiàn)象發(fā)生。還好,需要讀取實(shí)時(shí)數(shù)據(jù)的時(shí)候不多,比如用戶更改了郵件地址,就沒(méi)必要馬上讀取,所以這種 Master-Slaves 架構(gòu)在多數(shù)情況下還是有效的。
bitsCN.com聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com