如何将本地 Oracle 数据库同步到 AWS

已发表: 2023-01-11

从第一排观察企业软件发展二十年,过去几年不可否认的趋势是显而易见的——将数据库迁移到云端。

我已经参与了一些迁移项目,目标是将现有的本地数据库引入 Amazon Web Services (AWS) 云数据库。 虽然从 AWS 文档材料中,您将了解这有多么容易,但我在这里告诉您,执行这样的计划并不总是那么容易,并且在某些情况下可能会失败。

数据上云

在这篇文章中,我将介绍以下案例的真实体验:

  • 来源:虽然从理论上讲,您的来源是什么并不重要(您可以对大多数最流行的数据库使用非常相似的方法),Oracle 多年来一直是大公司的首选数据库系统,并且这就是我的重点所在。
  • 目标:没有理由在这方面具体。 您可以在 AWS 中选择任何目标数据库,该方法仍然适用。
  • 模式:您可以进行完全刷新或增量刷新。 批量数据加载(源和目标状态延迟)或(接近)实时数据加载。 两者都将在这里涉及。
  • 频率:您可能需要一次性迁移,然后完全切换到云,或者需要一些过渡期并让双方的数据同时更新,这意味着在内部部署和 AWS 之间建立每日同步。 前者更简单并且更有意义,但后者更经常被请求并且有更多的断点。 我将在这里介绍两者。

问题描述

要求通常很简单:

我们想开始在 AWS 内部开发服务,所以请将我们所有的数据复制到“ABC”数据库中。 快速简单。 我们现在需要使用 AWS 内部的数据。 稍后,我们将找出要更改数据库设计的哪些部分以匹配我们的活动。

在继续之前,有一些事情需要考虑:

  • 不要太快陷入“只复制我们拥有的东西,以后再处理”的想法。 我的意思是,是的,这是你能做的最简单的事情,而且会很快完成,但这有可能造成这样一个基本的架构问题,如果不对大部分新云平台进行认真重构,以后将无法修复. 试想一下,云生态系统与本地生态系统完全不同。 随着时间的推移,将推出几项新服务。 自然地,人们将开始以非常不同的方式使用相同的东西。 以 1:1 的方式在云中复制本地状态几乎不是一个好主意。 这可能是您的特定情况,但请务必仔细检查。
  • 用一些有意义的疑问来质疑需求,例如:
    • 谁将是使用新平台的典型用户? 在内部部署时,它可以是交易业务用户; 在云中,它可以是数据科学家或数据仓库分析师,或者数据的主要用户可能是服务(例如,Databricks、Glue、机器学习模型等)。
    • 即使在过渡到云之后,常规的日常工作是否预计会保留下来? 如果不是,他们将如何改变?
    • 您是否计划随着时间的推移大幅增长数据? 答案很可能是肯定的,因为这通常是迁移到云中的最重要的单一原因。 一个新的数据模型应该为此做好准备。
  • 期望最终用户考虑新数据库将从用户那里收到的一些一般的、预期的查询。 这将定义现有数据模型应更改多少以保持与性能相关。

设置迁移

一旦选择了目标数据库并满意地讨论了数据模型,下一步就是熟悉 AWS Schema Conversion Tool。 这个工具可以服务于几个领域:

  1. 分析并提取源数据模型。 SCT 将读取当前本地数据库中的内容,并将生成一个源数据模型作为开始。
  2. 根据目标数据库建议目标数据模型结构。
  3. 生成目标数据库部署脚本以安装目标数据模型(基于工具从源数据库中发现的内容)。 这将生成部署脚本,执行后,云中的数据库将准备好从本地数据库加载数据。
AWS SCT
参考资料:AWS 文档

现在有一些使用模式转换工具的技巧。

首先,几乎永远不会直接使用输出。 我认为它更像是参考结果,您可以根据您对数据的理解和目的以及数据在云中的使用方式从中进行调整。

其次,早些时候,这些表可能是由期望快速获得有关某些具体数据域实体的简短结果的用户选择的。 但是现在,可能会选择数据用于分析目的。 例如,以前在本地数据库中运行的数据库索引现在将毫无用处,并且绝对不会提高与这种新用途相关的数据库系统的性能。 同样,您可能希望在目标系统上对数据进行不同的分区,就像之前在源系统上一样。

此外,最好考虑在迁移过程中进行一些数据转换,这基本上意味着更改某些表的目标数据模型(以便它们不再是 1:1 副本)。 稍后,需要将转换规则实施到迁移工具中。

配置迁移工具

如果源数据库和目标数据库属于同一类型(例如,Oracle on-premise vs. AWS 中的 Oracle,PostgreSQL vs. Aurora Postgresql 等),那么最好使用具体数据库原生支持的专用迁移工具(例如,数据泵导出和导入、Oracle Goldengate 等)。

然而,在大多数情况下,源数据库和目标数据库不兼容,那么显而易见的选择工具将是 AWS Database Migration Service。

AWS数据管理系统
参考资料:AWS 文档

AWS DMS 基本上允许在表级别配置任务列表,这将定义:

  • 要连接到的确切源数据库和表是什么?
  • 将用于获取目标表数据的语句规范。
  • 转换工具(如果有),定义如何将源数据映射到目标表数据(如果不是 1:1)。
  • 将数据加载到的确切目标数据库和表是什么?

DMS 任务配置以一些用户友好的格式(如 JSON)完成。

现在在最简单的场景中,您需要做的就是在目标数据库上运行部署脚本并启动 DMS 任务。 但这远不止于此。

一次性全量数据迁移

全数据迁移-1

