新一代读写分离技术——AlwaysOn
早在SQL Server 2005的时候微软就已经实现了数据库的查询分离技术——发布订阅。但生产库和查询库的同步性能较差,时常出现性能问题,因此在大型生产环境中一直被人所诟病。
从SQL Server 2012开始,微软逐渐使用AlwaysON技术来取代发布订阅。AlwaysOn 作为SQL Server 2012引入的一种新的技术架构,性能相比发布订阅而言提升很多,最明显的区别在于其充分利用内存高效读取的原理来实现日志的传递。下文将通过AlwaysOn的同步原理和可用模式来详细了解AlwaysOn的同步优势。
AlwaysOn同步原理
AlwaysON是一种整库同步的技术,所有的成员服务器都维护一套相同的数据库副本。当主副本上的数据发生变化时,数据会实时同步到辅助副本上。这点与数据库镜像非常类似。
下图详细描述了AlwaysON数据同步的整个过程,我们先来看看每个步骤所代表的意义。
① 主副本的logwiter把事务修改的日志信息先记入一段内存中的日志缓冲区,然后再写入物理日志文件(日志固化);
② 主副本的logscanner从缓存中或者日志文件中读取日志块,然后把它发送给AlwaysON的日志块解码器;
备注:解码器会搜索日志中那些需要特别处理的操作,比如file stream操作、文件增长等。
③ 主副本将日志块通过网络传送给辅助副本;
④ 和⑤
辅助副本接受到日志块后,logwiter把事务修改的日志信息先记入一段内存中的日志缓冲区,然后再写入物理日志文件(日志固化),另外,如果辅助副本处于同步可用模式时,在日志固化后,还必须反馈信息给主副本,主副本在接受到辅助副本完成固化的消息后才可以提交该事务,如果辅助副本在异步可用模式或者主副本在异步模式下,主副本提交事务与否跟辅助副本是否完成日志固化没有关系,下文在介绍可用模式时会详细介绍;
⑤ 重做(Redo)线程将日志中记录的事务在辅助副本上重新演绎。重做线程每隔固定的时间点,会跟主副本通信,告知它自己的工作进度。主副本就能够知道两边数据的差距有多远。
AlwaysOn VS 发布订阅
我们知道,事务日志发布订阅通常不会用于整个数据库的同步,而同步发布库中的部分对象,而AlwaysON却是整个数据库都要同步,从数据量的角度来说,AlwaysON要同步的数据要更多,那为什么其性能还更好呢?
我们从如下两个个方面的对比来寻找答案吧:
1. 同步对象
发布订阅的同步对象是已经写入到磁盘的事务日志,但不是所有的事务日志都发布,只有那些被标记为待发布的日志才会被发布,因此它不仅需要读磁盘,而且对于某个事务,扫描所有日志才能筛选到标记为待发布的日志,如果这个事务的日志非常多而待发布的日志非常少,则日志读取器的效率将非常低;
而AlwaysON同步的对象绝大部分位于内存的日志缓冲中,日志扫描器不需要读取磁盘或者只需读取少量磁盘,且AlwaysON是整库同步,只要是主副本产生的日志都会同步到辅助副本,不需要进行日志筛选,因此不仅读取速度快,而且效率还很高。
备注:AlwaysON同步的日志要比事务日志发布订阅的要多,但从网络角度来看不一定占用网络带宽也会更多,因为在AlwaysON中,网络上传递的是压缩了的日志,而发布订阅则没有做压缩的优化。
2. 同步过程
在发布订阅中,日志无法直接从发布库到订阅库,期间必须通过分发库中转,每个过程都会产生大量的磁盘IO和网络消耗;
而AlwaysON是点到点的数据同步,日志从主副本直接发送到辅助副本,中间不需要中转,传输过程简单高效。
AlwaysOn的可用性模式
上文在介绍AlwaysON同步原理时,我们考虑地比较简单,只考虑了日志的同步情况。
如果要结合事务来整体考虑,AlwaysON的同步——更准确地说是可用模式,应该分为异步提交模式和同步提交模式。
可用性模式是AlwaysON中每个可用性副本的一个属性,它决定了主副本在提交事务之前是否需要等待某个辅助副本将事务日志记录固化到磁盘,如果需要等待,则该AlwaysON的可用模式为“同步提交模式,反之,则是“异步提交模式”。
异步提交模式
使用此可用性模式的可用性副本称为"异步提交副本"。
当辅助副本处于异步提交模式下或者尽管辅助副本在同步提交模式下,但此时主副本在异步提交模式时,主副本无须确认该辅助副本是否已经完成日志固化,就可以提交事务。因此,主数据库事务提交不会受到辅助数据库的影响而产生等待。但是,辅助数据库的更新可能会滞后于主数据库,如果发生故障转移,可能会导致某些数据丢失。因此这种可用模式适合于可用性副本的分布距离较远的情况。
同步提交模式
使用此可用性模式的可用性副本称为"同步提交副本"。同步提交模式要求主副本和辅助副本必须设置成同步提交副本。
在同步提交模式中,主副本必须确认辅助副本已经完成日志固化才可以提交事务(不需要等待辅助副本完成日志重做),这样就保证两边的数据始终是同步的。但是这种保障的代价是主数据库上的事务提交会有滞后时间。可以说,同步提交模式相对于性能而言更强调高可用性。