GTLC全球技术领导力峰会·上海站,首批讲师正式上线! 了解详情
写点什么

微软云数据库 Azure SQL DB Hyperscale 如何实现超大规模存储和高可用?

2019 年 1 月 07 日

微软云数据库 Azure SQL DB Hyperscale如何实现超大规模存储和高可用?

Azure SQL DB Hyperscale 是微软推出的一款 Amazon Aurora 竞品。Aurora 采用了开源版本 MySQL 和 PostgreSQL 的前端,并将它们连接到强大的后端云存储引擎,而 Hyperscale 采用了 SQL Server 的前端(查询优化器和查询处理器),并将它们连接到新的后端。


SQL DB Hyperscale 是一种基于 SQL 的高度可扩展的服务层,适用于单个数据库,可根据工作负载需求进行调整。 借助 SQL DB Hyperscale,数据库可以快速自动扩展至 100TB,无需预先配置存储资源,并显著扩大应用程序增长的潜力,而不受存储大小的限制。


当数据库服务器在物理硬件上运行时,看起来像这样:



  • CPU:用于运行数据库引擎代码的 Intel 或 AMD 处理器;

  • 内存:缓存层;

  • 数据文件:本地存储中的文件,其中包含了数据库数据,是数据库主要的事实来源;

  • 日志文件:本地存储中的文件,其中记录了数据库对数据文件所做的操作。当数据库服务器意外崩溃,数据文件处于不一致状态时,日志文件会非常有用;

  • RAID:在驱动器阵列上存储数据的处理器。


传统数据库服务器高可用性

通常,如果你让 DBA 画出数据库故障转移架构图,他们画出来的会是这张图的多个副本,它们跨越了多台独立的服务器。数据库服务器(SQL Server、Postgres、MySQL、Oracle 等)通过将记录命令复制到其他副本来保持数据同步:



一种不太常见的做法(在技术上是可行的)是将数据库服务器与文件存储分离开。你可以将数据库放在文件服务器上,然后通过 UNC 路径来访问它们。



如果数据库服务器满载,可以启动另一个数据库服务器,将数据和日志文件附加到新服务器上,然后继续提供服务。这是一种不太常见的做法,它存在一些问题,比如网络问题、启动另一个数据库服务器太慢,等等。


但如果你在云端这么做会怎样?


从概念上将存储分开

RAID 的职责是:


  • 接收数据写入,并将它们临时存储在数量有限的快速缓存中(接近内存的速度,但在发生崩溃或断电时是安全的);

  • 稍后,将这些写入分发给持久存储(硬盘或固态硬盘);

  • 在读取数据时,找出哪些驱动器保存了需要读取的数据;

  • 尝试在快速存储中缓存数据(它发现了数据的访问模式);

  • 监控底层持久存储的运行状况,当驱动器发生故障时,自动将热备驱动器置于运行状态。


在这个新设计中,我们将构建一个更强大的存储子系统。我们将用另一种更强大的设计来替换 RAID,而在这个新设计中,我们将为存储分配比之前更多的职责:


  • 将数据分解为几个网络服务(这可能比本地闪存存储慢一点,但比共享存储要快);

  • 跨多个数据中心复制数据库(不涉及数据库服务器);

  • 存储引擎负责将事务日志变更应用在数据文件上。


以下是新的架构图:



  • CPU:运行数据库引擎代码的虚拟机(Intel 或 AMD 处理器);

  • 内存:本地固态缓存层;

  • 数据文件:本地存储服务中的文件,其中包含了数据库数据,是数据库主要的事实来源;

  • 日志文件:本地存储服务中的文件,其中记录了数据库对数据文件所做的操作。当数据库服务器意外崩溃,数据文件处于不一致状态时,日志文件会非常有用;

  • RAID:在驱动器阵列上存储数据的处理器服务


当你进行数据插入时:


  • 数据库引擎的查询处理器告诉日志服务:“我想在数据文件 1 的第 300 页添加一行”。

  • 在将命令写入日志服务后,插入完成。

  • 日志服务读取要完成的任务清单,打开数据文件 1,定位到第 300 页,添加相关行。


