SQL Server 高可用性(转载)

AlwaysOn

从 SQL Server 2008 开始,微软在“高可用”、“灾难恢复”技术中使用 AlwaysOn 一词。在 SQL Server 2012 中,微软明确地打出的 AlwaysOn 招牌。

SQL Server AlwaysOn 即“全面的高可用性和灾难恢复解决方案”。使用 AlwaysOn,您可以提高应用程序可用性,并且通过简化高可用性 (HA) 部署和管理方面的工作,获得更好的硬件投资回报。

SQL Server AlwaysOn 在以下 2 个级别提供了可用性。

数据库级高可用性

AlwaysOn 可用性组允许将一组数据库同步到最多 4 个只读副本,这是 SQL Server 2012 引入的新特性。SQL Server 2014 将只读副本的数量提升到 8 个。

Windows Server Failover Cluster

特点:

  • 每个节点都安装了本地的 SQL Server,可以不使用共享存储,但是数据库在每个节点上的磁盘文件夹必须是一致的。
  • 主节点可读可写,其它辅助节点可读。
  • 全部节点都加入一个 Windows Fail-over Cluster 中。可以为 AlwaysOn 可用性组配置一个侦听器(虚拟计算机)。客户端如果访问这个侦听器则可以实现 read/write;客户端如果访问指定的辅助节点,可能实现 read/write(如果该节点是主节点),或者只能 read-only。

负载分离: AlwaysOn 可用性组具有一部分的负载平衡能力,即可以将一部分的 read only 请求发送到辅助副本。实现方法有 2 种。

  • 第一种:修改应用程序,在客户端实现。例如,指定将 read/write 都指向 AlwaysOn 可用性组的侦听器(不赞成指向某个节点,因为无法确保某个节点可以 write),将部分 read only 请求指向辅助副本。

  • 第二种:为 AlwaysOn 可用性组配置只读路由。语法示例如下:

