走向无服务器数据库——如何以及为何

大家好! 我的名字是戈洛夫·尼古拉。 此前,我在 Avito 工作并管理数据平台六年,也就是说,我负责所有数据库:分析型(Vertica、ClickHouse)、流式处理和 OLTP(Redis、Tarantool、VoltDB、MongoDB、PostgreSQL)。 在此期间,我处理了大量的数据库 - 非常不同和不寻常,以及它们的使用非标准情况。

我目前在 ManyChat 工作。 本质上,这是一家初创公司——新的、雄心勃勃的、快速成长的。 当我第一次加入公司时,出现了一个经典问题:“一家年轻的初创公司现在应该从 DBMS 和数据库市场中获得什么?”

在这篇文章中,基于我的报告 线上音乐节 RIT++2020,我来回答这个问题。 该报告的视频版本可在以下网址获取: YouTube.

走向无服务器数据库——如何以及为何

2020年常见数据库

现在是 2020 年,我环顾四周,看到了三种类型的数据库。

第一种类型—— 经典OLTP数据库:PostgreSQL、SQL Server、Oracle、MySQL。 它们是很久以前编写的,但仍然具有相关性,因为它们对开发人员社区来说非常熟悉。

第二种—— 从“零”开始。 他们试图通过放弃 SQL、传统结构和 ACID、添加内置分片和其他有吸引力的功能来摆脱经典模式。 例如,这是 Cassandra、MongoDB、Redis 或 Tarantool。 所有这些解决方案都希望为市场提供一些全新的东西并占据自己的利基市场,因为事实证明它们对于某些任务来说非常方便。 我将用总称 NOSQL 来表示这些数据库。

“零”时代已经过去,我们已经习惯了 NOSQL 数据库,从我的角度来看,世界迈出了下一步—— 托管数据库。 这些数据库与经典 OLTP 数据库或新的 NoSQL 数据库具有相同的核心。 但它们不需要 DBA 和 DevOps,并且在云中的托管硬件上运行。 对于开发人员来说,这“只是一个在某个地方工作的基础”,但没有人关心它如何安装在服务器上、谁配置了服务器以及谁更新了它。

此类数据库的示例:

  • AWS RDS 是 PostgreSQL/MySQL 的托管包装器。
  • DynamoDB 是基于文档的数据库的 AWS 类似物,类似于 Redis 和 MongoDB。
  • Amazon Redshift 是一个托管分析数据库。

这些基本上是旧数据库,但在托管环境中提出,不需要使用硬件。

笔记。 这些示例针对的是 AWS 环境,但它们的类似物也存在于 Microsoft Azure、Google Cloud 或 Yandex.Cloud 中。

走向无服务器数据库——如何以及为何

这有什么新鲜事吗? 到了2020年,这些都没有了。

无服务器概念

2020 年市场上真正的新鲜事是无服务器或无服务器解决方案。

我将尝试使用常规服务或后端应用程序的示例来解释这意味着什么。
要部署常规后端应用程序,我们购买或租用服务器,将代码复制到其上,将端点发布到外部并定期支付租金、电费和数据中心服务费用。 这是标准方案。

还有其他办法吗? 借助无服务器服务,您就可以做到。

这种方法的重点是什么:没有服务器,甚至没有在云中租用虚拟实例。 要部署服务,请将代码(函数)复制到存储库并将其发布到端点。 然后我们只需为该函数的每次调用付费,完全忽略执行该函数的硬件。

我将尝试用图片来说明这种方法。
走向无服务器数据库——如何以及为何

经典部署。 我们有一个具有一定负载的服务。 我们提出两个实例:物理服务器或AWS中的实例。 外部请求被发送到这些实例并在那里进行处理。

正如您在图片中看到的,服务器的处理方式并不均衡。 一种是 100% 利用率,有两个请求,一种是仅 50% - 部分闲置。 如果不是三个请求到达,而是 30 个,那么整个系统将无法应对负载并开始变慢。

走向无服务器数据库——如何以及为何

无服务器部署。 在无服务器环境中,此类服务没有实例或服务器。 有一定的热资源池 - 已部署功能代码的小型准备好的 Docker 容器。 系统接收外部请求,对于每个请求,无服务器框架都会生成一个带有代码的小容器:它处理这个特定的请求并杀死该容器。

一个请求 - 提出一个容器,1000 个请求 - 1000 个容器。 而在硬件服务器上的部署已经是云提供商的工作了。 它被无服务器框架完全隐藏。 在这个概念中,我们为每次通话付费。 例如,一天打一个电话 - 我们为一个电话付费,每分钟打一百万个电话 - 我们为一百万个电话付费。 或者下一秒,也会发生这种情况。