这样做的优势在于:


  • 主副本具有较少的存储吞吐量,因为它不需要将变更写入数据文件。

  • 日志服务可以对多个数据文件副本做出必要的数据文件变更,即使是在多个数据中心中,甚至是跨多个大洲。

  • 你可以添加更多的数据库和数据库副本,而无需额外开销。如果你曾经处理过可用工作线程耗尽或者由于副本超载而导致同步提交延迟问题,你就会知道这有多酷。

  • 我们可以使用廉价的本地固态存储器来线性扩展数据文件存储。


Azure SQL DB Hyperscale 是这么做的


在传统的 SQL Server 中,如果数据库很大,你可以创建多个数据文件,并将每个数据文件放在单独的卷中。


在 Hyperscale 中,微软通过一种更优雅的方式自动做到这一点:你看到的数据文件实际上是页面服务器。当上一个页面服务器达到约 80%时,会自动为你添加另一个页面服务器,这个服务器在数据库中显示为新的数据文件。


Aurora 和 Hyperscale 所面临的挑战(我不想将它们视为缺点,因为它们是可以被修复的):


  • 现在,如果我们在 IO 子系统经过完美调优的物理服务器上运行数据库,写入延迟可能会在亚毫秒级。但说实话,这样的条件太奢侈了。对于 Azure SQL DB Hyperscale,微软的目标是将日志写入延迟控制在 2.5 毫秒以下,随着他们推出 Azure Ultra SSD,延迟降到 0.5 毫秒以下。

  • 我们将无法使用一些依赖于直接操作数据文件的数据库引擎功能——例如,现在 Hyperscale 不提供透明数据加密或批量日志恢复模型。

  • 缓存变得有点奇怪。主副本仍然需要自己修改内存缓存的数据页,因为有时候人们在插入一行数据后又立即查询刚刚插入的数据,不需要等待日志服务对数据页做出修改,然后主副本从缓存中获取数据页的新副本。

  • 更多的复杂性。这种范式包含了很多新的移动部件,如果要提高可靠性,至少需要成对地运行它们。所有这些移动部件都需要进行控制、诊断和打补订。

  • 在短期内需要花更多的钱。我打赌你们当中的一些人一定会说:“这个许可真是绝了,这个比包含 2 个节点的 Availability Group(在 1,000 美元的英特尔 PCIe 上运行 SQL Server 标准版)还要贵,而且还慢”。你说的没错。这也是为什么微软称之为“Hyperscale”。


AWS Aurora 和 Azure SQL DB Hyperscale 在这方面采用了相同的方法,将删除/更新/插入操作委托给日志服务,让日志服务直接修改数据文件。


下一阶段:扩展计算

之前说过,日志服务可以添加更多的数据库和数据库副本,而无需额外开销。既然如此,为什么不利用这个优势呢?


在 Azure SQL DB Hyperscale 中,这是借助 Always On Availability Group 监听器来实现的。当应用程序要查询一个可读副本时,应用程序在连接期间指定 ApplicationIntent = ReadOnly,并被自动重定向到其中的一个可读副本。


同样,在 AWS Aurora 中,应用程序连接到一个用于只读连接的 DNS 名称。AWS 有一个有趣的特性:对于某些类型的查询,Aurora 将跨多个可读副本进行并行化查询。DBA 很喜欢这个特性,但如果你的查询总是需要涉及多个副本,那么你的脚下可能踩着一颗定时炸弹:你将无法进行大量的并行查询,并且 AWS 会对你执行的每个 IO 收取费用。这是在往糟糕的查询上砸钱——但有时候这样做也无可厚非。


缓存当然变得有点奇怪了。使用传统的 SQL Server Availability Group,数据库引擎可以接收到每一个日志变更,因此它知道需要修改哪些页,而且即使缓存提供的是过时的数据也没关系。现在,数据页由日志服务负责修改,那么就存在副本会提供过时数据的风险。在我看来,我并不太担心这一点,因为 Availability Group 也可能发生类似的问题。异步复制可能会发生延迟(甚至暂停),并且副本可能会在应用变更时落后。


这种设计具有巨大的优势:副本之间不需要发生交互,也不需要在物理位置上靠近彼此。它们只是从数据文件和日志文件中读取数据,不需要知道任何有关刷新数据和日志文件的信息。


谁应该考虑使用 Hyperscale 和 Aurora?