ALTER AVAILABILITY GROUP [AG1]
MODIFY REPLICA ON
N'COMPUTER01' WITH
(SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
ALTER AVAILABILITY GROUP [AG1]
MODIFY REPLICA ON
N'COMPUTER01' WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://COMPUTER01.contoso.com:1433'));

上述示例中,首先将某个节点设置为允许副本 READ_ONLY,然后配置辅助角色的只读路由。完成上述配置后,客户端可以在连接字符串中添加只读意向。例如,.Net Framework 4.0 的示例如下:

Server=tcp:MyAgListener,1433;Database=Db1;IntegratedSecurity=SSPI;ApplicationIntent=ReadOnly;MultiSubnetFailover=True

实例级高可用性

AlwaysOn 故障转移群集实例可以在最多 16 个节点(企业版才支持 16 个节点,标准版只支持 2 个节点)间实现故障转移(Fail-over)。下图是一个典型的群集配置:

SQL Server Cluster

特点:数据库必须位于共享存储。这可能是单一故障点。一旦共享存储崩溃了,SQL Server 服务将停止,数据将全部丢失。任何时刻只有主节点提供 SQL Server 服务,其它节点的 SQL Server 服务(实例)处于“冷备”状态。当主节点的 SQL Server 服务发生故障时,才自动转移,然后由另一个备用节点继续提供服务。

区别:让我们首先揭穿这样一个常见误解。故障转移群集是用于获得高可用性的,而非用于实现负载平衡。此外,SQL Server 没有任何内置的、自动负载平衡功能。您必须通过应用程序的物理设计来实现负载平衡。

集群

MSFC (Microsoft Failover Cluster)

在 SQL Server 中谈到群集,首先就会存在一个误区。实际上,SQL Server 群集应当理解为“在 MSFC 中运行的 SQL Server Service”,它依赖于 MSFC。

在 Windows Server 2003 时,Windows 的群集被称为 Microsoft Cluster Service(MSCS)。从 Windows Server 2008 开始被称为 Microsoft Failover Cluster(MSFC)。

在创建 SQL Server 群集之前,必须在 Windows 中实现一个 MSFC,然后再将 SQL Server 安装成为 MSFC 中的一个“服务与应用程序”。

节点

SQL Server 群集实际上是将 SQL Server 实例作为一个服务安装在 MSFC 的每一个节点。MSFC 最多允许 16 个节点。也就是说,可以将一个 SQL Server 实例安装到最多 16 个节点上。

但同一时间只能在其中一个节点(主节点)运行这个 SQL Server 实例(服务)。即使你想在辅助节点上强行启动对应的 SQL Server 实例,MSFC 也会加以阻止。

Fail-over

关于群集的第二个误区,是群集与负载平衡的区别。故障转移群集是用于获得高可用性的,而非用于实现负载平衡。

MSFC 会一直监听 SQL Server 实例(服务),当主节点上的 SQL Server 实例失败(Fail)了,MSFC 会通知下一个节点立即运行 SQL Server 实例,并且 MSFC 将连接到旧节点上的全部请求转移到新的节点,从而保证客户端业务的连续性。这就是 Fail-over(故障转移),也就是说,只有在发生故障时才会转移,而不是负载平衡(Load Balance)。

仲裁

MSFC 中存在一个非常重要的因素,那就是节点配置方式(仲裁)。可以理解为,仲裁需要使用投票机制,得票超过半数的节点才能成为主节点。

Windows Server 2003 时较常用的是 2 个节点加 1 个仲裁磁盘。

Windows Server 2008 则推荐使用节点多数(奇数个节点),当节点数量为偶数时才推荐添加一个仲裁磁盘。也就是说,Windows Server 2008 创建 Microsoft Windows Cluster 时,仲裁磁盘(共享存储)并不是必须的。

侦听器

侦听器在 MSFC 中被称为虚拟网络名称(Virtual Network Name)。

Virtual Network Name

MSFC 的侦听器

MSFC 自身就有一个侦听器,客户端可以直接访问这个侦听器。对这个侦听器的访问被 MSFC 重定向到主节点。

msfc vnn

例如,使用远程桌面直接连接到侦听器。进入远程桌面后,再查看这台计算机的属性,可以发现其实就是主节点这台计算机。

msfc vnn

SQL Server Cluster 的侦听器

要访问 SQL Server 群集,必须访问 SQL Server Cluster 的侦听器。

sql server vnn

如果直接访问主节点的名称,则报错,因为 SQL Server 群集实例并没有绑定到主节点名称,而是只绑定到 MSFC 中的 SQl Server 群集侦听器。

sql server vnn

AlwaysOn 可用性组的侦听器

要访问 AlwaysOn 可用性组,可以使用以下两种方式:

  1. 访问 AlwaysOn 可用性组的侦听器
    连接到侦听器后,客户端可以实现 read/write。而且由于后端的节点是自动 Fail-over,所以客户端不用关心后端发生的节点切换。

alwayson vnn

  1. 直接访问指定的节点
    如果可以连接到指定的节点,客户端可以实现 read-only(前提条件是该节点启用了 read-only 选项。但是客户端在 write 时可能会报错,因为这个节点不一定就是主节点。当这个节点 Fail 后,客户端的连接被断开。

alwayson vnn

共享磁盘

共享磁盘

在群集技术中可能会用到共享磁盘。这类磁盘可以被多个节点同时访问,但任一时间只有主节点对共享磁盘享有使用权。

disk

使用共享磁盘的场景

  1. 仲裁磁盘
    在搭建 MSFC 时,如果是偶数个节点,那么可以添加一个仲裁磁盘,从而使投票时可以形成“多数”。

disk
disk
disk

  1. SQL Server Cluster 的数据磁盘
    SQL Server Cluster 的本质,是将所有的 SQL Server 数据库放在一个所有节点共享的磁盘上,当主节点 Fail 时,下一个节点通过获得共享磁盘的使用权,从而顺利启动 SQL Server 实例(服务)。从客户端来看,似乎数据没有变化(因为数据位于共享磁盘上),服务也没有中断(MSFC 将客户端连接重定向到新的节点)。

disk
disk

而对于 AlwaysOn 可用性组,不需要使用共享磁盘。AlwaysOn 可用性组的每个节点都有自己独立的 SQL Server 实例(服务),实例访问的是本地磁盘(或者是将网络磁盘作为本地独占的磁盘)。

故障转移

SQL Server 的高可用通过故障转移手段使用户端几乎没有察觉的情况下将服务交由下一个节点接管。

SQL Server 故障转移群集

这是一个实例级的故障转移。备用节点需要较长的时间启动 SQL Server 服务,然后读取共享磁盘上的数据,最后才接管旧节点上的客户端请求。因此,实例级的故障转移一般需要较长的时间才可以成功切换到下一个节点(通常需要 60 秒或更长的时间)。甚至有时候切换时间过长而导致超时,从而不能成功实现故障转移。有时候为了实现特定的目的,需要手动将服务从一个节点切换到另一个节点。

failover

弱点:

  • 需要共享磁盘
  • 共享磁盘是单一故障点
  • 故障转移速度慢
  • 辅助节点的资源利用率低

AlwaysOn 可用性组的故障转移

这是一个数据库级的故障转移。在故障转移之前,各节点的 SQL Server 服务已经开启,并且数据已经同步提交(节点之间实时同步)。因此数据库级的故障转移速度非常快(通常在 10 秒内完成)。也可以手动将主副本转移到新的节点。

failover

数据库镜像

数据库镜像是 SQL Server 2005 sp1 正式引入的一项数据库级的高可用性技术。

db mirror

镜像的先决条件

  1. 使用 Windows 域帐户或者证书
  2. SQL Server 标准版/商业智能版(仅支持同步提交),或者企业版/数据中心版本(SQL Server 标准版仅支持同步提交,可能会导致性能问题)。

镜像的实现

镜像是主体服务器、镜像服务器和见证服务器(见证服务器为可选项)之间通过 TCP5022 端口进行实时通信从而实现数据同步或监控。

主体数据库 (principal database)

  • 主体数据库的事务日志记录将应用到镜像数据库
  • 可读写

镜像数据库 (mirror database)

  • 从主体数据库同步过来的数据库副本
  • 不可访问

见证服务器(可选)

  • 仅仲裁功能,不参与数据复制
  • 甚至可以使用 SQL Server Express 版本

db mirror
db mirror

镜像的 3 种运行模式

  1. 高性能(异步)

    • 主体服务器上的更改被异步传送给镜像服务器。
    • 由于是异步执行,因此对性能的影响很小。
  2. 高安全(同步)

    • 主体服务器上的更改被同步传送给镜像服务器,而且只有当这些更改同时主体和镜像服务器上完成之后主体服务器才可以继续下一个更改。
  3. 高可用(同步)

    • 数据的更改模式与高安全模式时相同。
    • 此模式必须存在一台见证服务器,监控主体与镜像服务器的运行状态。如果主体服务器变得不可用,则见证服务器会控制自动故障转移到镜像服务器。

数据库快照

镜像数据库可以创建数据库快照,从而实现只读访问数据库某个时间点的快照

  • 即时创建的, 只读性的,基础数据库继续变化
  • 快照不影响、限制对基础数据库的更新
  • 返回到以前创建的快照可挽救误操作
  • 可实现多数据版本
  • 极其有效的空间管理
  • 采用 “copy on write” 机制
    • 无需复制数据的完整备份
    • 共享无变化的数据库页面
    • 仅存储已变化的数据页

镜像的故障转移

  1. 服务器端

如果有见证服务器,则由见证服务器控制自动故障转移。也可以手动控制。

db mirror

  1. 客户端

由于镜像技术没有采用 MSFC 作为底层,因此客户端直接连接在原来的主体服务器。

可以在客户端的连接字符串中添加镜像服务器的 IP 地址,那么客户端在连接主体服务器失败时会自动尝试连接镜像服务器。关于添加连接字符器的方法,请参考将客户端连接到数据库镜像会话

镜像技术的不足

SQL Server 2012 的联机手册就已经申明将在未来的版本中取消镜像技术。镜像技术主要存在以下不足。

  1. 客户端不能连接到一个虚拟网络名称。
  2. 对于标准版的用户,镜像只能使用高安全(同步)模式,通常都会对性能带来很大的影响。一般在实现镜像之前都需要对数据库做一次性能调整与优化。
  3. 只能针对单个数据库。例如,SharePoint 用户希望同时对一组数据库实现高可用,而镜像只能一个一个地对数据库实现。
  4. 镜像服务器上的数据库一直处于“正在还原”状态,只能通过创建快照才能实现只读访问。

日志传送

日志传送是非常古老的高可用性技术。

日志

事务日志提供了数据库管理系统的活动的执行历史,以保证原子性(Atomicity)和持久性(Durability)

translog

通过重做(re-do)事务日志,使数据可以恢复到另一个数据库

redolog

日志传送的先决条件

SQL Server 的日志传送需要以下条件:

  1. 推荐使用 Windows 域环境
  2. 启用 SQL Server Agent 服务
  3. SQL Server 数据库必须是完整恢复模式(事务日志备份)
  4. 共享网络文件夹

日志传送依赖于传统的 Windows 技术与 SQL Server 代理。

log

日志传送的实现

主服务器实例和辅助服务器实例将它们自己的历史记录和状态发送到监视服务器(monitor server)实例(可选)。 监视服务器跟踪日志传送的所有详细信息,包括:

  • 主数据库中事务日志最近一次备份的时间。
  • 辅助服务器最近一次复制和还原备份文件的时间。
  • 有关任何备份失败警报的信息。

简单地说,日志传送是通过以下 3 个步骤实现的。

log

  1. 为主数据库创建一个事务日志备份计划
  2. 为辅助数据库创建一个文件复制计划
  3. 为辅助数据库创建一个事务日志还原计划

事务日志还原的选项

有 2 个还原选项。

  1. 无恢复模式
    在这种模式时,辅助数据库在做事务日志还原时使用 WITH NORECOVERY 选项(未提交的事务没有被回滚),数据库一直处于“正在还原”状态,不可以访问。

  2. 备用模式
    在这种模式时,辅助数据库在做事务日志还原时使用 WITH STANDBY 选项(将未提交的事务在一个临时文件中回滚)。数据库处于“只读,备用”状态,可以提供只读访问。

log

日志传送的优势

  • 可以广泛地部署。
  • 辅助数据库可以提供只读访问,作为报表等应用程序的数据源。

日志传送的不足

  • 不支持自动的故障转移。
  • 数据同步被拆分成 3 个步骤实现,因此会有较大的延时。

复制

复制是一个开发范畴的技术,但是也可以像日志传送一样作为高可用技术的一个后备选项。

复制类型

  • 快照复制
  • 事务复制
  • 合并复制
  • 异类数据库复制

复制的拓扑

replica

复制的冲突处理

在执行复制时,源数据库与目标数据库都是敞开式的,因此在写入记录时可能发生冲突。为解决冲突,常用的方法有以下两种:

  1. 合并复制
    合并复制允许存在冲突。当冲突发生时,合并复制将比较这些记录的时间戳,仅保留最新的记录(时间戳最后的那条记录)。

  2. 专用的写入区

    • 一种方式是将 read 请求随机发送给任意一个数据库,而将 write 指定只写入发布服务器。
    • 另一种方式是设置专用的写入区,所有写入被事先隔离,从而避免冲突。例如,一个 table 被分割成 3 个 table,分别保存 3 个分公司的数据。

复制在负载均衡中的应用

在一些稍微容忍数据同步存在延迟的场合,复制可以作为负载均衡的手段。这种实现方法,其实质是通过复制实现分布式数据库。

例如:工厂的流水线生产过程中的数据采集,可以根据车间与流水线的分布情况,部署多套 SQL Server,然后通过复制实现数据的分布式存储、查询。

replica

负载平衡

高可用与负载平衡是两种不同的技术,却经常被混淆。

服务的类型

  • 无状态的服务(stateless service)

    • 对单次请求的处理,不依赖其他请求。
    • 处理一次请求所需的全部信息都包含在这个请求里或者可以从外部获取(例如,数据库),服务本身不存储任何信息。
    • IIS(Web 服务)可以设计成无状态的服务,可以实现池化(负载均衡),从而横向扩展。
  • 有状态的服务(stateful service)

    • 会在自身保存一些数据。
    • 先后的请求是有关联的,通常用于实现事务。
    • 数据库服务一般是有状态的服务。

区别

高可用

高可用是针对“有状态”的服务,其目标是为了减少硬件或软件故障造成的影响,保持业务的连续性,从而将用户可以察觉到的停机时间送到最少。

load balance

负载平衡

负载平衡是针对“无状态”的服务,其目标是通过对服务的“池化”(多个服务,形成一个“池”)使客户端的请求被分摊到多个服务。

load balance

联系

高可用技术中兼具一部分的负载分摊功能。例如,AlwaysOn 可用性组的辅助副本可以提供只读访问,从而分摊一部分的只读请求给报表等应用程序。

负载均衡给客户端的感觉就像高可用技术一样,保持了业务的连续性。例如,客户端连接到 IIS 池,池中的某台 IIS 服务器发生故障后,客户端的连接被重定向到池中的其它 IIS 服务器。

数据库产品几乎都没有宣称自己的“产品功能”(feature)中包含有负载均衡、读写分离等技术特性。对于 SQL Server 来说,负载分摊、读写分享应当作为一个解决方案(Solution)来实现。例如,指定一个只读副本专门用来查询,应当从业务需求角度事先进行设计。

SQL Server 负载分离示例

生产环境通常在设计时就要考虑到未来的数据增长,并且预留负载分离的接口。

以下案例显示了一家 OTA 企业在遇到数据库规模迅速增长时,依次实施了三期部署。

第一期:数据库将所有数据都存放在一台服务器。
load balance

第二期:进行了负载分离,将原先的单台服务器根据业务类型进行分离。
load balance

第三期:继续进行分离。
load balance

综述

SQL Server 2012 HA 解决方案

  • 热插拔物理内存(服务器级)
  • 热插拔 CPU(服务器级)
  • 故障转移集群(实例级)
  • 日志传送(数据库级)
  • 数据库镜像(数据库级)
  • AlwaysOn 可用性组(数据库级)
  • 复制(数据库级)

解决方案比较:

解决方案 故障转移集群 日志传送 数据库镜像 AlwaysOn 可用性组
故障转移单元 单个实例 单个数据库 单个数据库 一组数据库
自动故障转移 仅在有见证服务器时
数据复制 无副本 副本数量不受限 1 个副本 最多 4 个副本
可用的副本 只读,备用模式时 通过快照实现只读 只读,备用
部署复杂度 中等 中等 中等
0%