MySQL 8 複製(十)——組複製效能與限制

lhrbest發表於2020-02-12


目錄


一、組複製效能


1. 概述


2. 測試規劃


3. 訊息壓縮


4. 組通訊執行緒迴圈


5. 寫入集


6. 流控


7. 其它配置


8. 主從、半同步、組複製效能對比測試


二、組複製要求與限制


1. 組複製要求


2. 組複製限制


一、組複製效能

1. 概述

        組複製的基本保證是,只有在組中的大多數節點接收到事務並且就併發事務的相對順序達成一致之後,才會提交事務。其對事務的基本處理流程為:


在提交之前攔截伺服器接收到的客戶端事務,並構建事務寫入集。該寫入集唯一標識了對應事務所修改的資料集合。

將寫入集傳送給組成員,並就併發事務的應用順序達成一致。

如果事務與之前的事務不存在衝突則提交,否則回滾該事務。即相互衝突的事務第一個成功提交,其它回滾。

        影響組複製效能的元件主要有三個:組通訊層、認證和二進位制日誌應用程式。


(1)組通訊層

        組複製實現了一個基於Paxos協議的組通訊層,以允許多個伺服器在事務提交順序上達成一致。傳送給組通訊層的訊息在每個組成員中以相同的順序接收。Paxos協議很複雜,但為了理解組複製中實現變體對效能的影響,需要知道處理一個典型訊息的過程:


從訊息源向每個其它組成員傳送帶有使用者事務的訊息。

向訊息源傳送每個接收者的投票資訊,當達到多數票後,客戶端將訊息視為已傳遞。

將訊息源所接收的資訊傳送給其它所有組成員。

        由此可見,組複製效能的關鍵因素是網路吞吐量(可以在網路通道中容納多少並行訊息)和節點到節點的延遲(需要多長時間才能與傳送方達成一致)。Paxos的組複製實現包括許多優化,如並行處理多條訊息,並將多個訊息打包成一個訊息,以便在可能的時候傳送到每個節點。從使用者角度來看到的結果是:


在現有網路頻寬下,傳送者將盡可能多的事務傳送到其它節點。節點間的實際頻寬是網路頻寬除以組成員數量。

在準備好提交之後,每個事務將被延遲至少從傳送者到接收者的一箇中間網路往返時間。

(2)認證

        從組通訊層接收到的事務訊息會被放入一個佇列進行認證。在每個節點中執行的演算法判斷認證結果以決定如何處理事務。若認證通過,事務被認為在面向客戶端的伺服器(事務發起方)上完成,然後在本地中繼日誌中排隊,以便在其它組成員上執行後續操作。反之如果認證失敗,事務將根據需要被丟棄或回滾。


        認證是在每個節點接收到正確排序的事務訊息後獨立完成的,因此不需要進一步的網路同步活動。認證演算法在一個專用執行緒中執行,該執行緒遵循由組通訊層建立的事務順序,如果事務是遠端的,則將其寫入中繼日誌。因為認證每個事務都需要時間,所以該過程可能成為爭用點。影響認證吞吐量的主要因素是中繼日誌頻寬,如果用於本地中繼日誌的儲存子系統(即認證事務排隊等待應用程式執行緒的儲存子系統)無法跟上寫入請求,其事務認證佇列開始增長,事務應用開始落後於發起事務的成員。從下面的查詢可以獲得每個組成員認證佇列大小的近似值:


select member_id, count_transactions_in_queue from performance_schema.replication_group_member_stats;

        多主組複製中,由於多個組成員都可以執行寫事務,gtid_executed集合的複雜性可能成為另一個影響認證效能的因素。當多個成員同時向組寫入時,認證資料庫上執行的大量gtid_executed集合可能變得難以處理,因為其中可能出現許多間隙,並且無法按照GTID範圍進行壓縮。這也可以看作是成員節點之間的吞吐量平衡性降低了。


(3)二進位制日誌應用程式

        將事務寫入中繼日誌後,它們就可以像非同步或半同步複製一樣,由複製的二進位制日誌應用程式執行。然而,組複製的二進位制日誌應用程式有一個應該注意的細微差別。一旦組成員對事務進行了認證,認證程式會立即將事務更新行標記為已更改,但實際該事務可能會在中繼日誌中保留一段時間等待應用。多主模式中,在此期間嘗試更改這些行的本地事務都被回滾。


        與MySQL傳統主從非同步複製同理,具有足夠執行緒的MTS(multi-threaded slave)應用程式來處理接收到的工作負載,有助於增加從庫的吞吐量。對於非同步複製,LOGICAL_CLOCK排程程式使用二進位制日誌組提交機制來確定哪些事務可以在從庫上並行執行。組提交能提高從庫併發度。但是,儲存子系統速度太快或客戶端併發量太小都會使提交組中的事務變少(一個組提交不能包含來自同一客戶端的多個事務),從而降低了效率。尤其是在級聯複製中,因為複製執行緒通常比使用者執行緒少的多,這意味著較低階別從庫的並行度更低。


        使用選項binlog_group_commit_sync_delay或binlog_group_commit_sync_no_delay_count可以增加提交組中的事務數量,以抵消儲存速度過快的影響。而基於寫集(WRITESET)的依賴跟蹤允許更高的並行度,特別是在低併發工作負載下。基於寫集的依賴項跟蹤可能重新排序來自同一會話的事務,這意味著來自同一會話的兩個事務在主從庫的提交順序可能不同。以犧牲一點效能為代價,可以選擇強制使用slave_preserve_commit_order選項來保持從庫上會話歷史與主庫保持一致。


        組複製考慮了用於驗證每個成員中事務的寫入集,並根據認證順序和事務更改的資料行構建依賴項。如果兩個事務在其寫入集中存在相同的行,則它們不能在從庫中並行執行,因此後一個更新這些行的事務將依賴於前一個事務。


        關於多執行緒複製的詳細討論,參見“MySQL 8 複製(六)——拓撲與效能”。


        簡單說,組複製效能受限於組通訊層、認證和二進位制日誌應用程式三個主要元件:


