订阅以接收新文章的通知:

Hyperdrive:让数据库拥有全球分布式性能

2023/09/28

12 分钟阅读时间
Hyperdrive: making databases feel like they’re global

Hyperdrive 让 Cloudflare Workers 快速访问您的现有数据库,无论它们位于何处,都能获得优越性能。您只需将 Hyperdrive 连接到您的数据库,更改一行代码以通过 Hyperdrive 连接, 然后就能加快连接和查询速度(剧透一下:今天就可以使用了)。

简而言之,Hyperdrive 利用我们的全球网络加速对您现有数据库的查询,无论它们是在传统的云提供商还是您喜爱的无服务器数据库提供商中;显著减少重复建立新数据库连接所产生的延迟;并缓存对数据库的最常用的读取查询,这往往避免了再次访问数据库的需要。

假设核心数据库——包含用户配置文件、产品库存或运行关键网络应用的数据库——位于某个传统云提供商的 us-east1 区域,如果没有 Hyperdrive,对于巴黎、新加坡和迪拜的用户来说,访问速度将非常慢,而对于洛杉矶或温哥华的用户来说,速度也比应有的慢。每次往返所需的时间长达 200 毫秒,仅建立连接所需的多次往返,可能就要耗时 1 秒(或更多!),而您甚至还没有开始进行查询数据。Hyperdrive 旨在解决这个问题。

为了展示 Hyperdrive 的性能,我们构建了一个 演示应用,该应用对同一个数据库进行连续查询:分别使用 Hyperdrive 和不使用 Hyperdrive (直接)。该应用选择一个位于相邻大陆的数据库:如果您在欧洲,它会选择一个位于美国的数据库——这对许多欧洲互联网用户来说是司空见惯的经历——如果您在非洲,它选择一个位于欧洲的数据库(以此类推)。它返回一个简单的 SELECT 查询的原始结果,没有精心选择的平均值或仔细挑选的指标。

我们构建了一个演示应用,在分别使用和不使用 Hyperdrive 的情况下,对一个 PostgreSQL 数据库发出真实的查询。

在内部测试、初步用户报告和我们的多次基准测试中,相对于直接访问数据库的缓存查询,Hyperdrive 提供了 17-25 倍的性能提升;对于未缓存的查询和写入操作,提供 6-8 倍的性能提升。缓存查询的延迟可能不会让您感到惊讶,但是我们认为,对于未缓存的查询,速度提高了 6-8 倍,使“我无法从 Cloudflare Workers 查询集中式数据库”变成“为什么以前不能这样!?”。我们还在继续努力提升性能:我们已经确定了额外的延迟削减,并将在接下来的几周内推出这些改进。

最妙之处是什么呢?拥有 Workers 付费计划的开发人员可以立即开始使用 Hyperdrive 公开测试版:无需等待,也不用注册。

Hyperdrive?从未听说过?

我们秘密研发 Hyperdrive 已有一段时间:但允许开发人员连接到现有的数据库,并使用原有的数据、查询和工具,这是我们已经思考了相当长时间的一件事。

在像 Workers 这样的现代分布式云环境中,连接传统数据库一直存在速度慢和不可扩展的问题。连接速度慢是因为需要进行多次往返(TCP 握手、TLS 协商、认证)才能建立连接。而不可扩展的问题在于像 PostgreSQL 这样的数据库,每个连接的资源成本较高。即使只有数百个到数据库的连接,也会消耗可观的内存,另外查询也需要额外的内存。

我们在 Neon(一家流行的无服务器 Postgres 提供商)的朋友曾经写过有关这方面的文章,甚至发布了一个 WebSocket 代理和驱动程序来减少连接开销,但依然面临艰巨的挑战:尽管使用了自定义驱动程序,我们的往返次数减少到 4 次,每次依然可能需要 50-200 毫秒甚至更多。对于长时间的连接,这是可以接受的,可能最多每几个小时发生一次。但是,如果仅用于几毫秒到最多几分钟的个别函数调用时,您的代码会花费更多时间等待。这实际上相当于另一种冷启动:在查询之前必须建立与数据库的新连接,意味着在分布式或无服务器环境中使用传统数据库非常缓慢