发布无服务器函数的概念适用于无状态服务。 如果您需要(状态)全状态服务,那么我们会向该服务添加数据库。 在这种情况下,当涉及到状态时,每个有状态函数只需从数据库中写入和读取。 此外,来自本文开头描述的三种类型中任何一种的数据库。

所有这些数据库的共同限制是什么? 这些是经常使用的云或硬件服务器(或多个服务器)的成本。 无论我们使用经典数据库还是托管数据库,无论我们是否有 DevOps 和管理员,我们仍然需要 24/7 支付硬件、电力和数据中心租金。 如果我们有一个经典的基地,我们就为主人和奴隶付费。 如果是高负载的分片数据库,我们会为 10、20 或 30 台服务器付费,而且会持续付费。

成本结构中永久保留服务器的存在以前被认为是一种不可避免的罪恶。 传统数据库还存在其他困难,例如连接数量限制、扩展限制、地理分布式共识——这些问题可以在某些数据库中以某种方式解决,但不能一次性全部解决,而且效果也不理想。

无服务器数据库 - 理论

2020年问题:数据库也可以无服务器化吗? 每个人都听说过无服务器后端...让我们尝试使数据库无服务器?

这听起来很奇怪,因为数据库是一个有状态服务,不太适合无服务器基础设施。 同时,数据库的状态非常大:千兆字节、太字节,在分析数据库中甚至是拍字节。 在轻量级 Docker 容器中提升它并不容易。

另一方面,几乎所有现代数据库都包含大量逻辑和组件:事务、完整性协调、过程、关系依赖和大量逻辑。 对于相当多的数据库逻辑来说,一个小的状态就足够了。 千兆字节和太字节仅由直接执行查询所涉及的一小部分数据库逻辑直接使用。

因此,这个想法是:如果部分逻辑允许无状态执行,为什么不将基础分为有状态和无状态部分。

用于 OLAP 解决方案的无服务器

让我们通过实际示例来看看将数据库分为有状态部分和无状态部分会是什么样子。

走向无服务器数据库——如何以及为何

例如,我们有一个分析数据库:外部数据(左侧红色圆柱体)、将数据加载到数据库的 ETL 过程以及向数据库发送 SQL 查询的分析人员。 这是一个经典的数据仓库操作方案。

在该方案中,ETL 有条件地执行一次。 然后,您需要不断地为运行数据库并填充 ETL 数据的服务器付费,以便有地方可以向其发送查询。

让我们看一下在 AWS Athena Serverless 中实施的替代方法。 没有永久专用的硬件来存储下载的数据。 而不是这个:

  • 用户向 Athena 提交 SQL 查询。 Athena 优化器分析 SQL 查询并在元数据存储(Metadata)中搜索执行查询所需的特定数据。
  • 优化器根据收集到的数据,从外部源下载必要的数据到临时存储(临时数据库)中。
  • 用户发出的SQL查询在临时存储中执行,并将结果返回给用户。
  • 临时存储被清除,资源被释放。

在这个架构中,我们只需为执行请求的过程付费。 没有要求 - 没有成本。

走向无服务器数据库——如何以及为何

这是一种可行的方法,不仅在 Athena Serverless 中实现,还在 Redshift Spectrum(在 AWS 中)中实现。

Athena 示例表明,无服务器数据库可以处理数十甚至数百 TB 数据的实际查询。 数百 TB 将需要数百台服务器,但我们不必为它们付费 - 我们为请求付费。 与 Vertica 等专业分析数据库相比,每个请求的速度(非常)低,但我们不会为停机时间付费。

这样的数据库适用于罕见的分析即席查询。 例如,当我们自发地决定用大量数据来检验一个假设时。 Athena 非常适合这些情况。 对于常规请求,这样的系统非常昂贵。 在这种情况下,请将数据缓存在一些专门的解决方案中。

用于 OLTP 解决方案的无服务器

前面的示例着眼于 OLAP(分析)任务。 现在让我们看看 OLTP 任务。

让我们想象一下可扩展的 PostgreSQL 或 MySQL。 让我们用最少的资源构建一个常规托管实例 PostgreSQL 或 MySQL。 当实例接收更多负载时,我们将连接额外的副本,我们将向其分配部分读取负载。 如果没有请求或负载,我们将关闭副本。 第一个实例是主实例,其余实例是副本。

这个想法在一个名为 Aurora Serverless AWS 的数据库中实现。 原理很简单:代理队列接受来自外部应用程序的请求。 看到负载增加后,它会从预热的最小实例中分配计算资源 - 尽快建立连接。 禁用实例以相同的方式发生。

