如果您在全球范围内部署应用程序,并需要保持数据库读取延迟较低,那么就需要物理上将数据库靠近应用程序所在的地区。借助 PlanetScale 的 Portals 功能,您现在可以创建只读区域,以支持全球分布式应用程序,更好地服务全球用户。

将数据放置在用户和应用程序所在的地方

Portals 允许您从距离应用部署区域最近的地区读取数据。无论您的应用程序部署在北弗吉尼亚、法兰克福、圣保罗或 PlanetScale 的其他地区,Portals 都可以为您的应用程序提供更低的读取延迟!

目前,PlanetScale 中的每个数据库都仅支持在一个区域内进行读写操作。但通过 Portals,您可以添加任意数量的分布式只读区域。

如果没有 PlanetScale,自行设置全球分布的数据库可能会非常麻烦。您可能需要进行容量规划、处理复杂的价格结构,同时还需要担心复制策略或性能问题。相反,借助 PlanetScale 的 Portals,您只需点击几下即可轻松添加和管理额外的只读区域。

Portals 的强大性能示例

为了更直观地展示 Portals 的优势,让我们看看不同地区之间的读取延迟:

对于部署在法兰克福的应用程序,如果直接与位于北弗吉尼亚的数据库通信,每次查询可能会增加额外约 90 毫秒的延迟。然而,如果在法兰克福添加一个只读区域,这个延迟可以减少到每次查询约 3 毫秒。(延迟数据基于 SELECT * FROM books LIMIT 10 查询。)

连接到新的只读区域

您可以通过连接字符串连接到新的只读区域,与连接到其他 PlanetScale 数据库分支或 MySQL 数据库类似。此连接字符串专用于您的只读区域和生产分支。

以下示例展示了在 Ruby on Rails 应用程序中如何同时部署到圣保罗和法兰克福并连接到只读区域的操作流程。

示例代码

注意:
以下示例使用 Ruby on Rails 提供实现方法,但具体使用何种开发框架和应用部署方式将会有所不同。比如,您可以参考 Fly.io 与 PlanetScale 的指南,在将 Fly 的全球应用平台与 PlanetScale 的只读区域结合使用期间实现数据库区域的接近部署。

在 Rails 应用中,您可以设置连接到只读区域。

首先,修改 database.yml 来包括主区域以及只读区域的连接配置:

Yaml1default: &default
2  adapter: trilogy
3  encoding: utf8mb4
4  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
5  username: root
6  password:
7  socket: /tmp/mysql.sock
8
9development:
10  primary:
11    <<: *default
12    database: multi_region_rails_development
13  primary_replica:
14    <<: *default
15    database: multi_region_rails_development
16    replica: true
17
18test:
19  primary:
20    <<: *default
21    database: multi_region_rails_test
22  primary_replica:
23    <<: *default
24    database: multi_region_rails_test
25    replica: true

上述配置允许您向只读区域发送查询,或者利用 Rails 的“自动角色切换”功能为您路由查询。

Ruby1ActiveRecord::Base.connected_to(role: :reading) do
2  books = Book.where(author: "Taylor")
3  # 此代码块内的所有查询都将连接到只读区域
4end

您可以设置生产应用程序以连接到最近的 PlanetScale 区域以进行读取操作,从而实现低延迟的读取效果。

在示例中,我们通过 Rails credentials(凭据)存储连接详情:

Erb1<%
2  # 应用程序具有区域环境变量。
3  # 根据此变量连接到最近的数据库区域。
4  region = ENV["APP_REGION"]
5
6  # 在法兰克福时,使用法兰克福区域。
7  # 在圣保罗时,则使用圣保罗区域。
8  region_replica_mapping = {
9      "fra" => Rails.application.credentials.planetscale_fra,
10      "gra" => Rails.application.credentials.planetscale_gra
11  }
12
13  # 如果没有特定区域,连接到主区域。
14  db_replica_creds = region_replica_mapping[region] || Rails.application.credentials.planetscale
15%>
16
17production:
18  primary:
19    <<: *default
20    username: <%= Rails.application.credentials.planetscale&.fetch(:username) %>
21    password: <%= Rails.application.credentials.planetscale&.fetch(:password) %>
22    database: <%= Rails.application.credentials.planetscale&.fetch(:database) %>
23    host: <%= Rails.application.credentials.planetscale&.fetch(:host) %>
24    ssl_mode: verify_identity
25  primary_replica:
26    <<: *default
27    username: <%= db_replica_creds.fetch(:username) %>
28    password: <%= db_replica_creds.fetch(:password) %>
29    database: <%= db_replica_creds.fetch(:database) %>
30    host: <%= db_replica_creds.fetch(:host) %>
31    ssl_mode: <%= Trilogy::SSL_VERIFY_IDENTITY %>
32    replica: true

一旦完成设置,我们的全球部署应用就可以从全球分布式数据库读取数据。这种方式能显著提升区域内的 GET 请求速度,而所有写入仍然发送到主数据库。

自动角色切换与“读取自己的写入”

我们可以更进一步,通过让所有读取查询自动发送到只读区域而在代码中无需显式指定。同时,可以告诉 Rails 在用户最近写入数据库时从主数据库读取。这种机制可以防止用户因复制延迟而读取到过时数据。

实现这一点需要为模型设置读取/写入角色:

Ruby1# app/models/application_record.rb
2class ApplicationRecord < ActiveRecord::Base
3  primary_abstract_class
4
5  connects_to database: { writing: :primary, reading: :primary_replica }
6end

然后启用自动角色切换,在生产配置中添加以下内容:

Ruby1# config/environments/production.rb
2config.active_record.database_selector = { delay: 2.seconds }
3config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
4config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session

上述配置告诉 Rails 将所有读取操作发送到只读区域,而写入操作发送到主数据库。每次写入操作后,它会设置一个 cookie,强制所有读取在 2 秒内从主数据库进行,从而让用户能够读取自己的最新写入。

(感谢 PlanetScale 的软件工程师 Mike Coutermarsh 帮助撰写此部分 Ruby on Rails 代码。)


价格

任何使用 Scaler Pro 或企业计划的数据库均可创建只读数据库区域。Portals 的定价基于存储成本和行读取量。

存储成本

随着购买的只读区域增加,您的存储成本将线性增加。例如,如果您的生产分支需要 10GB,每增加一个只读区域,存储成本将增加 10GB。Portals 的存储费用按月份比例收费。如果在 15 日添加一个只读区域到 10GB 分支,则您将按比例收费 5GB 的使用费用。

新增的只读区域始终按独立存储计费,与您的默认存储不算入免费额度。

行读取

查询在只读区域上的运行将计入您的月度总可计费用量。为了更方便地跟踪成本,您的账单详情将新增一项,专门列出从任何只读区域读取的行数。



介绍 PlanetScale Portals:只读区域插图

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:https://choupangxia.com/2025/05/23/introducing-planetscale-portals-read-only-regions/