为了应对这个问题,Hyperdrive 做了两件事。

首先,它在 Cloudflare 的网络中维护一组区域数据库连接池,以便 Cloudflare Worker 避免为每个请求对数据库建立新连接。相反,Worker 可以与 Hyperdrive 建立连接(快速!),由 Hyperdrive 维护一个准备就绪的连接池返回给数据库。由于到数据库的单次往返需时 30 毫秒到(通常)300 毫秒不等(更不用说建立新连接所需的 7 次或更多往返),拥有一个可用连接池显著减少了短时间连接可能遇到的延迟问题。

其次,它能够理解读取(非变异)和写入(变异)查询以及事务之间的区别,并且可以自动缓存您最常用的读取查询:这些查询通常占典型 Web 应用程序中对数据库进行的查询的 80% 以上。每小时有数万用户访问的产品列表页面;主要求职网站上的职位空缺;甚至是对偶尔更改的配置数据的查询;大量被查询的内容并不经常变化,将其缓存到用户查询的位置附近可以显著加快下一批用户访问该数据的速度。无法安全缓存的写入查询仍然可以受益于 Hyperdrive 的连接池 Cloudflare 的全球网络: 能够通过我们的骨干网络在互联网上通过最快的路径传输,同样减少了延迟。

即使您的数据库位于国家的另一边,70 毫秒 x 6 次往返对于用户等待查询响应而言也是相当长的时间。

Hyperdrive 不仅适用于 PostgreSQL 数据库,包括 Neon、Google Cloud SQL、AWS RDS 和 Timescale,也适用于 PostgreSQL 兼容数据库,例如 Materialize (强大的流处理数据库),CockroachDB (主流分布式数据库),Google Cloud 的 AlloyDB,以及 AWS Aurora Postgres。

我们还计划在今年年底前提供对 MySQL 的支持,包括 PlanetScale 等提供商,并计划在未来支持更多数据库引擎。

神奇的连接字符串

Hyperdrive 的主要设计目标之一是开发人员需要继续使用他们现有的驱动程序、查询构建器和 ORM(对象关系映射)库。如果我们要求您迁移到其他 ORM 或重写数百行(或更多)的代码和测试来获得 Hyperdrive 的性能优势,那么 Hyperdrive 有多快就无关紧要了。

为了实现这一目标,我们与流行开源驱动程序的维护者合作,包括 node-postgresPostgres.js ,以帮助它们的库支持 Worker 的新 TCP 套接字 API,后者正在通过标准化过程,而且我们预计它也将在 Node.js、Deno 和 Bun  中得到支持。

平凡无奇的数据库连接字符串是数据库驱动程序的共同语言,通常采用以下格式:

postgres://user:[email protected]:5432/postgres

Hyperdrive 的神奇之处在于您可以在现有的 Workers 应用中使用它来处理现有的查询,只需将连接字符串替换为 Hyperdrive 生成的连接字符串即可。

创建一个 Hyperdrive

对于一个准备就绪的现有数据库, 在这个例子中,我们将使用来自 Neon 的一个 Postgres 数据库,启动 Hyperdrive 需时不到一分钟(没错,我们进行了计时)。

如果您还没有 Cloudflare Workers 项目,可以快速创建一个:

$ npm create cloudflare@latest
# Call the application "hyperdrive-demo"
# Choose "Hello World Worker" as your template

从这里开始,我们只需要数据库的连接字符串和一个快速的 wrangler 命令行调用,让 Hyperdrive 连接到数据库。

# Using wrangler v3.10.0 or above
wrangler hyperdrive create a-faster-database --connection-string="postgres://user:[email protected]:5432/neondb"

# This will return an ID: we'll use this in the next step

将我们的 Hyperdrive 加入到 Worker 的 wrangler.toml 配置文件:

