使用 Firestore 构建可伸缩应用

本文档介绍应在何时使用 Firestore 构建大型应用。本文档为管理大型应用的数据库系统的基础架构管理员提供解决方案。搭配使用 Firestore 和 Google Cloud 中的其他产品可简化数据库的预配和维护工作,让您可以专注于开发应用,而非容量规划。

Firestore 功能和限制

Firestore 专为移动应用和 Web 应用而设计,用于存储具有灵活的非关系型架构的分层事务数据。在将 Firestore 作为潜在的数据库解决方案评估时,请确保其配额和限制适合您的用例。Firestore 功能多样且适用于许多情况,但其他 Google Cloud 数据库产品可能更适合某些场景。在决定是使用 Firestore 还是其他解决方案时,请考虑以下因素。

存储

Firestore 可以托管任意数量的数据存储。它以相同的方式处理从千字节到拍字节的数据量,而不会影响性能。

实时更新

Firestore 通过让客户端监听文档并使用查询来获取实时更新,来提供实时更新。您可以提供一个可使用单个文档的当前内容立即创建文档快照的回调。每次文档内容发生更改时,另一个调用将更新文档快照。

离线数据持久化

Firestore 为离线数据持久性提供了对移动和 Web 客户端的完全离线支持。您可以在离线状态下访问和更新数据,然后在恢复在线状态后自动将更改同步到云端。内置离线支持使用本地缓存传送和存储数据,即便遭遇网络延迟或互联网连接问题,您的应用仍能保持快速响应。

事务

Firestore 支持多文档、符合 ACID 的事务。术语 ACID 是原子性、一致性、隔离性和耐用性的简称。

查询

Firestore 在整个数据库中提供高度一致的查询。除了主索引之外,Firestore 还支持二级索引和复合索引,以快速查找您在查询中所请求项的位置。

Firestore 查询在以下方面受到限制:

  • Firestore 是一种非关系型数据库,因此它不支持使用 SQL 语义的关系型架构或查询。特别是,Firestore 不支持联接操作、对多个属性的不平等过滤或对基于子查询结果的数据的过滤。
    • 如果您的应用需要非横向扩缩的 SQL 支持,请使用 Cloud SQL
    • 如果您的应用需要用于横向和全局扩缩的 SQL 支持,请使用 Cloud Spanner
  • Datastore 针对在线事务处理 (OLTP) 进行了优化。

安全

Firestore 会在将数据写入磁盘之前自动加密所有数据。Firestore 通过以下方法提供强大的访问管理和身份验证,具体取决于您使用的客户端库:

自动扩缩

Firestore 会自动纵向扩容,无停机时间。通过这种扩容机制,Firestore 每秒可处理数千个请求和数百万个并发连接。您只需根据存储空间大小和操作次数为实际用量付费。如需了解详情,请参阅 Firestore 价格

Firestore 自动扩缩功能在以下方面受到限制:

  • Firestore 原生模式可以将文档更新操作数量扩展到每秒最多 10000 次写入以及一百万个以上的连接。如果您的应用超出了这些写入速率上限,我们建议您使用 Datastore 模式,该模式每秒最多可处理数百万次写入。如需详细了解这些模式之间的差异,请参阅选择原生模式或 Datastore 模式
  • Firestore 可以大规模地处理操作。但是,为了支持复制和事务等复杂功能,Firestore 会进行一些权衡,这可能会降低预期支持极端负载的应用的性能。
    • 如果您的应用产生了极其繁重的写入操作,请考虑使用 Cloud Bigtable 以牺牲事务和二级索引为代价来获取更强的数据提取能力。
    • 如果您的应用经常向用户显示相同的信息,例如游戏中的玩家排行榜,请考虑使用客户端缓存来避免向服务器发送不必要的请求,以减少负载。

延迟时间

相对于延迟时间而言,通过执行跨地区或跨区域同步写入,Firestore 会优先保证耐用性和可用性。如果您的应用在读取或写入数据时需要一致的低于 10 毫秒的延迟时间,请考虑使用 Memorystore for Redis 等内存数据库。

冗余和可用性