缺乏網路頻寬會降低在途訊息數量,而高的網路往返時間會相應地增加使用者事務延遲。

缺乏中繼日誌儲存頻寬會延遲認證,因此要注意認證佇列的增長。

二進位制日誌應用程式瓶頸除了會增加複製延遲外,還可能增加多主場景中的事務中止。

        對於每個元件,組複製提供了若干選項,適當配置這些選項可以從底層計算資源中獲取最佳效能。後面小節中將詳細介紹這些選項。


        MySQL官方描述的組複製效能影響因素,參見http://mysqlhighavailability.com/tuning-mysql-group-replication-for-fun-and-profit/。


2. 測試規劃

        在討論具體選項配置前,希望使用一個統一的測試方法,對比不同配置值對複製效能產生的影響,測量的指標包括主、從庫的每秒事務數(TPS)和從庫的複製延遲時長。測試目的在於對比不同配置情況下組複製的效能,而不是針對測量絕對值進行優化。這裡使用的思路是:主庫加壓,同時從庫複製。記錄加壓前後的GTID,得到需要執行的總事務數。主庫的執行時間等於加壓時間。等待從庫應用完所有事務,記錄從庫的執行時間。用總事務數除以相應執行時間得到主、從庫的TPS。加壓使用tpcc-mysql基準測試工具。


(1)測試環境

        單主模式下一主兩從的組複製基本資訊如下:

單主庫:172.16.1.125

 從庫1:172.16.1.126

 從庫2:172.16.1.127


MySQL版本:8.0.16

作業系統:CentOS Linux release 7.2.1511 (Core)


硬體配置:

三個伺服器均為Linux虛擬機器,雙核雙 2.10GHz CPU,8G實體記憶體,100G硬碟空間,1000MB/s 網路卡。MySQL例項基本配置:


[mysqld]

server_id=1125    # 兩個從庫為1126、1127

gtid_mode=ON

enforce-gtid-consistency=true

innodb_buffer_pool_size=4G

disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

 

log_bin=binlog

log_slave_updates=ON

binlog_format=ROW

binlog_checksum=NONE

master_info_repository=TABLE

relay_log_info_repository=TABLE

 

plugin-load=group_replication.so

group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"

group_replication_start_on_boot=off

group_replication_local_address= "172.16.1.125:33061"    # 兩個從庫為"172.16.1.126:33061"、"172.16.1.127:33061"

group_replication_group_seeds= "172.16.1.125:33061,172.16.1.126:33061,172.16.1.127:33061"

group_replication_bootstrap_group=off

        為保證不同配置的測試環境相同,每次修改配置後重啟三個MySQL例項。開始測試前,使用下面的指令碼重啟組複製:


-- 主

change master to master_user='repl', master_password='123456' for channel 'group_replication_recovery';

set global group_replication_bootstrap_group=on;

start group_replication;

set global group_replication_bootstrap_group=off;

select * from performance_schema.replication_group_members;

 

-- 從

stop slave;

reset slave all;

change master to master_user='repl', master_password='123456' for channel 'group_replication_recovery';

start group_replication;

(2)測試指令碼

        每次測試只需要執行同一個指令碼檔案tpcc_test.sh,內容如下:


[mysql@hdp2~/tpcc-mysql-master]$more tpcc_test.sh

# 初始化tpcc資料

mysql -uwxy -p123456 -h172.16.1.125 < tpcc_test.sql

 

# 開始GTID

read start_gtid < <(mysql -uwxy -p123456 -e "show variables like 'gtid_executed';" --skip-column-names | awk '{print $2}' | sed "s/\\\n//g")

 

# 等待從庫執行完初始化複製

mysql -uwxy -p123456 -h172.16.1.126 -e "select wait_for_executed_gtid_set('$start_gtid');" > /dev/null &

mysql -uwxy -p123456 -h172.16.1.127 -e "select wait_for_executed_gtid_set('$start_gtid');" > /dev/null

 

# 開始時間

start_time=`date '+%s'`

 

# 主庫執行壓測,10個倉庫,32個併發執行緒,預熱1分鐘,壓測5分鐘

tpcc_start -h172.16.1.125 -d tpcc_test -u wxy -p "123456" -w 10 -c 32 -r 60 -l 300 > tpcc_test.log 2>&1

 

# 結束GTID

read end_gtid < <(mysql -uwxy -p123456 -e "show variables like 'gtid_executed';" --skip-column-names | awk '{print $2}' | sed "s/\\\n//g")

 

# 等待從庫執行完複製

mysql -uwxy -p123456 -h172.16.1.126 -e "select wait_for_executed_gtid_set('$end_gtid'); select unix_timestamp(now());" --skip-column-names | awk 'NR>1' > end_time1 &

