1. 程式人生 > >MySQL 8.0復制性能的提升(翻譯)

MySQL 8.0復制性能的提升(翻譯)

行存儲 快捷 試圖 提高 需要 並發 流量 trac sla

What’s New With MySQL Replication in MySQL 8.0

MySQL復制從問世到現在已經經歷了多個年頭,它的穩定性和可靠性也在穩步的提高。這是一個不停進化的過程,由於MySQL的很多重要功能都是依賴於復制,所以復制的快速發展也是很容易理解的。


在MySQL的上一個版本當中,MySQL通過實現真正意義的並行復制將復制的性能提升到了一個新的層面,因為在MySQL 5.6的版本中,雖然號稱是實現了並行復制,但是並行復制是schema級別的,即如果binlog row event操作的是不同的schema的對象,在確定沒有DDL和foreign key依賴的情況下,就可以實現並行復制,並不能稱為真正意義的復制。它只是將不同schema的事物分開來執行,並不能真正意義的實現並行復制(比如主從架構只有一個schema的情況還是很多見的)。當然如果你的主從架構有多個schema的話,5.6的並行復制是對性能有很大的提升的。

MySQL5.7的並行復制是基於組提交(group commit)的並行復制的方法,5.7的並行復制,即使你的多個事物是對同一個schema進行操作,也能夠在從庫上並行回放。簡而言之,就是多個事物如果相互不影響,在刷盤的時候是能夠作為一個組來提交刷盤,我們甚至可以通過在從庫手動設置binlog_group_commit_sync_delay這個參數控制日誌在刷盤前日誌提交要等待的時間,從而提高從庫復制的效率。

這個方案看起來似乎很完美,但是並不是沒有缺點。事物提交的延遲,最終都會影響到應用端的用戶體驗。當然,你可以將延遲設置在幾毫秒內,但是即使是這樣還是會影響到客戶端的時效性。

MySQL8.0復制性能的提升

截至目前(2017年8月)的MySQL 8.0最新發布了beta版本,起初是為了組復制(GR)開發的,但是由於GR在底層也是使用的普通復制,普通復制也受益匪淺。我們提到的改進是8.0在binary log中加入了一些依賴的跟蹤信息。在MySQL8.0中,MySQL通過一種方法能夠存儲記錄那些行受到了那些事物的影響信息(稱之為writeset),而且MySQL可以對比不同事物的writeset信息,這樣就可以將兩個事物是否是對同一個對象的同一行進行操作,如果不是,就可以並行執行。這相比於MySQL5.7的復制又提升了一個級別。你需要牢記的事,最終,從庫看到的數據可能會出現和主庫不同的情況,這種情況是永遠不會發生在主庫的。發生這種情況的原因是因為,從庫執行事物的順序可能和主庫執行事物的順序是不一致引起的。雖然這並不能稱之為一個問題,MySQL5.7的並行復制機制也是會產生這個問題的,除非你指定啟用了slave-preserve-commit-order這個參數。

為了避免這種情況的發生,MySQL8.0新增了binlog_transaction_dependency_tracking 參數來解決這個問題。他可以取以下三個值:

  • COMMIT_ORDER:默認設置,默認設置為MySQL5.7的默認機制

  • WRITESET:它能夠實現更好的並行化,並且主庫開始在二進制日誌中存儲寫入writeset信息

  • WRITESET_SESSION:設置事物在從庫是順序執行的,這就消除了我們上面說的從庫查看數據可能會存在和主庫不同的情況。設置為這個值會雖然會降低並行復制的性能,但是相比默認設置來說,性能還是有很大提升的。

基準測試

7月份,Vitor Oliveira在mysqlhighavailability.com上寫了一篇文章,他試圖測試復制新模式下的性能。在他的測試中,使用了最理想的情況-沒有做數據持久化,借此來對比新舊復制模式下的性能。我們決定使用相同的方法,這一次在一個更接近生產的設置:使用log_slave_updates啟用二進制日誌。持久化參數在MySQL8.0中是默認的(sync_binlog=1-這在MySQL8.0是默認的,開啟了雙寫緩存和innodb校驗),innodb_flush_log_at_trx_commit設置為2。

