SQLServer AlwaysOn在阿里云的前世此生

缘起

早在2015年的时候,随着阿里云业务日新月异的发展,SQLServer业务也积累了大批忠实客户,其中一些体量较大的客户在相似大促的业务高峰时RDS的单机规格(规格是按照 内存CPUIOPS 必定比例分配,根据底层资源不一样都会有各自上限)已经不能知足用户的业务需求,在咱们看来也须要作Scale Out了,但SQLServer并无完备的中间件产品,因此不管是逻辑Sharding仍是只读分离,都须要用户配合作应用改造,而从用户角度看Sharding改动量很大不是一时间能完成的,那么更多寄但愿咱们提供读写分离的方案来知足业务需求。html

那么读写分离咱们第一个想到的便是AlwaysOn技术,但因为当时AlwaysOn对域控和Windows群集都是强依赖,而这二者又对咱们所依赖的基础设施有很大挑战,须要作不少的突破产品限制的非标准化操做才有可能实现而且还有安全风险,因此最后咱们只能放弃AlwaysOn技术方案,从新设计方案帮助用户度过难关。sql

最后,面对这类客户需求咱们的方案如何产品化是值得咱们思考的。数据库

产品快速发展

除了读写分离,产品上还有不少更重要的问题急需咱们去解决,因此从2015年到2017年咱们经历了一个飞速发展阶段,围绕产品稳定性、多样性以及用户体验作了很是多的事情,举几个点:安全

在这当中依旧不断有读写分离的用户需求,每次遇到咱们都先引导到了IaaS层用ECS自建实现,由于PaaS化的时机并不成熟,具体缘由跟SQLServer当前的技术栈和云产品的结合有着密切的关系,这里也能够把咱们背后的一些思考分享出来。网络

读写分离

首先明确咱们讨论的读写分离是什么,MySQL的读写分离大部分是利用中间层作路由解析,基本上能够实现对应用端透明只有少部分场景须要用户作适配。架构

SQLServer并无成熟的中间件产品,本质上讲是TDS(Tabular Data Stream)不彻底开放的缘由,若是要作也是有办法的,只是投入的成本远大于收益;基于此,SQLServer不管利用当前何种技术实现读写分离,对应用来说都须要作一些适配,即便是使用AlwaysOn技术在连接驱动的参数配置上也会不一样,因此咱们后面讨论的读写分离都是基于这个前提。运维

技术选型

咱们对比了SQLServer全部相关的技术栈异步

其中数据安全、HA(High Availability 高可用)、DR(Disaster Recovery 灾难恢复)以及备库是否可读是咱们最关注的;这里的HA是指原生技术自己是否支持自动HA,当结合了部分云产品后咱们也有能力把不支持变为支持,数据安全和灾难恢复的时间基本是原生技术决定的,备库是否可读是对单一技术的说明但作一些技术组合是能够把不可读变为可读的(好比Database Mirroring+Database Snapshots),最终综合来看Transactional Replication和AlwaysOn是咱们以为有机会作读写分离产品化的技术。分布式

接着咱们单独来看这两种技术对比工具

原理上讲Replication是逻辑复制,对比AlwaysOn的物理复制在性能、延迟、可靠性上都会有必定的差距;而且在产品复杂度读、可控性上和易用性上,因为Replication过于灵活细到表、列级别很难控制,不管用户使用仍是咱们作产品化整个复杂度很是高;因此最终咱们选用AlwaysOn。

AlwaysOn技术

AlwaysOn是原生支持High Availability和Disaster Recovery的技术,自己又分为Failover Cluster Instances(后续简称FCI)和Availability Groups(后续简称AG),下面的图是FCI和AG的基础架构

其中FCI和常规版本的AG都依赖Windows Server Failover Clustering(后续简称WSFC),不一样点是FCI是Share Storage而AG是Share Nothing,FCI是实例级别同步而AG是DB级别,那么很容易想到Share Nothing会有同步和异步的区别(和镜像技术相似),其中二者的区别点须要咱们知道AlwaysOn的基本同步过程

首先在Primary节点的日志(Commit/Log Block Write)会从Log Cache刷到磁盘,同时Primary节点的Log Capture也会把日志发送到其它全部Replica节点,对应节点的Log Receive线程把收到的日志一样从Log Cache刷到磁盘,最后会由Redo Thread应用这些日志刷到数据文件里。

这其中还有一步,就是在Secondary端刷日志的时候,若是Primary节点等待此次返回的Acknowlege Commit,那么就是同步模式,反之若是Primary端不等Secondary的返回那么就是异步模式,二者的区别由此展开。