mysql -uwxy -p123456 -h172.16.1.127 -e "select wait_for_executed_gtid_set('$end_gtid'); select unix_timestamp(now());" --skip-column-names | awk 'NR>1' > end_time2

 

# 結束時間

end_time1=`cat end_time1`

end_time2=`cat end_time2`

 

# 複製執行時長

elapsed1=$(($end_time1 - $start_time))

elapsed2=$(($end_time2 - $start_time))

 

# 執行的事務數

read start end < <(mysql -uwxy -p123456 -e "select gtid_subtract('$end_gtid','$start_gtid');" --skip-column-names | awk -F: '{print $2}' | awk -F- '{print $1,$2}')

trx=$(($end - $start + 1))

 

# 計算主庫、從庫的TPS

Master_TPS=`expr $trx / 360`

Slave1_TPS=`expr $trx / $elapsed1`

Slave2_TPS=`expr $trx / $elapsed2`

 

# 列印輸出

echo "TRX: $trx" 

echo "Master TPS: $Master_TPS"

echo "Elapsed1: $elapsed1" "Slave1 TPS: $Slave1_TPS"

echo "Elapsed2: $elapsed2" "Slave2 TPS: $Slave2_TPS"

        關於tpcc工具的安裝和tpcc_test.sql檔案的生成及作用,參見https://wxy0327.blog.csdn.net/article/details/94614149#1.%20%E6%B5%8B%E8%AF%95%E8%A7%84%E5%88%92。每條指令前的註釋已經明確表明其用途,這裡做兩點補充說明:


MySQL組複製要求表具有主鍵。tpcc測試庫中的history表沒有主鍵,因此需要手工編輯tpcc_test.sql檔案,在其建表的create table語句中增加主鍵定義。這完全是為了滿足組複製的要求,因此只要將所有欄位一起定義成聯合主鍵即可,即使出現主鍵重複的錯誤,也不會影響測試繼續進行。況且這裡要得到的只是對比結果,而測試結果的絕對值並無多大參考意義。

使用MySQL 5.7.5新增的wait_for_executed_gtid_set函式,等待從庫應用完事務,返回複製結束時間。本測試中採用一主兩從的組複製拓撲,需要並行但分別取得兩個從庫的結束時間,因此使用 & 符號,將第一條執行wait_for_executed_gtid_set的命令在後臺執行。這樣可以獲得兩個從庫各自的執行時間,而後面的命令會在它們都執行完後才開始執行,而不論它們誰先執行完。

(3)執行預設配置測試

        獲得預設配置的測試結果,作為後面不同配置的對比基準。測試結果如下:

TRX: 176527

Master TPS: 490

Elapsed1: 708 Slave1 TPS: 249

Elapsed2: 922 Slave2 TPS: 191


        預設配置下,主庫360秒內執行了 176527 個事務,TPS為490。從庫1執行了708秒,比主庫延時了348秒,TPS為249。而從庫2更慢,執行了922秒,比主庫延時了562秒,TPS僅為191。


3. 訊息壓縮

        當網路頻寬成為瓶頸時,訊息壓縮可以在組通訊層提高吞吐量。如圖1所示,壓縮發生在組通訊系統API級別,因此事務負載可以在被髮送到組之前被壓縮,並且在成員接收事務時進行解壓縮。壓縮使用LZ4演算法,閾值預設為1000000位元組,由group_replication_compression_threshold引數控制,即只壓縮大於該引數指定位元組數的事務,設定為0將禁用壓縮。收到訊息後,組成員檢查訊息是否被壓縮。如果需要,該成員在將事務交付給上層之前解壓縮該事務。組複製不要求組中的所有伺服器都同時啟用壓縮。

MySQL 8 複製(十)——組複製效能與限制


圖1

        將group_replication_compression_threshold設定為0、100、1024時的測試結果如下表:


group_replication_compression_threshold


TRX


Master TPS


Slave1 Elapsed


Slave1 TPS


Slave2 Elapsed


Slave2 TPS


0


175932


488


727


241


914


192


100


175384


487


715


233


895


195


1024


176601


490


743


237


904


195


        禁用壓縮、壓縮大於100位元組的事務、壓縮大於1K位元組的事務,與預設壓縮大於1000000位元組的事務相比,在我的測試環境中,主、從庫的TPS、從庫複製延時並無顯著差異。結論是此測試環境和負載壓力下,網路傳輸不是瓶頸,因此後面的測試保持group_replication_compression_threshold的預設值不變。


4. 組通訊執行緒迴圈

        組通訊執行緒(Group Communication Thread,GCT)在載入組複製外掛後迴圈執行。GCT從組外掛接收訊息,處理仲裁和故障檢測相關任務,傳送活動訊息,並處理伺服器和組之間的雙向事務傳輸。當佇列中沒有訊息時,GCT進入睡眠狀態。通過在實際進入睡眠狀態之前將等待時間設定為稍長,即進行主動等待,在某些情況下是有益的,因為GCT頻繁休眠可能浪費可用的CPU時間。要強制GCT執行活動等待,使用group_replication_poll_spin_loops選項。此選項控制GCT在進入睡眠狀態前嘗試接收訊息的次數,也可說是控制通訊執行緒的貪婪程度,預設值為0。在網速很慢的環境中,適當配置該選項可以降低事務延遲。


        這裡沒有針對group_replication_poll_spin_loops引數進行不同配置的實驗,原因有二:一是在我的實驗環境下網路不是瓶頸,這點從上面的壓縮選項測試中已經得到佐證。二是即便在慢網環境中,按MySQL官方文件的說法,該選項也只是作為一種微調手段。


