當網站越做越大的時候,資料庫的 HA (High Available) 就很重要了。業界常用的是 DRBD,上個月我去了北京參加系統架構師大會,中國的網站大部分解決資料庫 HA 都是用 DRBD 。 DRBD 簡單說就是 RAID 1 over TCP 。也就是透過 TCP 讓兩台主機的硬碟內容完全一模一樣,因此不只是 MySQL 可以使用 DRBD ,只要是任何會需要用到硬碟的 Server ,都可以用 DRBD 來做 HA,加上 MySQL InnoDB Engine 本身的 crash safe ,可以做到當一台主機掛點時,另一台主機可以用一模一樣的硬碟內容在最短時間把服務重新跑起來。 DRBD 已經被業界使用了多年,已經算是一個很成熟的架構。2005 年 8 月,LiveJournal 的 Brad Fitzpatrick (也是 memcached, MogileFS, Perlbal, Gearman 的作者) ,寫了一篇 LiveJournal's Backend ,裡面也有提到 DRBD 。那份文件也成為了很多新興網站架構時參考的文件,去北京的系統架構師大會時也發現中國的網站架構大部分與 Livejournal 相似,大概也都受到這份文件影響吧。 2006 年,出現了新的 MMM(Mysql Master-Master Replication Manager) 的架構,到現在來說也算是比較新的技術,業界上使用的也不多,上個月去北京參加系統架構師大會時也沒有任何一家公司有提到。但是相對 DRBD 起來,我比較喜歡 MMM 的架構,所以這篇文章應該也會比較著重於 MMM 的介紹。 MMM 就是在 MySQL 的 Master-Master 加強版。多用一台 Monitor 去監控兩台 MySQL 主機,當主機掛點時,會主動讓另一台主機變成 Master 。 來畫個 DRBD vs MMM 的優缺點比較表格。
以上是這一年來 PIXNET 使用 DRBD 和 MMM 上大概遇到的狀況的比較。 接下來下面再針對以上提到的問題再提出解決問題的方法吧。
1. 架構複雜度:(敗的 MMM 的解決方法) 在 PIXNET 這邊,去年八月改版之後,就沒有什麼地方會直接用 PHP 執行 MySQL query 了,我們所有跟資料庫有關的存取,都是透過我們自己寫的一套 library ,而這套 library 就已經解決了寫入會透過 Master , 讀取會透過 Slave 的問題。 如果要使用 MMM 或是任何 Master/Master 架構的話,就儘量不要自己寫 SQL query 用 mysql_query 的寫法,最好是把所有透過 MySQL 的存取的部分用 library 解決,這樣子可以保證寫入會透過 Master ,讀取就全部從 Slave ,如此達到 load balance。但是相對的就會遇到架構比較複雜,也會有 「Replication Delay」 的問題(後面會講解決法。) 另外在 Query 的架構上,因為 MMM 是兩台 Master ,有可能會造成兩台 Master 分別 INSERT 而 Primary key 重覆而 Replication Error。 (Ex: 目前 A[Master],B[Slave] 兩台機器 max increment id 都是 12345 ,這時候我在 A 機器 INSERT 一筆資料(Auto Increment ID = 12346)之後,這個 Query 還來不及 Repliction 到 B 去,A 機器網路就掛了,於是 B 機器就自動成為 Master ,接下來再有人 INSERT 資料進 B 之後,又出現一筆 ID = 12346 的資料。等到 A 機器復活之後,兩台都有了 ID = 12346 的資料,於是就造成 Replication Error 了。
解決方法就是利用 MySQL 的 auto_increment_increment 和 auto_increment_offset 兩個設定 另外在 CREATE TABLE 或是 DROP TABLE 時的指令,也要記得下 CREATE TABLE IF EXISTS ,讓 Slave 在不存在該 table 時也能正常運作。 UPDATE 的 ON DUPLICATE KEY UPDATE 也要常用。
2. Warm up:
3. Replication delay:
這邊的解決方法有幾個。
但是如果有兩個人在幾乎同時要寫入資料,原先的 a => b => c 的流程
Memcached protocol 在這方面有提供解決方案,叫 cas unique。 set, delete 會需要 cas unique ,如果你用 inc, append, prepend 等指令的話,就可以不用在乎 race condition 問題。 不過可惜的是 PHP 預設的 memcache extension 只支援最基本的 set/get ,沒有 cas unique 功能,因此這部分沒辦法這樣解決。
(2) 當資料庫有修改時,接下來的幾筆 query 要直接從 Master 去要,而不是從 Slave 其中 a 和 b 已經可能是兩個完全不同的 PHP process ,因此 a 在 master 寫入資料後, b 是在 slave 讀資料,還是有可能有因為資料還沒從 master replication 到 slave 去而讀不到資料的情況。
(3) 使用 MySQL 的 MASTER_POS_WAIT('binlog file', 'binlog pos', ['timeout']) function
(4) 把寫入和回傳資料的部分都用同一個 process 處理。
4. 需要做 Slow Query: 不過這部分要注意就是在做 ALTER TABLE 的時候,必須要 ALTER TABLE 成不影響上線服務的狀態。像是 INT 改成 BIGINT 、增加一組 INDEX KEY 之類的,這些做了之後不會影響到原先的服務。 Split-Brain 和其他雜七雜八的地方就留到第二篇再講吧。 ======================================== DRBD 與 MMM 的比較 ronny 去了在北京辦的「2009系統架構師大會」寫的文章:「MySQL 的 DRBD 與 MMM (1)」。 裡面有些地方可以補充一下,在不完全能接受 replication delay 的情況下,可以用 Google 提供的 SemiSyncReplicationDesign patch,所有在 master 的新增、更新、刪除動作時 (也就是有寫入的動作時) 都會等到 master 傳給 slave,並且 slave 說 OK 才結束。
转载:http://clip.artchiu.org/2009/10/19/mysql-%e7%9a%84-drbd-%e8%88%87-mmm-1/ |
用户登录
还没有账号?立即注册
用户注册
投稿取消
文章分类: |
|
还能输入300字
上传中....