这是基本的同步过程,但不管是AlwaysOn仍是Database Mirroring都存在一种状况,即同步模式下若是Secondary端异常,Primary端没有收到他的心跳也没有收到此次的Acknowlege Commit,那么也并不会算做写入失败,由于它一旦认定Secondary异常就不会等此次ACK,而是退化为相似异步的模式,但会把Secondary端的异常状态记录在基表里,经过相关视图(sys.dm_hadr_database_replica_states、sys.database_mirroring)暴露出来,就是咱们常见的NOT SYNCHRONIZING/Disconnect状态,这时候自动化运维系统或者DBA就须要作判断处理,等到Secondary修复从新联机后会向Primary报告End of Log (EOL) LSN,Primary端再向它发送EOL LSN 以后hardened的全部日志,一旦Secondary端开始接收到这些日志并逐步刷到日志文件中,那么整个AG或者Mirroring相关的视图又会标记其状态为Synchronizing,代表正在追赶直到Last Hardened (LH) LSN达到主备一致状态,这时从新回到同步模式。

之前的状况一直是这样,直到SQLServer 2017 CU 1引入了REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT这个参数,参数名字很长但也基本包含了他的做用,应对刚才的场景是可让Primary端一直等到Secondary节点从新联机并同步后在提供服务。

了解了AG同步、异步以及FCI,在总结下咱们关心的点

在实际方案中这些也能够结合起来,最终再和阿里云产品整合作一个总体方案,以前也讲到阿里云从15年就开始作相似方案来解决用户问题,一直到最终PaaS化也过分了三个版本。

云上演进

初版本咱们使用了ECS、SSD云盘、OSS、VPC、SLB做为基础;在SQL技术上,咱们使用SQL+WSFC+AD的方式,目前看这种方式支持的版本也很是多,从12到17均可以;验证方式既能够用域控也能够用证书。

但他有2个缺点:第一是成本高,除了Primary和两个Secondary节点还要有两个AD节点,毕竟咱们每一个环节都要保证高可用;
第二点是稳定性不够,网络抖动的状况很是容易让WSFC判断异常,SQL端DB同时出现不可用;

这是第二版的架构,跟初版相比咱们用到了HAVIP来解决监听器问题,去掉了AD只能用证书作验证,但也所以最小资源开销下降到3;这个方案也是以前在阿里云上用的比较多的,但同第一个方案同样,在网络稳定性上会有不少挑战,由于咱们将来面对的场景不仅是同城跨可用区还会有更多跨Region以及打通海外的场景,因此这个方案也只能Cover一部分用户的需求,但对咱们不是一个最终方案。

最终咱们找到了方案三,去除了WSFC和AD,只关注基础云产品和SQL自己;最终要的是跟方案二相比,对网络的抖动敏感度会更低也更可控,最可能是在Primary端出现Send Queue的堆积,这个咱们彻底能够经过SQLServer相关的Performance Counter监控并作一些修复调整。

但没有方案是完美的,可控性强的代价是这种无群集无域控架构原生是不具有HADR能力的,这点熟悉WSFC的同窗能够知道以前架构的HA都是依赖WSFC,他包括健康检查、资源管理、分布式元数据通知维护以及故障转移,因此这时候就必须咱们本身去解决这个问题;为此咱们也作了不少努力,最终实现了支持AlwaysOn无域控无群集的HA系统,不依赖Cluster彻底自主可控的HA。

产品化

最终的产品架构以下,首先会保证有2个同步节点作主备,而且尽可能分配在不一样的可用区,其它只读节点默认是异步,最多能够有7个只读节点;用户的访问链路能够有三种:

  • 第一种是读写链路,会指向两个同步节点,由咱们的HA来保证高可用
  • 第二种是统一只读链路,根据用户需求设定,把指定的Replica节点绑定到一块儿按照必定的权重比例分配连接
  • 第三种是单一只读链路,即每一个只读节点会提供一个单独的连接,让用户也能够本身灵活配置,好比用户的APP Server就是在可用区A那么就能够直接访问可用区A的只读地址,避免再经过统一只读被路由到其它区域

至此SQLServer AlwaysOn已经在阿里云PaaS化,固然目前只是支持最主要功能,后续还有不少能够完善丰富的地方,但愿有更多用户了解和使用这个产品并帮他们解决实际问题。

原文连接

相关文章
相关标签/搜索