5. 寫入集

        在前面測試執行過程中,通過執行查詢觀察認證佇列中的事務數量:


select member_id, count_transactions_in_queue from performance_schema.replication_group_member_stats;

        發現count_transactions_in_queue的值始終很小,大於0的時候非常少,而且最大也不過十幾。從組複製的流程可知,認證不存在積壓情況。但是從庫延遲如此之大,網路無瓶頸,認證不積壓,剩下就是針對二進位制日誌應用程式做調整了。從前面的組複製效能概述中,自然想到了MTS和WRITESET,於是修改以下配置選項繼續測試。


主庫啟用寫入集增加組提交併行度

binlog_transaction_dependency_tracking  = WRITESET

transaction_write_set_extraction        = XXHASH64

從庫啟用8執行緒MTS

slave_parallel_type = LOGICAL_CLOCK

slave_parallel_workers = 8

slave_preserve_commit_order=1

        測試結果如下:

TRX: 175459

Master TPS: 487

Elapsed1: 478 Slave1 TPS: 367

Elapsed2: 589 Slave2 TPS: 297


        可以看到,總事務數和主庫的TPS沒有基本不變,但兩個從庫的TPS卻增加了50%以上,吞吐量明顯得到提升。但即便如此,兩個從庫的複製延遲還是分別將近2分和4分鐘。說明在此壓力負載下,從庫無力追趕上主庫。如果一定要縮減主從之間的複製延遲時間,就要啟用下面介紹限流措施。


        MySQL官方提供的寫入集與多執行緒下組複製基準測試,參見https://mysqlhighavailability.com/zooming-in-on-group-replication-performance/。


6. 流控

        組複製可確保事務僅在組中的大多數成員收到事務,並同意所有併發傳送事務之間的相對順序後提交。如果對組的寫入總量不超過組中任何成員的寫入容量,則此方法很有效。如果某些成員的寫入吞吐量低於其它成員,特別是少於主庫,那些成員可能會開始落後於主庫。必須強調的是,MySQL組複製並不要求成員保持同步,複製延遲只會增加本地中繼日誌中掛起的事務數。


        成員落後於組會帶來一些問題,例如:對這些成員的讀取可能會使舊資料外化到應用程式;組中其它成員可能必須儲存更多複製上下文,以便能夠滿足來自慢成員的資料傳輸請求等等。組複製協議中存在一種被稱為流量控制的機制,可以避免快速和慢速成員之間的應用事務存在太大距離。它試圖達到的主要目標是保持成員的已執行事務足夠接近。


        流量控制依賴於兩種基本機制:


監控伺服器,收集所有組成員的吞吐量和佇列大小統計資料,對每個成員可以承受的最大寫入量進行有根據的猜測。

限制伺服器,避免寫入超出其可用容量限制。

(1)探測和統計

        監控機制的工作原理是讓每個成員部署一組探針來收集有關其工作佇列和吞吐量的資訊。成員會定期將該資訊傳播給組,以便與其它成員共享這些統計資料。此類探針分散在整個外掛中,允許建立以下指標:


認證佇列大小。

複製應用程式佇列大小。

經認證的事務總數。

成員中應用的遠端事務總數。

本地事務總數。

        監控資料每秒與組中其它成員共享一次。一旦成員收到其它成員的統計資訊,它將計算在上一個監控週期內認證、應用和本地執行的事務數量。


(2)限流

        根據在組中所有伺服器上收集的統計資料,限制機制決定成員能夠提交新事務的速率。流量控制考慮了兩個工作佇列:認證佇列和二進位制日誌應用程式佇列,因此使用者可以選擇在認證器或複製應用程式執行流量控制,或者兩者都執行。使用以下變數控制相應佇列的大小:


group_replication_flow_control_mode:指定是否開啟流控,可取值為quota和disable。預設值為quota,表示啟用流控限額,如果指定為disable則禁用流控。

group_replication_flow_control_certifier_threshold:如果認證佇列中的事務數超過該變數值觸發認證流控,預設值為25000,值域為0-2147483647。

group_replication_flow_control_applier_threshold:如果複製應用佇列中的事務數超過該變數值觸發應用流控,預設值為25000,值域為0-2147483647。

        如果認證佇列或二進位制日誌應用程式佇列大小超過使用者定義的閾值,則限制機制將強制執行寫入配額。配額將本監控週期的事務數比上一週期減少10%,以允許觸發問題的佇列減小其大小。為了避免吞吐量的大幅跳躍,增加吞吐量同樣僅允許增長上個週期的10%。當前的限制機制不會影響低於配額的事務,但會延遲完成那些超過它的事務,直到監控期結束。


        從前面的測試中已知,認證佇列始終很小,基本不存在積壓,複製延遲主要是由從庫的複製應用程式緩慢造成的。因此調整主庫的group_replication_flow_control_applier_threshold變數以對應用佇列進行流控,縮小主從複製延遲。該變數設定為100、1000、10000時的測試結果如下表:


group_replication_flow_control_applier_threshold


TRX


Master TPS


Slave1 Elapsed


Slave1 TPS


Slave2 Elapsed


Slave2 TPS


100


98469


273


361


272


361


272


1000


106442


295


361


294


363


293


10000


162866


452


461


353


556