Aurora 中有 Aurora 容量单位 (ACU) 的概念。 这是(有条件地)一个实例(服务器)。 每个特定的 ACU 可以是主设备或从设备。 每个容量单元都有自己的 RAM、处理器和最小磁盘。 因此,一个是主副本,其余的是只读副本。

运行的这些 Aurora 容量单元的数量是一个可配置参数。 最小数量可以是 XNUMX 或零(在这种情况下,如果没有请求,数据库将无法工作)。

走向无服务器数据库——如何以及为何

当基础接收到请求时,代理队列会提高 AuroraCapacityUnits,从而增加系统的性能资源。 增加和减少资源的能力使系统能够“处理”资源:自动显示各个 ACU(用新的 ACU 替换它们)并对撤回的资源推出所有当前更新。

Aurora Serverless 基础可以扩展读取负载。 但文档并没有直接说明这一点。 可能感觉他们可以举起多大师。 没有魔法。

该数据库非常适合避免在访问不可预测的系统上花费大量资金。 例如,在创建 MVP 或营销名片网站时,我们通常不期望稳定的负载。 因此,如果无法访问,我们不会为实例付费。 当发生意外负载时,例如会议或广告活动结束后,大量人访问站点,负载急剧增加,Aurora Serverless 会自动承担此负载并快速连接缺失的资源 (ACU)。 然后会议结束,每个人都忘记了原型,服务器(ACU)变黑,成本降到零——方便。

该解决方案不适合稳定的高负载,因为它无法扩展写入负载。 所有这些资源连接和断开都发生在所谓的“扩展点”——事务或临时表不支持数据库的时间点。 例如,一周之内可能不会发生规模点,并且基础在相同的资源上工作,根本无法扩展或收缩。

没有什么魔法——它就是普通的 PostgreSQL。 但添加机器和断开连接的过程是部分自动化的。

无服务器设计

Aurora Serverless 是针对云重写的旧数据库,以利用 Serverless 的一些优势。 现在我将告诉您有关该基础的信息,该基础最初是为云、无服务器方法(无服务器设计)编写的。 它立即被开发出来,并没有假设它会在物理服务器上运行。

这个底座被称为雪花。 它具有三个关键块。

走向无服务器数据库——如何以及为何

第一个是元数据块。 这是一种快速的内存服务,可以解决安全、元数据、事务和查询优化问题(如左图所示)。

第二个块是一组用于计算的虚拟计算集群(图中有一组蓝色圆圈)。

第三块是基于S3的数据存储系统。 S3 是 AWS 中的无量纲对象存储,有点像商业用的无量纲 Dropbox。

让我们看看 Snowflake 是如何工作的(假设冷启动)。 也就是说,有一个数据库,数据已加载到其中,没有正在运行的查询。 因此,如果没有对数据库的请求,那么我们就提出了快速内存元数据服务(第一个块)。 我们有 S3 存储,其中存储表数据,分为所谓的微分区。 为简单起见:如果表包含事务,那么微分区就是事务的天数。 每一天都是一个单独的微分区,一个单独的文件。 并且当数据库以这种模式运行时,您只需为数据占用的空间付费。 而且,每个座位的利用率非常低(特别是考虑到显着的压缩)。 元数据服务也持续工作,但您不需要大量资源来优化查询,并且该服务可以被视为共享软件。

现在我们假设一个用户来到我们的数据库并发送了一条 SQL 查询。 SQL 查询立即发送到元数据服务进行处理。 因此,在收到请求后,该服务会分析该请求、可用数据、用户权限,如果一切顺利,则制定处理该请求的计划。

接下来,服务启动计算集群。 计算集群是执行计算的服务器集群。 也就是说,这是一个可以包含 1 台服务器、2 台服务器、4、8、16、32 台服务器的集群——任意数量。 您发出一个请求,该集群就会立即开始启动。 确实需要几秒钟。

走向无服务器数据库——如何以及为何

接下来,集群启动后,处理请求所需的微分区开始从 S3 复制到集群中。 也就是说,假设要执行 SQL 查询,您需要一个表的两个分区,另一个表的一个分区。 在这种情况下,只有三个必要的分区将被复制到集群,而不是全部表。 这就是为什么,正是因为所有内容都位于一个数据中心内并通过非常快的通道连接,所以整个传输过程发生得非常快:几秒钟,很少是几分钟,除非我们正在谈论一些巨大的请求。 因此,微分区被复制到计算集群,并且完成后,在该计算集群上执行SQL查询。 该请求的结果可以是一行、几行或一张表——它们从外部发送给用户,以便他可以下载它、在他的 BI 工具中显示它或以其他方式使用它。

每个 SQL 查询不仅可以从先前加载的数据中读取聚合,还可以在数据库中加载/生成新数据。 也就是说,它可以是一个查询,例如将新记录插入到另一个表中,这会导致计算集群上出现新分区,而新分区又会自动保存在单个 S3 存储中。