我們看一下機器的配置,32G,8核(slave_parallel_workers 設置為8),測試工具為sysbench的oltp_read_write.lua腳本,32個表中的1600萬行存儲在1000GB gp2卷上(即3000 IOPS),我們在所有復制模式下分別開1,2,4,8,16,32並發對性能進行測試和對比。測試過程如下:停止slave,執行100000個事物,打開slave並計算從庫追上主庫的時間。 技術分享

首先,我們不知道當使用1個線程執行sysbench時發生了什麽。每次測試在暖機運行後執行了五次。這個特殊的配置被測試了兩次 - 結果是穩定的:單線程工作量是最快的。我們將進一步研究,以了解到底是為什麽。

除此之外,一切都符合我們的預期。COMMIT_ORDER是最慢的,特別是對於低流量,2-8線程。 WRITESET_SESSION通常比COMMIT_ORDER效率更好,但是對於低並發流量,它比WRITESET慢。

這對我來說有什麽好處?

第一個益處是顯而易見的,如果你的數據庫負載較高,而且從庫有延遲的話,你可以通過將主庫升級為MySQL 8.0來提升復制的性能。這裏需要留意兩個方面:第一,此功能向下兼容,即使的從庫是MySQL 5.7,性能也能有很好的提升;第二,MySQL8.0暫時並沒有GA,所以說不推薦在生產庫使用Beat版本。MySQL8.0對復制的提升不僅能夠很好解決從庫延遲的問題,這種情況下主從的延遲幾乎是沒有的,除非你重新添加一個新的slave或者重新配置了slave的時候可能會產生延遲。如果使用“WRITESET”模式將使得配置新主機的過程更加快捷。

總而言之,這個功能可能比你預期的產生更大的影響,鑒於所有基準測試,顯示MySQL處理低並發性流量時的性能回歸,任何有助於提高在這種環境中復制的效率的任何操作都將是巨大的進步。

如果你使用了級聯復制,這也是你需要了解的一個功能。任何中間主節點都會將事務處理和執行的方式添加一些序列化的信息-但是真是情況卻是,中間節點的負載要比主庫要小。因為他使用了一些寫入組件來實現更好的並行化,從而提高了自身和自身從庫的並行效率。甚至你可以通過將中間節點的主庫升級為MySQL8.0來提高下層從庫的節點(請記住,MySQL 5.7從站可以識別riteet數據並使用它,即使它不能自己生成它)。當然,MySQL 8.0到5.7的主從復制聽起來確實是很棘手的,這倒不是因為MySQL8.0還沒有GA的原因。當然在一些情況下,這可以使從庫的CPU使用率得到很好的提升。

MySQL復制的其他變化

MySQL8.0對於復制最主要的提升就是引入了writesets,但是這並不是唯一的變化。讓我們來看一下其他的一些重要的改進,如果你的主庫是MySQL5.0以下版本,8.0將不再支持讀取它的二進制日誌,所以如果你使用的還是老版本的MySQL進行傳統復制,是時候升級你的數據庫版本了。 為了確保復制的安全性和穩定性,修改了復制了默認參數:master_info_repository 和relay_log_info_repository 默認將設置為table,Expire_log_days 默認設置為30,除了Expire_log_days ,還新增了一個參數binlog_expire_log_seconds,這將對binlog的輪詢策略實現更細粒度的管控。在binlog信息中將會添加一些額外的時間戳信息,目的是能夠更好的觀察監控復制的延遲,達到微妙級別。

總而言之,這不是與MySQL復制相關的更改和功能的完整列表。你可以訪問這裏獲得完整的列表信息,了解復制功能的所有的改進和提升。

如我們所知,MySQL的復制正在變化,而且越來越好。正如我們開始所說,雖然這是一個緩慢進步的過程,但是我們已經可以看到了它的大好前景了。而且我們也很高興看到Group Replication的底層復制也是采用了常規復制的功能來。

MySQL 8.0復制性能的提升(翻譯)