292


        從表中看到:


當group_replication_flow_control_applier_threshold=100時,兩個從庫基本沒有延遲,但整個組的TPS只有273左右。

當group_replication_flow_control_applier_threshold=1000時,兩個從庫的延遲依然很小,整個組的TPS為294,提升了不到8%。

當group_replication_flow_control_applier_threshold=10000時,從庫1、從庫2分別延遲了100秒和200秒,主庫、從庫1、從庫2的TPS分別是452、353、292。

        在本測試環境的壓力下,解讀表中的結果可得以下結論:


組複製的吞吐量和主從複製延時無法兼得。

要保持主從複製低延時,組複製的吞吐量取決去最小TPS的節點,符合木桶原理。

group_replication_flow_control_applier_threshold大於某一閾值時,主從延遲將變得非常明顯。

7. 其它配置

(1)訊息分段

        當組複製組成員之間傳送異常大的訊息時,可能會導致某些組成員報告為失敗並從組中移除。這是因為組通訊引擎使用的單個執行緒被處理訊息佔用時間太長,使得某些組成員將接收狀態報告為失敗。從MySQL 8.0.16開始,預設情況下,大訊息會自動拆分為單獨傳送的訊息片段,並由接收方重新組裝為原訊息。


        系統變數group_replication_communication_max_message_size指定組複製通訊的最大訊息大小,超過該大小的訊息將被分段。預設值為10485760位元組(10MB),允許的最大值與slave_max_allowed_packet系統變數的最大值相同,即1073741824位元組(1GB)。group_replication_communication_max_message_size的值不能大於slave_max_allowed_packet的值,因為複製應用程式執行緒無法處理大於slave_max_allowed_packet的訊息片段。要關閉訊息分段,可將group_replication_communication_max_message_size設定為0。


        當所有組成員收到並重新組裝訊息的所有片段時,認為訊息傳遞已完成。分段訊息包括其標頭中的資訊,這些資訊在訊息傳輸期間加入,以使成員恢復之前傳送的早期訊息片段。如果組成員無法恢復訊息,則將其從組中移除。為了使複製組使用訊息分段,所有組成員必須為MySQL 8.0.16或更高版本,並且組使用的複製通訊協議版本也必須設定為8.0.16或更高版本。


        如果複製組因某些成員不支援而無法使用訊息分段時,系統變數group_replication_transaction_size_limit可用於限制組接收的最大事務。在MySQL 8.0中,預設值為150000000(約143MB),大於該值的事務將被回滾。


(2)XCom快取

        作為組複製協議的一部分,用於組複製的通訊引擎(XCom,Paxos變體)包括用於組成員之間交換的訊息及其後設資料的快取記憶體,用於與其它組成員通訊超時後重新連線時進行恢復。從MySQL 8.0.16開始,可以使用group_replication_message_cache_size系統變數設定XCom的訊息快取大小,預設值和最小值為1GB。如果達到快取大小限制,XCom將刪除已交付的最舊條目。


        如果重新連線成員時需要恢復訊息,但該訊息已從訊息快取記憶體中刪除,則該成員無法重新連線。當使用了group_replication_member_expel_timeout系統變數(在MySQL 8.0.13中引入)指定可疑成員從組中移除之前的延遲時間,更有可能發生這種情況。組複製通訊系統(GCS)通過警告訊息告知使用者何時從訊息快取中刪除當前無法訪問的成員恢復時可能需要的訊息。此警告訊息記錄在所有活動組成員上,表明快取記憶體大小可能不足以支援移除成員之前的超時時間。在這種情況下,應參考group_replication_member_expel_timeout系統變數指定的時間段內的預期訊息量來增加快取記憶體大小,以便快取記憶體包含成員成功返回所需的所有錯過的訊息。


        可以使用以下語句查詢效能模式表memory_summary_global_by_event_name:


select * from performance_schema.memory_summary_global_by_event_name where event_name like 'memory/group_rpl/gcs_xcom::xcom_cache'\G

        這將返回訊息快取的記憶體使用情況統計資訊,包括當前快取條目數和快取的當前大小。如果減小快取大小限制,XCom將刪除已確定並交付的最舊條目,直到當前大小低於限制。在此刪除過程正在進行時,XCom可能會暫時超出快取大小限制。


(3)故障檢測

        組複製的故障檢測機制旨在識別不再與該組通訊的組成員,並在它們可能發生故障時將其移除。通常,所有小組成員定期與所有其它小組成員交換訊息。如果組成員在5秒內沒有收到來自特定成員的任何訊息,會引起對該成員的懷疑。當懷疑超時時,假定被懷疑的成員失敗,並將其移出該組。被移除成員從其它成員看到的成員列表中刪除,但它不知道自己已被移出該組,因此它將自己視為線上而其它成員無法訪問。如果該成員實際上沒有失敗(例如網路閃斷)並且能夠恢復與其它成員的通訊,則它會收到已被從組中移除的資訊。預設情況下,如果懷疑某個成員失敗,則會發生以下行為:


當懷疑被建立時,它會立即超時(group_replication_member_expel_timeout預設值為0),因此成員只要被懷疑就會被立即移除。該成員可能會在超時後存活幾秒鐘,因為對過期懷疑的檢查會定期進行。

如果被驅逐的成員恢復通訊並意識到被移除,它不會嘗試重新加入該組。

