系统高可用/容灾,是每一个系统运维人员很是关心的一个话题。只有高可用作好,才从容的应对区域性系统灾难故障。而数据才是须要保护的核心。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