Firestore 根据不同的复制机制提供以下级别的多位置冗余:

  • 如果您的首要任务是实现低写入延迟,则地区复制是您的最佳选择。使用地区复制功能时,数据会在同一地区内复制。为了确保延迟时间最短,您可能希望应用位于同一地区。
  • 如果您的首要任务是确保可用性,则多地区复制是最佳选择。使用多地区复制时,数据在至少两个不同地区的多个区域中复制,这使得数据库可以适应地区中断。多地区复制可提供更高的可用性和冗余,但其写入延迟时间更长。见证节点部署在第三个地区中,用作两个复制地区之间的裁定程序,如图 1 所示。

多地区数据库的复制方案。

图 1.Firestore 中多地区数据库示意图。

客户端库

移动和 Web 客户端可以使用 Android、iOS 或 Web 客户端库直接访问 Firestore。Firestore 可与提供 Crash Reporting用户身份验证消息传送用户事件分析等功能的 Firebase 平台无缝集成。

何时使用 Firestore

Firestore 功能适用于各种用例,其中包括:

  • 用户个人资料:管理用户个人资料,以根据用户过去的活动和偏好自定义用户体验。可以使用 Firestore 的灵活架构来完善用户个人资料的结构。例如,您可以添加新属性来支持应用中的新功能。架构更改不会停机,并且即使用户的数量不断增加,性能也不会降低。
  • 实时商品目录:使用 Firestore 丰富的嵌套对象为各种产品存储大量非同构稀疏数据,而无需过度指定结构。例如,您可以为零售商创建商品清单。
  • 用户会话管理:在事务完成前,Firestore 对 ACID 事务的支持有助于确保用户可以锁定一个或多个文档。例如,您可以为零售交易创建购物车,或者为预订事件创建分段处理表单。
  • 状态突变:使用 Firestore 的 ACID 事务可在大量并发用户中传播突变。例如,您可以为游戏应用中的所有玩家保持一致的状态。
  • 永久性透写缓存:Firestore 的高可用性和耐用性提供了永久性状态,并防止应用崩溃可能导致的数据丢失。Firestore 提供了简单易用的键值对存储等功能。但是,Firestore 没有内置的生存时间 (TTL) 或缓存到期机制。
  • 跨设备数据同步:Firestore 的实时更新可确保所有已连接的设备都始终显示最新的状态。例如,Firestore 为协作的多用户移动应用以及您从多个设备连接的应用提供了一致的状态。
  • IoT 管理和资产跟踪:Firestore 的离线数据永久化功能可让您在设备断开网络连接时也能记录数据点。例如,您可以设置移动设备和车辆的实时 GPS 跟踪。
  • 实时功能:Firestore 的实时更新可让您设置实时分析和消息功能。您可以让可视化图表和图表(例如交互式可视化信息中心)保持最新,并设置实时讨论论坛和聊天室。
  • 分布式计数器:设置分布式计数器以显示文档交互,例如博文的顶数或特定内容的收藏量。

参考架构

本部分提供了用于构建将 Firestore 与其他 Google Cloud 产品相结合的大型 Web 应用的参考架构,包括以下内容:

  • 每日导出
  • 缓存
  • 数据处理
  • 机器学习的训练模型

这些架构不是规范性的。相反,它们会着重介绍 Firestore 在构建可扩缩 Web 应用时可能的广泛用途。您可以重新组织和调整架构,以构建满足您需求的 Web 应用。

游戏

游戏平台支持成千上万的玩家并发访问。游戏的前端服务使用 Firestore 存储数十亿个具有分层世界状态数据的文档。Firestore 中还包含用户数据、团队成员、公会、好友列表和在线状态数据等用户数据。此用例包含其他 Google Cloud 产品,如下所示:

  • Spanner 提供了一个全球一致的数据库,该数据库可以为世界各地的大量玩家保留库存或匹配历史记录。
  • Memorystore for Redis 中部署了地区内存缓存,以加快对常用数据的访问速度。
  • 事件被记录到 Bigtable 中,开发者或支持人员可以访问这些事件进行问题排查。
  • 前端和后端数据库中的数据会定期导入 BigQuery 以运行数据分析流水线。这些流水线有助于发现漏洞或发现那些需要更新的游戏机制,以免其影响游戏社区并推动玩家流失。

图 2 显示了游戏用例的架构:

游戏用例的架构。

图 2.游戏平台架构示例。

物联网

