本文為您介紹PolarDB MySQL版基於物理複製架構,如何提升半同步複製(Semisynchronous replication,簡稱Semi-sync)的效率,降低對主庫的效能影響。主要內容包括背景介紹、功能介紹、注意事項、效能測試、常見問題等。
背景介紹
MySQL官方預設支援基於Binlog的半同步複製功能。在此模式下,主庫在事務提交前需要等待從庫確認已接收並同步了該事務所產生的Binlog日誌。然而,這種同步機制會引入額外的延遲,從而對主庫的寫入效能產生一定的影響。
PolarDB MySQL版基於物理複製架構,通過高效的Redo日誌在主備可用性區域之間進行同步,這使得半同步複製的效率顯著提高,從而大幅降低主庫的效能損失。在高並發負載情況下,與非同步模式相比效能降低約為10%。
相較於MySQL官方基於Binlog的半同步機制,PolarDB MySQL版基於物理複製(Redo 流)的半同步機制具備更高的同步效率。在事務執行過程中,Redo日誌的產生和同步鏈路就已經產生並即時傳輸到備可用性區域,因此,在事務提交時,僅需等待對應的這條Redo日誌成功同步至備可用性區域。而傳統的Binlog半同步機制則在事務提交時才產生完整的Binlog,此過程需要等到所有的Binlog日誌同步完成後,才能向用戶端返回操作成功的資訊。
功能介紹
PolarDB MySQL版半同步複製的邏輯相對容易理解:藉助物理複製架構,通過Redo日誌來完成主備可用性區域之間的同步工作。對於業務下發的寫入請求,會在主可用性區域完成資料修改時產生Redo日誌,並通過物理複製鏈路同步Redo資訊。在主可用性區域返回業務執行成功前,寫請求對應的寫事務需要等待備可用性區域確認收到對應的Redo日誌。
提交前最長等待時間
考慮到備可用性區域可能因某些非自然因素導致主可用性區域的寫入請求遲遲無法提交,因此,在核心層面會限制寫事務的提交前的最長等待時間,如果超過了設定時間仍未收到備可用性區域的同步確認資訊,主可用性區域將會自動認可已經逾時的寫入事務。
自適應機制
在極端情況下,備可用性區域可能無法及時向主可用性區域確認同步資訊,導致主可用性區域的每一條寫入請求都需要等待逾時後才能提交,造成效能損失。為了避免這一問題,半同步複製(Semi-sync)引入自適應機制,動態監測主備可用性區域之間的網路通訊情況,在發生逾時的情況較為頻繁時,會自動切換至非同步模式,保證主可用性區域的寫入不受Semi-sync的影響,同時在監測到主備可用性區域的同步情況恢複正常時,系統將自動重新開啟Semi-sync模式。
注意事項
PolarDB MySQL版基於物理複製的半同步模式能極大提升跨可用性區域切換的資料一致性,具體開啟流程請參見跨可用性區域自動切換。
目前僅PolarDB MySQL企業版,資料庫引擎為8.0.1且核心小版本為8.0.1.35.1及以上的叢集支援跨可用性區域資料複製的半同步模式。
PolarDB MySQL企業版,資料庫引擎為8.0.1且核心小版本為 8.0.1.1.40及以上,新增半同步模式自適應機制。
PolarDB MySQL企業版,資料庫引擎為8.0.1且核心小版本為8.0.1.1.44.2及以上,開放參數
innodb_polar_wait_slave_reply_max_time
用於控制開啟半同步複製後,主可用性區域寫事務在提交前預設最長等待時間,預設值500ms。
RPO和RTO
在非同步情境下,跨可用性區域自動切換功能是有損切換(絕大部分情況下RPO<100ms,最差情況下RPO<60s),使用前請進行評估。
在半同步情境下,開啟後效能衰退約10%,預設事務提交等待時間是500ms,超過500ms就會退化為非同步,不再等待同步至備可用性區域。無退化情況下RPO=0。
非同步和半同步情境下的RTO<30s。
效能測試
本文中的測試結果僅反映目前的版本的表現,並不代表最新版本的運行結果。
測試方式:同一個規格的叢集,對比PolarDB MySQL版開啟非同步模式、PolarDB MySQL版半同步模式和MySQL半同步模式的QPS效能差異。
測試載入器:Sysbench下的oltp_write_only。
測試規格:16C 64 GB。
測試版本:PolarDB MySQL版8.0.1版本且核心小版本為8.0.1.35.1(可能與最新版本存在微小差異)。
資料量:10張資料表,每張表1000萬行資料。
可以看到開啟Semi-sync在高並發情境下的效能衰減約為10%,並且在任何並發壓力下,PolarDB MySQL版基於Redo日誌方式的半同步複製的效能都要優於MySQL基於Binlog方式的半同步。
常見問題
Q1:為什麼開啟Semi-sync功能後,效能下降不止10%?
A1:在高並發的情況下,效能衰減最佳狀態約為10%,原因在於Redo通過batch的方式進行同步處理,從而有效降低了因網路延遲帶來的開銷。在低並發情境下batch帶來效能提升不夠顯著,因此可能會導致效能下降的情況較為嚴重,僅單線程寫入時,無法對Redo IO進行batch操作,因為開啟半同步複製後,增加了一個網路往返延遲從而明顯降低了效能。
Q2:為什麼控制台看不到innodb_polar_wait_slave_reply_max_time
這個參數?我該如何調整這個參數到一個合適的值?
A2:僅PolarDB MySQL企業版,資料庫引擎為8.0.1且核心小版本為8.0.1.1.44.2及以上叢集支援修改此參數,若控制台無法搜尋到參數,請先確認叢集版本是否滿足要求,若不滿足可以進行版本升級。
關於該參數的設定:通常情況下,您無需手動修改,預設值是500ms。如存在特殊需求,例如希望事務必須等到備可用性區域同步後再提交,可以適當增加此參數值,但絕大多數情況下預設的500ms已經足夠。如果希望限制事務的等待時間,可以適當降低該參數值。但需要注意的是,當設定的值非常小,例如0或1ms時(通常主備可用性區域的網路延遲維持在1ms以內,而半同步複製同步至少需要等待一次網路來回),這可能導致半同步模式退化為非同步模式,因此,修改此參數時需要結合實際情況進行考慮。
Q3:Semi-sync的自適應機制,什麼情況下生效?我可以開啟Semi-sync但是關閉自適應機制嗎?
A3:目前Semi-sync開啟後,系統會預設採用自適應機制,動態監聽主備可用性區域同步狀態,並即時進行調整。目前暫不支援單獨關閉自適應機制。如果希望Semi-sync功能保持生效狀態,可innodb_polar_wait_slave_reply_max_time
調整為一個較大的值,自適應機制將依賴於此參數值來判斷當前的逾時情況。
Q4:Semi-sync不發生退化時的RPO=0,這裡說的退化和自適應機制動態關閉是一回事嗎?
A4:二者並不相同。不發生退化是指任何事務在提交前,必須確保備可用性區域已經同步了相應的Redo資訊,在此情況下,可以嚴格保證RPO=0,但是自適應機制監測的粒度並非事務,而是網路包的通訊,當自適應機制動態關閉Semi-sync時,通常已經發生了多個事務因同步逾時而被提交的情況。換句話說,即使開啟了Semi-sync且並沒有被自適應機制關閉,此時RPO並不嚴格等於0,可能存在極個別事務因同步逾時而提交,但這屬於小機率事件,因此Semi-sync功能,能夠保證RPO無限接近於0。