當被驅逐的成員接受其移除時,它會切換到超級只讀模式(super_read_only)並等待管理員干預。

        這些預設設定優先考慮組能夠正確處理請求。但在較慢或不穩定的網路情況下,可能經常需要管理員干預來修復被移除的成員。可以使用組複製配置選項永久或臨時更改這些行為:


可以使用可從MySQL 8.0.13新增的group_replication_member_expel_timeout系統變數,在產生懷疑和移除可疑成員之間留出更多時間,最大為3600秒。處於此狀態的可疑成員不可訪問,但不會從組的成員列表中刪除。建立懷疑之前的5秒檢測週期是不可配置的。

可以使用可從MySQL 8.0.16新增的group_replication_autorejoin_tries系統變數指定成員被移除後嘗試重新加入該組的次數。預設值0表示成員不嘗試重新加入組,並繼續執行由group_replication_exit_state_action系統變數指定的操作(預設為READ_ONLY)。每次重試間隔5分鐘,最多可以進行2016次重試。在自動重新加入過程中,被移除成員保持超級只讀模式,並在其複製組檢視上顯示ERROR狀態。

可以使用group_replication_exit_state_action系統變數選擇未能重新加入(或不嘗試)的被移除成員的行為,可選值為ABORT_SERVER或READ_ONLY,預設值為READ_ONLY。ABORT_SERVER表示關閉MySQL伺服器,READ_ONLY表示切換為超級只讀模式。與自動重新加入過程一樣,如果成員進入超級只讀模式,則讀取過時舊資料的可能性會增加。指示成員自行關閉意味著MySQL Server例項不可用,必須重新啟動。無論設定了什麼退出操作,都需要管理員干預,因為已經耗盡其自動重新加入嘗試(或從未有過)並且已被移出組的成員不允許在不重新啟動組複製的情況下重新加入。

如果希望避免由於不適當的配置產生裂腦情況,可以使用系統變數group_replication_unreachable_majority_timeout設定成員在與大多陣列成員失去聯絡後等待的秒數。在此之後,將回滾該成員和少陣列中其它成員處理的所有待處理事務,並且該組中的伺服器將變為ERROR狀態,然後執行group_replication_exit_state_action指定的退出操作。

8. 主從、半同步、組複製效能對比測試

        現在將關注點從組複製效能本身,轉移到主從、半同步、組複製三種MySQL複製的橫向效能對比上。我們最為關心的是不同複製方式對主庫TPS的影響。測試環境不變,不同的只是更改相應的複製配置。三種複製均為一主兩從,具體測試步驟描述如下。(1)MySQL例項基本配置


[mysqld]

server_id=1125    # 兩個從庫為1126、1127

gtid_mode=ON

enforce-gtid-consistency=true

innodb_buffer_pool_size=4G

disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

 

log_bin=binlog

log_slave_updates=ON

binlog_format=ROW

binlog_checksum=NONE

master_info_repository=TABLE

relay_log_info_repository=TABLE

 

# 主庫啟用寫集

binlog_transaction_dependency_tracking  = WRITESET

transaction_write_set_extraction        = XXHASH64

 

# 從庫使用8執行緒MTS

slave_parallel_type = LOGICAL_CLOCK

slave_parallel_workers = 8

slave_preserve_commit_order=1

(2)啟動傳統主從複製


-- 在從庫執行

change master to

master_host = '172.16.1.125',

master_port = 3306,

master_user = 'repl',

master_password = '123456',

master_auto_position = 1;

start slave;

(3)執行主從複製測試


./tpcc_test.sh

(4)配置半同步複製


# 主庫增加配置:

plugin-load="rpl_semi_sync_master=semisync_master.so"

rpl_semi_sync_master_enabled=1

 

# 從庫增加配置:

plugin-load="rpl_semi_sync_slave=semisync_slave.so"

rpl_semi_sync_slave_enabled=1

        然後重啟三個MySQL例項。


(5)執行半同步複製測試


./tpcc_test.sh

(6)組複製配置

        去掉上一步的半同步配置,並增加組複製配置:


plugin-load=group_replication.so

group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"

group_replication_start_on_boot=off

group_replication_local_address= "172.16.1.125:33061"    # 兩個從庫為"172.16.1.126:33061"、"172.16.1.127:33061"

group_replication_group_seeds= "172.16.1.125:33061,172.16.1.126:33061,172.16.1.127:33061"

group_replication_bootstrap_group=off

        然後重啟三個MySQL例項。之後:


-- 主庫執行

reset master;

reset slave all;

change master to master_user='repl', master_password='123456' for channel 'group_replication_recovery';

set global group_replication_bootstrap_group=on;

start group_replication;

set global group_replication_bootstrap_group=off;

 

-- 從庫執行

reset master;

stop slave;

reset slave all;

change master to master_user='repl', master_password='123456' for channel 'group_replication_recovery';

start group_replication;

(7)執行組複製測試


./tpcc_test.sh

        三種複製測試結果如下表所示。


複製方式


TRX


Master TPS


Slave1 Elapsed


Slave1 TPS


Slave2 Elapsed


Slave2 TPS


主從


196808


546


360


546


435


452


半同步


189303


525


361


524


414


457


組複製


166032


461


462


359


561


295


        從測試結果可以看到,相同條件下:


半同步複製主庫的TPS是傳統主從複製的96%,組複製主庫的TPS是傳統主從複製的84%。

