MySQL 主從復制與讀寫分離概念及架構分析

jopen 10年前發布 | 409K 次閱讀 MySQL 數據庫服務器

1.MySQL主從復制入門

首先,我們看一個圖:

MySQL 主從復制與讀寫分離概念及架構分析

  • 影響MySQL-A數據庫的操作,在數據庫執行后,都會寫入本地的日志系統A中。

     

    假設,實時的將變化了的日志系統中的數據庫事件操作,在MYSQL-A的3306端口,通過網絡發給MYSQL-B。

     

    MYSQL-B收到后,寫入本地日志系統B,然后一條條的將數據庫事件在數據庫中完成。

     

    那么,MYSQL-A的變化,MYSQL-B也會變化,這樣就是所謂的MYSQL的復制,即MYSQL replication。

     

    在上面的模型中,MYSQL-A就是主服務器,即master,MYSQL-B就是從服務器,即slave。

     

    日志系統A,其實它是MYSQL的日志類型中的二進制日志,也就是專門用來保存修改數據庫表的所有動作,即bin log。【注意MYSQL會在執行語句之后,釋放鎖之前,寫入二進制日志,確保事務安全】

     

    日志系統B,并不是二進制日志,由于它是從MYSQL-A的二進制日志復制過來的,并不是自己的數據庫變化產生的,有點接力的感覺,稱為中繼日志,即relay log。

     

    可以發現,通過上面的機制,可以保證MYSQL-A和MYSQL-B的數據庫數據一致,但是時間上肯定有延遲,即MYSQL-B的數據是滯后的。

    【即便不考慮什么網絡的因素,MYSQL-A的數據庫操作是可以并發的執行的,但是MYSQL-B只能從relay log中讀一條,執行下。因此MYSQL-A的寫操作很頻繁,MYSQL-B很可能跟不上。】

     

     

    </td> </tr> </tbody> </table>

     

    2.主從復制的幾種方式

     

     

    同步復制

    所謂的同步復制,意思是master的變化,必須等待slave-1,slave-2,...,slave-n完成后才能返回。

    這樣,顯然不可取,也不是MYSQL復制的默認設置。比如,在WEB前端頁面上,用戶增加了條記錄,需要等待很長時間。

     

     

    異步復制

    如同AJAX請求一樣。master只需要完成自己的數據庫操作即可。至于slaves是否收到二進制日志,是否完成操作,不用關心。MYSQL的默認設置。

     

     

    半同步復制

    master只保證slaves中的一個操作成功,就返回,其他slave不管。

    這個功能,是由google為MYSQL引入的。

     

     

    </td> </tr> </tbody> </table>

     

    3.主從復制分析

     

    問題1:master的寫操作,slaves被動的進行一樣的操作,保持數據一致性,那么slave是否可以主動的進行寫操作?

     

    假設slave可以主動的進行寫操作,slave又無法通知master,這樣就導致了master和slave數據不一致了。因此slave不應該進行寫操作,至少是slave上涉及到復制的數據庫不可以寫。實際上,這里已經揭示了讀寫分離的概念。

     

     

    問題2:主從復制中,可以有N個slave,可是這些slave又不能進行寫操作,要他們干嘛?

     

    可以實現數據備份。

    類似于高可用的功能,一旦master掛了,可以讓slave頂上去,同時slave提升為master。

    異地容災,比如master在北京,地震掛了,那么在上海的slave還可以繼續。

    主要用于實現scale out,分擔負載,可以將讀的任務分散到slaves上。

    【很可能的情況是,一個系統的讀操作遠遠多于寫操作,因此寫操作發向master,讀操作發向slaves進行操作】

     

    問題3:主從復制中有master,slave1,slave2,...等等這么多MYSQL數據庫,那比如一個JAVA WEB應用到底應該連接哪個數據庫?

     

    當 然,我們在應用程序中可以這樣,insert/delete/update這些更新數據庫的操作,用connection(for master)進行操作,select用connection(for slaves)進行操作。那我們的應用程序還要完成怎么從slaves選擇一個來執行select,例如簡單的輪循算法。

    這樣的話,相當于應用程序完成了SQL語句的路由,而且與MYSQL的主從復制架構非常關聯,一旦master掛了,某些slave掛了,那么應用程序就要修改了。能不能讓應用程序與MYSQL的主從復制架構沒有什么太多關系呢?可以看下面的圖:

     

    MySQL 主從復制與讀寫分離概念及架構分析

    找一個組件,application program只需要與它打交道,用它來完成MYSQL的代理,實現SQL語句的路由。

     

    mysql proxy并不負責,怎么從眾多的slaves挑一個?可以交給另一個組件(比如haproxy)來完成。

     

    這就是所謂的MYSQL READ WRITE SPLITE,MYSQL的讀寫分離。

     

     

    問題4:如果mysql proxy , direct , master他們中的某些掛了怎么辦?

     

    總統一般都會弄個副總統,以防不測。同樣的,可以給這些關鍵的節點來個備份。

     

     

    問題5:當master的二進制日志每產生一個事件,都需要發往slave,如果我們有N個slave,那是發N次,還是只發一次?

     

    如果只發一次,發給了slave-1,那slave-2,slave-3,...它們怎么辦?

    顯 然,應該發N次。實際上,在MYSQL master內部,維護N個線程,每一個線程負責將二進制日志文件發往對應的slave。master既要負責寫操作,還的維護N個線程,負擔會很重。可 以這樣,slave-1是master的從,slave-1又是slave-2,slave-3,...的主,同時slave-1不再負責select。 slave-1將master的復制線程的負擔,轉移到自己的身上。這就是所謂的多級復制的概念。

     

     

    問題6:當一個select發往mysql proxy,可能這次由slave-2響應,下次由slave-3響應,這樣的話,就無法利用查詢緩存了。

     

    應該找一個共享式的緩存,比如memcache來解決。將slave-2,slave-3,...這些查詢的結果都緩存至mamcache中。

     

     

    問題7:隨著應用的日益增長,讀操作很多,我們可以擴展slave,但是如果master滿足不了寫操作了,怎么辦呢?

     

    scale on ?更好的服務器? 沒有最好的,只有更好的,太貴了。。。

    scale out ? 主從復制架構已經滿足不了。

    可以分庫【垂直拆分】,分表【水平拆分】。

    來自:http://zhangfengzhe.blog.51cto.com/8855103/1563032

     本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!
  • sesese色