交互式 Web 应用会显示物联网 (IoT) 设备生成的实时遥测信息。设备会定期测量和收集用户的温度和心率,并对数据进行如下处理:

  1. 每条测量结果都会通过 MQTT 和 HTTP 网桥立即提交给 IoT Core
  2. IoT Core 将每个测量结果作为单独的消息发布到 Pub/Sub。
  3. Pub/Sub 消息会触发 Cloud Functions,其会从原始消息中提取相关信息,并将结果保存到 Firestore 进行长期存储。
  4. 托管在 Firebase Hosting 中且由 Angular 提供支持的交互式 Web 界面可直接侦听来自 Firestore 的更新。每个更新都会自动推送到 Web 界面,以便实时显示最新信息。

图 3 显示了以下情况中的遥测信息的数据流水线:

物联网应用用例的架构。

图 3.IoT 应用架构示例。

零售

零售平台通过不同的媒介向首次购买者提供商品推荐。Web 应用会记录在线用户的实时数据点(例如引荐来源网址、地理地区和设备类型),然后将收集的数据写入 Firestore,如下所示:

  1. 每个新记录创建都会触发 Cloud Functions 中的数据流水线,以便将用户数据复制到 BigQuery。
  2. 使用存储在 BigQuery 中的实时用户数据和存储在 Cloud SQL 中的产品元数据对使用 Spark MLlib 实现并部署在 Dataproc 上的推荐引擎进行培训。
  3. 建议引擎为推荐产品提供以下预测:
    • 写入 Firestore 并自动推送到在线用户设备的实时预测。
    • 通过电子邮件服务发送给离线用户的批量预测。

图 4 显示了零售平台场景的数据流:

零售平台用例的架构。

图 4.零售平台架构示例。

实时捕获数据更改

应用接受更改全局状态的实时用户输入。数据洞察中的信息中心可跟踪实时事件,以便更好地了解用户行为和互动情况。当用户操作更新任何状态值时,会发生以下事件:

  1. Firestore 会触发 Cloud Functions 函数,其可将更改写入 BigQuery,包括旧状态值和新状态值。
  2. 数据洞察信息中心会对 BigQuery 中的事件数据运行实时聚合查询。
  3. 这些查询会生成指标,例如汇总到不同存储分区的事件更改比率、每个时间存储分区的唯一事件类型,以及事件提取延迟。

如需查看此架构的详细演示文稿和演示,请参阅 Cloud Next '19 视频使用 Firestore 构建出色的应用

图 5 显示了记录实时数据更改的架构:

数据记录用例的架构。

图 5.简单数据捕获架构的示例。

协作内容修改

一个协作式内容管理系统 (CMS) 允许多个编辑者同时处理同一篇文章。每当编辑者进行更改(例如添加或删除某个字符)时,编辑者的客户端会直接将更改提交到 Firestore。

如果多位编辑者同时提交了更改,则系统会执行以下解决流程:

  1. Firestore 的事务确保仅将第一个收到的更改写入数据库。其他更改会被拒绝。
  2. Firestore 会自动将更新后的内容发送到所有编辑者。
  3. 最初被拒绝的编辑者会在更新后的内容上重新应用自己的更改,然后将更改提交到 Firestore。
  4. 相同的冲突解决过程会重复进行,直到所有客户端的所有更改都被接受并写入数据库。

暂存流水线可让编辑者预览内容,如下所示:

  1. Cloud Scheduler 上托管的 Cron 作业每秒触发一个 Cloud Functions 函数。
  2. 该函数将最新内容从 Firestore 复制到 Cloud SQL 上托管的暂存数据库。
  3. 编辑者在 App Engine 上托管的暂存服务器上预览暂存内容。

内容完成后,编辑者点击 CMS 中的发布按钮。此操作会触发一个 Cloud Functions 函数,其可将最新内容从 Firestore 复制到 Cloud SQL 上托管的生产数据库。然后,读者就能在生产网站上使用新发布的内容。如需查看此架构的真实示例,请参阅《纽约时报》的文章“我们为 Newsroom 的 CMS 打造了协作式修改”

图 6 显示了在协作内容修改用例中修改、暂存和发布内容的流水线:

内容修改用例的架构。

Figure 6. 协作内容修改平台架构示例。

后续步骤