在複製延遲上,從庫1的傳統主從和半同步複製基本無延遲,從庫2的傳統主從延遲還大於半同步複製;而兩個從庫的組複製延遲都很大(100秒和200秒)。

傳統主從複製與半同步複製沒有提供縮小複製延遲的機制;組複製可以通過流控機制,減少從庫的複製延遲,代價是將組複製整體的吞吐量拉低到組中吞吐量最差節點的水平。

        由於組複製會帶來整體吞吐量的下降,大多數情況下,使用傳統主從非同步複製即可。如果在讀寫分離場景下要求讀取一致性,可以考慮半同步複製。與非同步複製相比,半同步複製的吞吐量並沒有顯著衰減。只有在首要需求為多主可寫、自動處理事務衝突、主庫失敗自動轉移等情況下,再考慮使用組複製。


        MySQL官方提供的組複製效能基準測試,參見http://mysqlhighavailability.com/an-overview-of-the-group-replication-performance/。


二、組複製要求與限制

        目前的MySQL組複製對於儲存引擎、網路頻寬、表設計,以及伺服器例項的配置還存在諸多要求與限制,尤其是多主模式,使用時更要格外注意。下面是MySQL官方文件中指出的已知問題,在實際應用中使用組複製前,有必要了解它們以幫助做出正確的選擇。在採坑前做到未雨綢繆總是有益的。


1. 組複製要求

(1)基礎架構


資料必須儲存在InnoDB事務儲存引擎中。事務以樂觀方式執行,然後在提交時檢查衝突。如果存在衝突,為了保持整個組的一致性,將回滾一些事務,因此需要事務儲存引擎。此外,InnoDB還提供了一些附加功能,可以在與組複製一起操作時更好地管理和處理衝突。使用其它儲存引擎(包括臨時MEMORY儲存引擎)可能會導致組複製出錯。可以通過在組成員上設定disabled_storage_engines系統變數來阻止使用其它儲存引擎,例如:

disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

組複製的每個表必須具有主鍵,或者具有等效的非空唯一鍵。它們作為表中每一行的唯一識別符號是必需的,這使得系統能夠通過準確識別每個事務已修改的行來確定哪些事務存在衝突。

網路效能會影響組的效能,網路延遲和網路頻寬都會影響組複製效能及穩定性。因此組複製中的MySQL伺服器例項應該部署在彼此非常接近的叢集環境中,使得所有組成員之間始終保持雙向通訊。如果阻止伺服器例項的收發訊息(例如通過防火牆限制),則該成員無法在組中執行,並且組成員(包括有問題的成員)可能無法報告受影響的伺服器例項的正確成員狀態。從MySQL 8.0.14開始,可以使用IPv4或IPv6網路基礎結構,或兩者的混合,用於遠端組複製伺服器之間的TCP通訊。

(2)伺服器例項配置

        必須在作為組成員的伺服器例項上配置以下選項:


設定--log-bin [= log_file_name] 啟用二進位制日誌,MySQL 8中預設啟用此選項。與其它MySQL複製方式一樣,組複製需要複製二進位制日誌內容,因此需要開啟二進位制日誌才能執行。

設定--log-slave-updates 記錄從庫更新。伺服器需要記錄通過複製應用程式應用的二進位制日誌。組中的伺服器需要記錄它們收到的所有事務並從組中應用。這是必需的,因為分散式恢復依賴組中成員的二進位制日誌進行。因此,每個事務的副本都需要存在於每個伺服器上,即使對於那些未在伺服器本身上啟動的事務也是如此。MySQL 8中預設啟用此選項。

設定--binlog-format = row 將二進位制日誌設為行格式。組複製依賴於基於行的複製格式,以在組成員之間一致地傳播更改。它依賴於基於行的基礎結構來提取必要資訊,以檢測在組中不同伺服器併發執行的事務之間的衝突。

設定--binlog-checksum = NONE 關閉二進位制日誌校驗。由於複製事件校驗和的設計限制,組複製無法使用它們,因此必須禁用。

設定--gtid-mode = ON 開啟全域性事務識別符號。組複製使用全域性事務識別符號來準確跟蹤在每個伺服器例項上已提交的事務,從而能夠推斷哪些伺服器執行的事務可能與其它地方已提交的事務衝突。換句話說,顯式事務識別符號是框架的基本部分,以便能夠確定哪些事務可能發生衝突。

設定--master-info-repository = TABLE和--relay-log-info-repository = TABLE,將複製資訊資料庫儲存到表中。複製應用程式需要將主庫資訊和中繼日誌後設資料寫入mysql.slave_master_info和mysql.slave_relay_log_info系統表。這可確保組複製外掛具有一致的可複製性和複製後設資料的事務管理。從MySQL 8.0.2開始,這些選項預設值為TABLE,而從MySQL 8.0.3開始,不推薦使用FILE設定。

設定--transaction-write-set-extraction = XXHASH64,以便在以將資料行記錄到二進位制日誌時,伺服器也會收集寫入集。寫入集基於每行的主鍵,唯一標識已更改的行,用於檢測事務衝突。MySQL 8中預設啟用此選項。

推薦設定slave_parallel_workers為大於零的值,啟用組成員上的多執行緒複製應用程式,最多可以指定1024個並行複製應用程式執行緒。設定slave_preserve_commit_order = 1,確保並行事務的最終提交與原始事務的順序相同,這是組複製所需的,它依賴於所有組成員以相同順序接收和應用已提交事務,以保證並行事務的資料一致性。slave_preserved_commit_order = 1需要設定slave_parallel_type = LOGICAL_CLOCK,該策略指定用於決定允許哪些事務在從庫上並行執行的策略。設定slave_parallel_workers = 0會禁用並行複製,併為從庫提供單個應用程式執行緒,而不是協調器執行緒。使用該設定,slave_parallel_type和slave_preserve_commit_order選項無效並被忽略。

