系統高可用/容災,是每一個系統運維人員很是關心的一個話題。只有高可用作好,才從容的應對區域性系統災難故障。而數據纔是須要保護的核心。html
那基於AWS雲平臺的數據庫,咱們能作哪些高可用的架構設計呢?mysql
目前中國區,有北京和寧夏兩個獨立的Region。關於RDS,不只能作到Multi-AZ的設置,同時AWS還支持RDS的跨Region主從同步。sql
今天,咱們就討論基於Mysql的高可用/容災架構的性能測試。數據庫
1. 建立Replica Slave安全
2. 這裏咱們能夠選擇將Replica slave建立到「北京region」或者「寧夏region」。網絡
3. 因爲北京和寧夏的距離因素,你們都會關心北京Master和寧夏Replica的同步,會不會由於網絡延時,而致使lag較大?session
今天我就進行測試,看看網絡延遲,會對主從同步有多大影響。架構
(注: 北京region和寧夏region是沒有直接連通的,也就是說,客戶的EC2或者其餘服務的跨Region數據同步,都只能經過公網,或者本身準備的專線方式傳輸數據。可是AWS內部,會爲RDS的主從同步,以及S3 的 Cross Region Replication功能提供專用的線路,而且針對每一個account提供必定的帶寬)併發
測試環境準備,運維
<1. EC2 m4.xlarge (4CPU 16G) <2. RDS db.r4.xlarge (4CPU 16G ) Mysql版本5.7.12 <3. 建立兩個replica,一個在寧夏,一個在北京,主要是爲了比較同步狀況,確認和區分網絡因素的差別 <4. Mysql建立20個表,每一個表1000W行數據,數據量在40G左右 <5. 主庫使用sysbench進行壓力測試 ,sysbench使用方法參考: https://blog.51cto.com/hsbxxl/2068181 <6. 主庫的參數修改 binlog_format=row <7. 從庫的下面參數設置,利用5.7的relay work的併發性能 slave_parallel_workers=50
4. sysbench腳本
經過定時任務,執行sysbench腳本,每5分鐘執行一次 # crontab -l */5 * * * * /root/test.sh 每次執行150s,50個session併發讀寫20個表,每一個表1000W行數據 # cat test.sh date >> sync.log sysbench /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua \ --mysql-host=bjs.cbchwkqr6lfg.rds.cn-north-1.amazonaws.com.cn --mysql-port=3306 \ --mysql-user=admin --mysql-password=admin123 --mysql-db=testdb2 --oltp-tables-count=20 \ --oltp-table-size=10000000 --report-interval=10 --rand-init=on --max-requests=0 \ --oltp-read-only=off --time=150 --threads=50 \ run >> sync.log
5. 在主庫上,sysbench測試數據輸出以下,能夠根據輸出,肯定主庫的讀寫數據,進行參考:
[ 10s ] thds: 50 tps: 1072.24 qps: 21505.53 (r/w/o: 15060.08/4296.37/2149.08) lat (ms,95%): 89.16 err/s: 0.00 reconn/s: 0.00 [ 20s ] thds: 50 tps: 759.83 qps: 15195.04 (r/w/o: 10640.78/3034.21/1520.05) lat (ms,95%): 215.44 err/s: 0.00 reconn/s: 0.00 [ 30s ] thds: 50 tps: 631.10 qps: 12645.47 (r/w/o: 8853.55/2529.71/1262.21) lat (ms,95%): 262.64 err/s: 0.00 reconn/s: 0.00 ...... [ 130s ] thds: 50 tps: 765.94 qps: 15295.77 (r/w/o: 10701.91/3062.27/1531.59) lat (ms,95%): 125.52 err/s: 0.00 reconn/s: 0.00 [ 140s ] thds: 50 tps: 690.08 qps: 13776.96 (r/w/o: 9636.39/2761.41/1379.16) lat (ms,95%): 150.29 err/s: 0.00 reconn/s: 0.00 [ 150s ] thds: 50 tps: 749.51 qps: 15033.64 (r/w/o: 10532.97/3000.45/1500.22) lat (ms,95%): 147.61 err/s: 0.00 reconn/s: 0.00 SQL statistics: queries performed: read: 1458030 write: 416580 other: 208290 total: 2082900 transactions: 104145 (689.50 per sec.) queries: 2082900 (13790.04 per sec.) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 151.0422s total number of events: 104145 Latency (ms): min: 8.92 avg: 72.39 max: 7270.55 95th percentile: 167.44 sum: 7538949.20 Threads fairness: events (avg/stddev): 2082.9000/18.44 execution time (avg/stddev): 150.7790/0.44
如今咱們一塊兒看一下,在北京和寧夏的兩個replica的同步狀況
6. 指標Replica Lag (Milliseconds)
能夠看到,北京和寧夏的replica的同步性能基本是一致的,在每一個150s的寫週期,都會有lag的上升,基本延遲在40~50s左右。這說明,網絡不是瓶頸,由於北京的replica和Master在同一個AZ的同一個subnet。
北京
寧夏
7. 根據上圖結果能夠分析,主從的延遲,在Mysql自身replay的過程沒有跟上致使的延遲。
那麼,我將兩個replica的RDS機型升級到 8CPU 32G,進行測試,並比較結果。
能夠看到,升級機型,仍是有幫助的,lag明顯降低很多,將延遲維持在20~30S
北京
寧夏
也保持和北京相同的lag,更說明了,網絡不是同步的瓶頸。Mysql自身replay log,是一個性能瓶頸。
8. 再觀察CPU的使用率
因爲兩個replica只有同步數據的負載,因此能夠看到,同步數據的性能消耗,只有15%
後面的曲線是在我升級到8CPU 32G以後,只有7.5%的負載。說明硬件資源是足夠的,可是Mysql自身的緣由致使同步lag。
北京
寧夏
9. Write IOPS
穩定在4000左右,我實際分配的IOPS是6000,因此磁盤也不是瓶頸。另外,主庫能完成讀寫操做,理論上從庫只有寫操做,負載更低。物理硬件資源不會是限制。
北京
寧夏
10. 主庫的性能指標,能夠看到,一樣的配置,主庫的資源仍是夠用的。能知足讀和寫的需求。
CPU性能指標
11. Write IOPS性能指標
12. Read IOPS性能指標
13. Write throughput性能指標
14. 既然數據庫主機資源,和網絡不是瓶頸。那麼Mysql自身的問題,就須要咱們去逐步調整了。
接下來,針對mysql的參數進行調整優化。
說是優化,是儘可能下降備庫相關參數的影響,將IO相關的參數基本所有關閉,去跟隨OS層面的機制進行落盤。
實際上,replica的數據安全性要求相對主庫要小不少,因此,在從庫同步速度較慢的時候,結合實際狀況,調整下面參數,會有顯著的效果。
innodb_flush_log_at_trx_commit=0 innodb_flush_neighbors=0 innodb_flush_sync=0 sync_binlog=0 sync_relay_log=0 slave_parallel_workers=50 master-info-repository = TABLE relay-log-info-repository = TABLE
15. 調優以後的結果
寧夏
在調整完參數以後,效果立竿見影,從40s的延遲,下降到 5s左右
16. 再觀察一下北京區的replica(未調整Mysql參數)
依然仍是維持以前的lag,保持在50s的延遲狀況。
北京
17. 最後再調整一個參數,讓worker並行.默認狀況下,這個參數是database,也就是隻有在多個database被修改的狀況下,worker纔會並行工做。而實際狀況下,大部分客戶都是一個database(schema)多個tables的狀況。因此,將參數修改爲LOGICAL_CLOCK,才能起到並行的做用。
slave_parallel_type=LOGICAL_CLOCK
當worker並行以後,已經可以將主從延遲下降到2S之內了,基本能知足絕大部分業務場景了。
18. 測試總結
基於如下條件
硬件:4CPU 16G內存 6000IOPS磁盤
50個併發,每秒700個TPS,1.5W個QPS,1W個寫,的狀況下。
北京到寧夏的Mysql主從,能控制在10S之內的延遲。
若是對於replica的數據安全性要求比較高,即不調整Mysql落盤的參數狀況下,延遲在40~50s範圍。
根據實際狀況,你們能夠經過調整mysql參數,加大replica機型的方式,來獲取更好的同步性能。
Mysql做爲一個開源RDBMS,雖然在Oracle的技術支持下,有了很大的進步。可是replica的種種性能,和Oracle的Dataguard的同步相比,仍是有很大的差距。
後續我會繼續研究,如何能讓Mysql同步的更快。
19. 關於Mysql主從同步的調優:
<1. MySQL數據庫主從同步延遲原理。
答:談到MySQL數據庫主從同步延遲原理,得從mysql的數據庫主從複製原理提及,mysql的主從複製都是單線程的操做,主庫對全部DDL和 DML產生binlog,binlog是順序寫,因此效率很高,slave的Slave_IO_Running線程到主庫取日誌,效率很比較高,下一步, 問題來了,slave的Slave_SQL_Running線程將主庫的DDL和DML操做在slave實施。DML和DDL的IO操做是隨即的,不是順 序的,成本高不少,還可能可slave上的其餘查詢產生lock爭用,因爲Slave_SQL_Running也是單線程的,因此一個DDL卡主了,須要 執行10分鐘,那麼全部以後的DDL會等待這個DDL執行完纔會繼續執行,這就致使了延時。有朋友會問:「主庫上那個相同的DDL也須要執行10分,爲什 麼slave會延時?」,答案是master能夠併發,Slave_SQL_Running線程卻不能夠。
<2. MySQL數據庫主從同步延遲是怎麼產生的。
答:當主庫的TPS併發較高時,產生的DDL數量超過slave一個sql線程所能承受的範圍,那麼延時就產生了,固然還有就是可能與slave的大型query語句產生了鎖等待。
<3. MySQL數據庫主從同步延遲解決方案
答:最簡單的減小slave同步延時的方案就是在架構上作優化,儘可能讓主庫的DDL快速執行。還有就是主庫是寫,對數據安全性較高,好比 sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設置,而slave則不須要這麼高的數據安全,徹底能夠講sync_binlog設置爲0或者關閉binlog,innodb_flushlog也 能夠設置爲0來提升sql的執行效率。另外就是使用比主庫更好的硬件設備做爲slave。
參考文檔:
https://www.cnblogs.com/cnmenglang/p/6393769.html
https://dev.mysql.com/doc/refman/5.7/en/replication-options-slave.html