如果你符合以下这些条件,那么你应该考虑使用 AWS Aurora 或 Azure SQL DB Hyperscale:


  • 你有一个应用程序使用了 MySQL、Postgres 或 SQL Server 后端;

  • 只读查询的工作负载足够高,需要将负载分散到多个服务器上(要么让只读查询更快,要么释放主服务器的复杂,让写入更快);

  • 只读查询允许几秒钟的数据延迟;

  • 你无法很快或经济地实现缓存;

  • 你的主要瓶颈不在于写入事务日志(或者如果是,你的日志写入需要 2 毫秒以上);

  • 你愿意依赖供应商的支持。


如果你想了解更多关于这些内容的信息,请访问以下资源:



英文原文:https://www.brentozar.com/archive/2019/01/how-azure-sql-db-hyperscale-works/


2019 年 1 月 07 日 16:246141
用户头像

发布了 731 篇内容, 共 368.9 次阅读, 收获喜欢 1861 次。

关注

评论

发布
暂无评论
发现更多内容

RocketMQ中的事务消息

废材姑娘

RocketMQ

【Mysql-InnoDB 系列】锁定读

程序员架构进阶

MySQL innodb 锁机制 28天写作

不要用+""代替强转

BerryMew

Spring 源码学习 14:initApplicationEventMulticaster、onRefresh 和 registerListeners

程序员小航

spring 源码 源码阅读

京东搜索排序在线学习的 Flink 优化实践

Apache Flink

flink

玩一玩Linux常见命令第二篇

程序员的时光

程序员 28天写作

工信部:推动区块链等与工业互联网的融合技术研究

CECBC区块链专委会

大数据

Kubernetes介绍篇:是什么?为什么要用?

xcbeyond

Docker Kubernetes 容器 28天写作 Kubernetes从入门到精通

HBase 底层原理详解(深度好文,建议收藏)

五分钟学大数据

大数据 HBase

枪手博弈 - 在强者的世界,弱者的生存法则

石云升

博弈论 28天写作 枪手博弈

区块链未来三年内将广泛落地

CECBC区块链专委会

区块链

创业失败启示录|校园微生活(故事篇3)

青城

28天写作 创业失败启示录 青城

DevSecOps:好处和挑战

啸天

敏捷开发 运维自动化 DevSecOps 应用安全

精选算法面试-数组(二分查找)

李孟

面试 算法 数组 28天写作

【TF2系列笔记】Day01:在VSCode中创建开发环境

Tango

七日更 TF2

【计算机内功修炼】五:从小白到高手,你需要理解同步与异步

码农的荒岛求生

异步 同步 回调函数

《适用于初学者的Python》

计算机与AI

“直男”审美?不存在的!来看看 “攻城狮”对一款IoT App的UI改造吧!

IoT云工坊

android App 物联网 IoT sdk

全网独家首发!—份破解大厂面试官千层套路的算法+数据结构笔记!真是太TM重要了

比伯

Java 架构 面试 程序人生 算法

醒醒!Python已经支持中文变量名啦!

Python猫

Python

快的不止一点点!阿里强推的“Redis速成手册”也太香了吧

互联网架构师小马

Java 数据库 nosql redis 缓存

LeetCode题解:105. 从前序与中序遍历序列构造二叉树,递归+数组切割,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

Spring Boot 中的MVC支持

武哥聊编程

Java mvc springboot SpringBoot 2 28天写作

三分钟快速掌握 maven插件

田维常

maven

智慧building之一 智能家居

张老蔫

28天写作

Docker真的被Kubernetes放弃了吗?

蔡超

Docker Kubernetes 云原生

28 天带你玩转 Kubernetes-- 第六天(玩转 Docker命令)

Java全栈封神

Docker k8s 28天写作 docker命令

城市生态的机器人革命

脑极体

[4/28]保障产品高质量交付业务价值

俊毅

【小菜学网络】MAC地址详解

fasionchan

网络编程 网络协议 TCP/IP

区块链:行业应用即将“引爆”

CECBC区块链专委会

区块链

DNSPod与开源应用专场

DNSPod与开源应用专场

微软云数据库 Azure SQL DB Hyperscale如何实现超大规模存储和高可用?-InfoQ