上述场景,从用户到来到集群搭建、加载数据、执行查询、获取结果,按照搭建的虚拟计算集群、虚拟仓库的使用分钟数进行计费。 费率根据 AWS 区域和集群大小而有所不同,但平均为每小时几美元。 由四台机器组成的集群比由两台机器组成的集群昂贵两倍,而由八台机器组成的集群仍然昂贵两倍。 根据请求的复杂程度,可以选择 16 台、32 台机器。 但您只需为集群实际运行时的那几分钟付费,因为当没有请求时,您就可以松开手,等待 5-10 分钟(可配置参数)后,它会自行关闭,释放资源并变得自由。

一个完全现实的场景是,当你发送一个请求时,集群就弹出来,相对来说,一分钟,又算一分钟,然后五分钟就关闭了,最后你要为这个集群的七分钟运行付费,并且不是几个月或几年。

第一个场景描述了在单用户设置中使用 Snowflake。 现在我们假设有很多用户,这样更接近真实的场景。

假设我们有很多分析师和 Tableau 报告,它们不断地用大量简单的分析 SQL 查询轰炸我们的数据库。

此外,假设我们有富有创造力的数据科学家,他们试图利用数据做一些可怕的事情,操作数十 TB 的数据,分析数十亿和数万亿行的数据。

对于上述两种类型的工作负载,Snowflake允许您组建多个不同容量的独立计算集群。 此外,这些计算集群独立工作,但具有共同的一致数据。

对于大量的轻查询,您可以组建 2-3 个小集群,每个集群大约 2 台机器。 除其他外,可以使用自动设置来实现此行为。 所以你说:“雪花,举起一小簇。 如果其上的负载增加到某个参数以上,则提高类似的第二个、第三个参数。 当负载开始减弱时,消除多余的负载。” 这样无论有多少分析师来看报告,每个人都有足够的资源。

与此同时,如果分析师睡着了,没有人看报告,集群可能会完全变黑,你就停止为它们付费。

同时,对于繁重的查询(来自数据科学家),您可以为 32 台机器建立一个非常大的集群。 当您的巨大请求在那里运行时,该集群也将仅按分钟和小时付费。

上述机会使您不仅可以将 2 种工作负载划分为集群,还可以将更多类型的工作负载划分为集群(ETL、监控、报告实现等)。

让我们总结一下雪花。 该基础结合了美好的想法和可行的实施。 在 ManyChat,我们使用 Snowflake 来分析我们拥有的所有数据。 我们没有像示例中那样拥有三个集群,而是有 5 到 9 个不同大小的集群。 我们有传统的16机、2机,还有超小型1机来完成某些任务。 他们成功地分配了负载,让我们节省了很多。

数据库成功扩展了读写负载。 这与同样只承载阅读负载的《极光》相比,是一个巨大的差异,也是一个巨大的突破。 Snowflake 允许您使用这些计算集群扩展您的写入工作负载。 也就是说,正如我提到的,我们在ManyChat中使用了几个集群,小型和超小型集群主要用于ETL,用于加载数据。 而且分析师已经生活在中型集群上,绝对不会受到 ETL 负载的影响,因此他们的工作速度非常快。

因此,该数据库非常适合 OLAP 任务。 但不幸的是,它尚不适用于 OLTP 工作负载。 首先,这个数据库是柱状的,随之而来的就是所有后果。 其次,不幸的是,对于每个请求,如果有必要,您会建立一个计算集群并用数据淹没它,该方法本身对于 OLTP 负载来说还不够快。 对于OLAP任务来说等待几秒是正常的,但是对于OLTP任务来说这是不可接受的;100毫秒更好,或者10毫秒更好。

通过将数据库分为无状态和有状态部分,可以实现无服务器数据库。 您可能已经注意到,在上述所有示例中,相对而言,Stateful 部分是将微分区存储在 S3 中,Stateless 是优化器,处理元数据,处理可能作为独立轻量级无状态服务引发的安全问题。

执行SQL查询也可以被视为轻状态服务,可以在无服务器模式下弹出,就像Snowflake计算集群一样,只下载必要的数据,执行查询并“出去”。

无服务器生产级数据库已经可供使用,并且正在运行。 这些无服务器数据库已经准备好处理 OLAP 任务。 不幸的是,对于 OLTP 任务,它们的使用......存在细微差别,因为存在局限性。 一方面,这是一个缺点。 但从另一方面来说,这也是一个机会。 也许其中一位读者会找到一种方法使 OLTP 数据库完全无服务器,而不受 Aurora 的限制。

我希望你觉得这很有趣。 无服务器是未来:)

来源: habr.com

添加评论