[[hyperdrive]]
name = "HYPERDRIVE"
id = "cdb28782-0dfc-4aca-a445-a2c318fb26fd"

我们现在可以编写一个 Worker — 或使用现有的 Worker 脚本 — 并使用 Hyperdrive 来加速到现有数据库的连接和查询。我们在这里使用 node-postgres,但我们可同样轻松地使用 Drizzle ORM

import { Client } from 'pg';

export interface Env {
	HYPERDRIVE: Hyperdrive;
}

export default {
	async fetch(request: Request, env: Env, ctx: ExecutionContext) {
		console.log(JSON.stringify(env));
		// Create a database client that connects to our database via Hyperdrive
		//
		// Hyperdrive generates a unique connection string you can pass to
		// supported drivers, including node-postgres, Postgres.js, and the many
		// ORMs and query builders that use these drivers.
		const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });

		try {
			// Connect to our database
			await client.connect();

			// A very simple test query
			let result = await client.query({ text: 'SELECT * FROM pg_tables' });

			// Return our result rows as JSON
			return Response.json({ result: result });
		} catch (e) {
			console.log(e);
			return Response.json({ error: JSON.stringify(e) }, { status: 500 });
		}
	},
};

上面的代码故意保持简单,但希望您能看到其中的神奇之处:我们的数据库驱动程序从 Hyperdrive 获取连接字符串,并且对此一无所知。它不需要了解 Hyperdrive 的任何信息,我们也不需要放弃我们喜欢的查询构建器库,当进行查询时,我们可以立即体验到速度的好处。

连接被自动池化和保持可用状态,我们最常用的查询会被缓存,整个应用变得更快。

我们还编写了针对每个主流数据库提供商的指南, 让您轻松获得从这些数据库连接到 Hyperdrive 所需的信息(连接字符串)。

快速肯定不会便宜,对吗?

我们认为,在使用 Cloudflare Workers 构建时,Hyperdrive 对于访问现有数据库至关重要:传统数据库从来都不是为客户端全球分布的世界而设计的。

Hyperdrive 的连接池化将始终是免费的, 无论是我们目前支持的数据库协议还是将来添加的新数据库协议。正如 DDoS 保护和我们的全球 CDN, 我们认为 Hyperdrive 的核心功能太有用了,不应该限制。

在公测期间,无论你如何使用,Hyperdrive 本身不会产生任何使用费用。我们将在正式发布(2024 年初)前公布有关 Hyperdrive 定价的更多详情,并将充分提前通知。

是时候开始查询了

那么,接下来 Hyperdrive 将如何发展?

我们计划在 2024 年初推出 Hyperdrive 的正式版本,并专注于增加对缓存的控制,根据写入操作自动使缓存失效,提供详细的查询和性能分析(即将推出!),支持更多的数据库引擎(包括 MySQL),并继续努力进一步提升速度。

我们还在努力通过 Magic WAN 和 Cloudflare Tunnel 实现专用网络连接,以便您就连接到没有或不能公开暴露在互联网上的数据库。

要将 Hyperdrive 连接到您现有的数据库,请访问我们的开发人员文档 — 只需不到一分钟就可以创建一个 Hyperdrive 并更新现有的代码以使用它。欢迎加入我们的  Developer Discord#hyperdrive-beta 频道, 提出问题、报告错误、并直接与我们的产品和工程团队交流。

我们保护整个企业网络,帮助客户高效构建互联网规模的应用程序,加速任何网站或互联网应用程序抵御 DDoS 攻击,防止黑客入侵,并能协助您实现 Zero Trust 的过程

从任何设备访问 1.1.1.1,以开始使用我们的免费应用程序,帮助您更快、更安全地访问互联网。要进一步了解我们帮助构建更美好互联网的使命,请从这里开始。如果您正在寻找新的职业方向,请查看我们的空缺职位
Birthday Week (CN)Product News (CN)Database (CN)Developer Platform (CN)简体中文

在 X 上关注

Matt Silverlock|@elithrar
Alex Robinson|@alexwritescode
Cloudflare|@cloudflare

相关帖子