最容易执行的情况是请求将整个数据库一次移动到目标云数据库中。 然后基本上,所有需要做的将如下所示:

  1. 为每个源表定义 DMS 任务。
  2. 确保正确指定 DMS 作业的配置。 这意味着设置合理的并行性、缓存变量、DMS 服务器配置、DMS 集群大小等。这通常是最耗时的阶段,因为它需要对最佳配置状态进行大量测试和微调。
  3. 确保在目标数据库中以预期的表结构创建(空)每个目标表。
  4. 安排执行数据迁移的时间窗口。 显然,在此之前,请确保(通过性能测试)时间窗口足以让迁移完成。 在迁移过程中,从性能的角度来看,源数据库可能会受到限制。 此外,预计在迁移运行期间源数据库不会更改。 否则,一旦迁移完成,迁移的数据可能与存储在源数据库中的数据不同。

如果 DMS​​ 的配置做得好,在这种情况下不会发生任何坏事。 每个源表都将被拾取并复制到 AWS 目标数据库中。 唯一需要关注的是活动的性能,并确保每一步的大小调整都正确,以免由于存储空间不足而失败。

增量每日同步

增量每日同步

这是事情开始变得复杂的地方。 我的意思是,如果世界是理想的,那么它可能一直都运转良好。 但世界从来都不是理想的。

DMS 可以配置为以两种模式运行:

  • 满载——上面描述和使用的默认模式。 DMS 任务在您启动它们时或在它们计划启动时启动。 一旦完成,DMS 任务就完成了。
  • 更改数据捕获 (CDC) – 在此模式下,DMS 任务连续运行。 DMS 扫描源数据库以查找表级别的更改。 如果发生更改,它会立即尝试根据与更改表相关的 DMS 任务中的配置将更改复制到目标数据库中。

在选择 CDC 时,您需要做出另一个选择——即 CDC 如何从源数据库中提取增量更改。

#1。 Oracle 重做日志读取器

一种选择是从 Oracle 选择本机数据库重做日志读取器,CDC 可以利用它来获取更改的数据,并根据最新的更改,在目标数据库上复制相同的更改。

如果将 Oracle 作为源处理,这看起来是一个显而易见的选择,但有一个问题:Oracle 重做日志读取器利用源 Oracle 集群,因此直接影响数据库中运行的所有其他活动(它实际上直接在数据库)。

您配置的 DMS 任务越多(或并行的 DMS 集群越多),您可能需要越多地扩大 Oracle 集群——基本上,调整主 Oracle 数据库集群的垂直扩展。 这肯定会影响解决方案的总成本,如果每日同步将在项目中长期存在,则更是如此。

#2。 AWS DMS 日志挖掘器

与上面的选项不同,这是针对同一问题的原生 AWS 解决方案。 在这种情况下,DMS 不会影响源 Oracle 数据库。 相反,它将 Oracle 重做日志复制到 DMS 集群并在那里进行所有处理。 虽然它节省了 Oracle 资源,但它是较慢的解决方案,因为涉及更多操作。 而且,正如人们可以很容易地假设的那样,Oracle 重做日志的自定义读取器作为 Oracle 的本地读取器在其工作中可能更慢。

根据源数据库的大小和每日更改的数量,在最好的情况下,您可能最终将数据从本地 Oracle 数据库几乎实时地增量同步到 AWS 云数据库中。

在任何其他情况下,它仍然不会接近实时同步,但您可以尝试通过调整源和目标集群性能配置和并行性或试验来尽可能接近可接受的延迟(源和目标之间) DMS 任务的数量及其在 CDC 实例之间的分布。

您可能想了解 CDC 支持哪些源表更改(例如添加列),因为并非所有可能的更改都受支持。 在某些情况下,唯一的方法是手动更改目标表并从头开始重新启动 CDC 任务(在此过程中丢失目标数据库中的所有现有数据)。

当事情出错时,无论如何

数据库同步失败

我通过艰难的方式学到了这一点,但是有一个与 DMS 相关的特定场景很难实现每日复制的承诺。

DMS 只能以某种定义的速度处理重做日志。 是否有更多 DMS 实例执行您的任务并不重要。 尽管如此,每个 DMS 实例仅以单一定义的速度读取重做日志,并且每个实例都必须完整读取它们。 使用 Oracle 重做日志或 AWS 日志挖掘器甚至都没有关系。 两者都有这个限制。

如果源数据库在一天内包含大量更改,而 Oracle 重做日志每天都变得非常大(例如 500GB+ 大),CDC 将无法正常工作。 复制不会在当天结束前完成。 它会将一些未处理的工作带到第二天,而要复制的一组新更改已经在等待。 未处理的数据量只会一天比一天增长。

在这种特殊情况下,CDC 不是一个选项(在我们执行了许多性能测试和尝试之后)。 如何确保至少从当天开始的所有增量更改都将在同一天复制的唯一方法是像这样处理它:

  • 分离不经常使用的非常大的表,每周只复制一次(例如,在周末)。
  • 将不太大但仍然很大的表的复制配置为在多个 DMS 任务之间拆分; 一张表最终由 10 个或更多独立的 DMS 任务并行迁移,确保 DMS 任务之间的数据拆分是不同的(此处涉及自定义编码)并每天执行。
  • 添加更多(在本例中最多 4 个)DMS 实例,并在它们之间平均分配 DMS 任务,这意味着不仅按表的数量而且按大小分配。

基本上,我们使用 DMS 的全负载模式来复制每日数据,因为这是实现至少当天数据复制完成的唯一方法。

这不是一个完美的解决方案,但它仍然存在,即使在多年之后,仍然以同样的方式工作。 所以,也许毕竟不是那么糟糕的解决方案。