2. 組複製限制

        組複製存在以下已知限制:


使用MINIMAL選項(--upgrade = MINIMAL)的MySQL伺服器升級後,無法啟動組複製,該選項不會升級複製內部所依賴的系統表。

認證過程沒有考慮間隙鎖。除非應用程式中依賴REPEATABLE READ語義,否則MySQL建議將READ COMMITTED隔離級別與組複製一起使用。InnoDB在READ COMMITTED中不使用間隙鎖,它將InnoDB中的本地衝突檢測與組複製執行的分散式衝突檢測統一化。

認證過程不考慮表鎖(LOCK TABLES和UNLOCK TABLES)或命名鎖(GET_LOCK)。

複製不支援SERIALIZABLE隔離級別。將事務隔離級別設定為SERIALIZABLE會將使組拒絕提交事務。

使用多主模式時,不支援針對同一物件但在不同伺服器上執行的併發資料定義語句(DDL)和資料操作語句(DML)。

多主模式不支援具有多級外來鍵依賴關係的表,特別是具有已定義CASCADING外來鍵約束的表。MySQL建議在多主模式組複製中設定group_replication_enforce_update_everywhere_checks = ON,以避免未檢測到的衝突。

當組複製以多主模式執行時,SELECT .. FOR UPDATE語句可能導致死鎖。

全域性複製過濾器不能在為組複製配置的MySQL伺服器例項上使用。

MySQL伺服器自MySQL 8.0.16起可以支援TLSv1.3協議,並且需要使用OpenSSL 1.1.1或更高版本編譯MySQL。組複製當前不支援TLSv1.3,如果使用此支援編譯伺服器,則在組通訊引擎中明確禁用它。

        如果單個事務太大,以至於在5秒鐘內無法通過網路在組成員之間複製訊息,則可能會懷疑成員失敗,然後被移出組。由於記憶體分配問題,大型事務也可能導致系統速度變慢。要避免這些問題,使用以下緩解措施:


儘可能嘗試限制事務規模。例如,將與LOAD DATA一起使用的檔案拆分為較小的塊。

使用系統變數group_replication_transaction_size_limit指定組接收的最大事務大小。超過此大小的事務將回滾,不會傳送到組。在MySQL 8.0中,此係統變數預設值為150000000位元組(大約143 MB)。

從MySQL 8.0.13開始,可以使用系統變數group_replication_member_expel_timeout來允許在懷疑失敗的成員在被移出之前有更多的時間。可以在最初的5秒檢測期後最多延長一個小時。

從MySQL 8.0.16開始,大型訊息會自動分段,這意味著大型訊息不會觸發引發懷疑的5秒檢測週期,除非此時存在其它網路問題。為了使複製組使用分段,所有組成員必須處於MySQL 8.0.16或更高版本,並且組使用的組複製通訊協議版本必須允許分段。如果MySQL版本不支援訊息分段,可以使用系統變數group_replication_communication_max_message_size來調整最大訊息大小,預設值為10485760位元組(10 MB),或通過指定零值來關閉分段。

————————————————

版權宣告:本文為CSDN博主「wzy0623」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結及本宣告。

原文連結:https://blog.csdn.net/wzy0623/article/details/97782304




About Me

........................................................................................................................

● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除

● 本文在itpub、部落格園、CSDN和個人微 信公眾號( xiaomaimiaolhr)上有同步更新

● 本文itpub地址: http://blog.itpub.net/26736162

● 本文部落格園地址: http://www.cnblogs.com/lhrbest

● 本文CSDN地址: https://blog.csdn.net/lihuarongaini

● 本文pdf版、個人簡介及小麥苗雲盤地址: http://blog.itpub.net/26736162/viewspace-1624453/

● 資料庫筆試面試題庫及解答: http://blog.itpub.net/26736162/viewspace-2134706/

● DBA寶典今日頭條號地址: http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

........................................................................................................................

● QQ群號: 230161599 、618766405

● 微 信群:可加我微 信,我拉大家進群,非誠勿擾

● 聯絡我請加QQ好友 646634621 ,註明新增緣由

● 於 2020-02-01 06:00 ~ 2020-02-31 24:00 在西安完成

● 最新修改時間:2020-02-01 06:00 ~ 2020-02-31 24:00

● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解

● 版權所有,歡迎分享本文,轉載請保留出處

........................................................................................................................

小麥苗的微店https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

小麥苗出版的資料庫類叢書http://blog.itpub.net/26736162/viewspace-2142121/

小麥苗OCP、OCM、高可用網路班http://blog.itpub.net/26736162/viewspace-2148098/

小麥苗騰訊課堂主頁https://lhr.ke.qq.com/

........................................................................................................................

使用 微 信客戶端掃描下面的二維碼來關注小麥苗的微 信公眾號( xiaomaimiaolhr)及QQ群(DBA寶典)、新增小麥苗微 信, 學習最實用的資料庫技術。

........................................................................................................................

歡迎與我聯絡

 

 



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2675331/,如需轉載,請註明出處,否則將追究法律責任。

相關文章