背景
《SQL Server 2012实施与管理实战指南》中指AlwaysON同步过程如下:
任何一个SQL Server里都有个叫Log Writer的线程,当任何一个SQL用户提交一个数据修改事务时,
它会负责把记录本次修改的日志信息先记入一段内存中的日志缓冲区,然后再写入物理日志文件(日志固化)。
所以对于任何一个数据库,日志文件里都会有所有数据变化的记录。
对于配置为AlwaysOn主副本的数据库,SQL Server会为它建立一个叫Log Scanner的工作线程。
这个线程专门负责将日志记录从日志缓冲区或者日志文件里中读出,打包成日志块,发送给各个辅助副本。
由于它的不间断工作,才使主副本上的数据变化,可以不断地向辅助副本上传播。
在辅助副本上,同样会有两个线程,完成相应的数据更新动作,它们是固化(Harden)和重做(Redo)。
固化线程会将主副本Log Scanner所发过来的日志块写入辅助副本的磁盘上的日志文件里(这个过程被称为"固化")。
而重做线程,则负责从磁盘上读取日志块,将日志记录翻译成数据修改操作,在辅助副本的数据库上完成。
当重做线程完成其工作以后,辅助副本上的数据库就会跟主副本一致了。AlwaysOn就是通过这种机制,保持副本之间的同步。
重做线程每隔固定的时间点,会跟主副本通信,告知它自己的工作进度。主副本就能够知道两边数据的差距有多远。
这些线程在工作上各自独立,以达到更高的效率。Log Scanner负责传送日志块,而无须等待Log Writer完成日志固化;辅助副本完成日志固化以后就会发送消息到主副本,告知数据已经传递完毕,而无须等待重做完成。其设计目标,是尽可能地减少AlwaysOn所带来的额外操作对正常数据库操作的性能影响。
这个同步并不是数据的实时同步,当主副本数据发生变化时,同步模式下的辅助副本并不能立即取到变化的数据。哈哈 这个是不是很坑?据我所知有大型的软件产品因为这个陷阱吃了大亏!!
那么微软为什么不作成真正的实时同步呢?比如世面上的moebius集群,还能自动作负载均衡这多霸气? 我想微软还是从很多严谨性方面考虑吧,这里就不过多的废话了,下面进入这个同时间差到底有多大呢?
测试环境
SELECT @@VERSION 结果:
Microsoft SQL Server 2014 - 12.0.4100.1 (X64)
Apr 20 2015 17:29:27
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.2 (Build 9200: ) (Hypervisor)
系统server 2012 、sql 2014
3节点AlwaysOn 拓扑图:
实例名
IP
节点属性
VPC2012_1
192.168.2.55
主节点
VPC2012_2
192.168.2.56
同步辅助节点
VPC2012_3
192.168.2.57
异步辅助节点
工具准备
自开发测试程序、系统性能监视器、AlwaysOn监视器,系统性能计数器。
自开发程序介绍:
连接主副本和其中一个辅助副本,在设定的时间内循环 在主副本执行insert 操作,并根据设置的时间间隔,在辅助节点查询所插入的数据,如果查询到数据则成功,否则失败。
并发数:模拟并发压力,启动线程数。
等待时间:查询数据后查询等待的时间。
执行时间:模拟场景运行的时间。
系统性能监视器
通过系统性能监视器察看是否执行过程用有内存、磁盘队列、CPU压力。
性能计数器:
主要收集3个节点以下计数器观察AlwaysOn 同步状态
batch requests/sec 主要用于检查系统处理能力是否到达极限。
avg.disk read queue lenth 主要用于检查是否由于IO瓶颈导致时间延迟。
avg.disk write queue lenth 主要用于检查是否由于IO瓶颈导致时间延迟。
SQLServer:Database Replica 主要用于检查是否由于AlwaysOn同步异常导致时间延长。
测试展示
AlwaysOn压力测试工具
a) 测试以50并发 等待200毫秒开始,逐步增加等待时间查看并发数下的等待时间,当失败数为0时,增加并发数,测试等待时间下最大支持的并发数。
测试1同步节点
经过增加等待时间到1000毫秒 几次执行失败数均为0
增大并发测试 500并发左右1000毫秒出现失败情况
缩短等待时间错误数量大量增加
异步节点测试:
异步节点在节点无任何查询压力下等待时间大约为1200毫秒
系统指标
性能监控器监控期间CPU、内存、IO队列 未出现明显压力。
性能计数器
AlwaysOn仪表盘监测
结果
并发测试 500并发内AlwayOn需要1000毫秒左右才能完成数据可读,异步节点在节点无任何查询压力下等待时间大约为1200毫秒。
本例中的测试结果只是为了演示说明AlwaysOn同步节点数据可读时间的差异,而不是提供准确时间。
本例结果均针对本机AlwaysOn环境,及简单的测试语句,由于硬件环境,程序处理复杂度,数据量等等情况不同,结果也必不相同!!