1. 程式人生 > >數據庫主從復制和讀寫分離

數據庫主從復制和讀寫分離

其中 select htm targe 方式 文檔 size 打開 salve

參考文檔:

http://www.cnblogs.com/crazylqy/p/5542558.html

http://www.cnblogs.com/gl-developer/p/6170423.html

https://mp.weixin.qq.com/s?__biz=MzAxMTEyOTQ5OQ==&mid=400643724&idx=1&sn=82e5b5ec9e0567abea4cc1d960265d9e#rd

https://www.jianshu.com/p/89ad5129a8b7

在實際的生產環境中,如果把對數據庫的讀和寫操作都放在同一個數據庫服務器上來進行,無論從安全性、高可用性還是高並發等各個方面都是不可取的。因此,一般來說都是通過主從復制(Master-Slave)的方式來同步數據,再通過讀寫分離(MySQL-Proxy)來提升數據庫的並發負載能力。如下圖所示:

技術分享圖片

主從復制和讀寫分離的好處:

    1. 將讀操作和寫操作分離到不同的數據庫上,避免主服務器出現性能瓶頸;

    2. 主服務器進行寫操作時,不影響查詢應用服務器的查詢性能,降低阻塞,提高並發;

    3. 數據擁有多個容災副本,提高數據安全性,同時當主服務器故障時,可立即切換到其他服務器,提高系統可用性;

主從復制

1. MySQL支持的復制類型

  • 基於語句的復制。在服務器上執行sql語句,在從服務器上執行同樣的語句,mysql默認采用基於語句的復制,執行效率高。
  • 基於行的復制。把改變的數據復制到從服務器上,而不是把命令在從服務器上執行一遍。
  • 混合類型的復制。默認采用基於語句的復制,一旦發現基於語句無法精確復制時,就會采用基於行的復制。

2.主從復制的工作過程

a. 在每個事務更新數據完成之前,master在二進制日誌記錄(binary log)這些改變。寫入二進制日誌完成後,master通知存儲引擎提交事務。

b. Slave將master的binary log復制到其中繼日誌(Relay log)。首先slave開始一個工作線程(I/O),I/O線程在master上打開一個普通的連接,然後開始binlog dump process。binlog dump process從master的二進制日誌中讀取事件,如果已經跟上master,它會睡眠並等待master產生新的事件,I/O線程將這些事件寫入中繼日誌。

c. Sql slave thread(sql從線程)處理該過程的最後一步,sql線程從中繼日誌讀取事件,並重放其中的事件而更新slave數據,使其與master中的數據一致,只要該線程與I/O線程保持一致,中繼日誌通常會位於os緩存中,所以中繼日誌的開銷很小。

整個過程如下圖所示:

技術分享圖片

3. 主從復制的三種方式

  • 同步復制:

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

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

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

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

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

讀寫分離

讀寫分離指的是在主服務器上進行修改操作(如insert/delete/update這些更新數據庫的操作),從服務器只能提供讀取數據(select),不能寫入。這樣,在實現了備份的同時也實現了數據庫性能的優化,以及提升了服務器安全。如下圖所示:

技術分享圖片

目前較為常見的MySQL讀寫分離分為以下兩種:

1. 基於程序代碼內部實現

  在代碼中根據select 、insert進行路由分類,這類方法也是目前生產環境下應用最廣泛的。優點是性能較好,因為程序在代碼中實現,不需要增加額外的硬件開支,缺點是需要開發人員來實現,運維人員無從下手。

2.基於中間代理層實現

  代理一般介於應用服務器和數據庫服務器之間,代理數據庫服務器接收到應用服務器的請求後根據判斷後轉發到後端數據庫。代理有以下代表性的程序。

  • mysql_proxy。mysql_proxy是Mysql的一個開源項目,通過其自帶的lua腳本進行sql判斷。
  • Atlas。是由 Qihoo 360, Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的數據中間層項目。它是在mysql-proxy 0.8.2版本的基礎上,對其進行了優化,增加了一些新的功能特性。360內部使用Atlas運行的mysql業務,每天承載的讀寫請求數達幾十億條。支持事物以及存儲過程。
  • Amoeba。由阿裏巴巴集團在職員工陳思儒使用序java語言進行開發,阿裏巴巴集團將其用戶生產環境下,但是他並不支持事物以及存數過程。

經過上述簡單的比較,不是所有的應用都能夠在基於程序代碼中實現讀寫分離,像一些大型的java應用,如果在程序代碼中實現讀寫分離對代碼的改動就較大,所以,像這種應用一般會考慮使用代理層來實現。

數據庫主從復制和讀寫分離