如何将您的本地Oracle数据库与AWS同步

观察了20年的企业软件开发,最近几年的不可否认的趋势很明显 – 将数据库迁移到云中。

我已经参与了几个迁移项目,在这些项目中,目标是将现有的本地数据库迁移到亚马逊云数据库(AWS)。尽管从AWS的文档资料中,你会了解到这有多么容易,但我在这里要告诉你,执行这样一个计划并不总是顺利的,也有可能失败。

在本文中,我将介绍以下实际案例的经验:

  • 源数据库:理论上讲,你的源数据库并不重要(对于大多数最流行的数据库,你可以使用非常类似的方法),但是在大型企业公司中,Oracle多年来一直是首选的数据库系统,所以我将重点介绍这个。
  • 目标数据库:在这方面没有特别的原因。你可以选择AWS中的任何目标数据库,这个方法仍然适用。
  • 模式:可以进行完全刷新或增量刷新。批量数据加载(源数据库和目标数据库之间存在延迟)或(近)实时数据加载。这两种模式都将在这里涉及到。
  • 频率:你可能希望进行一次性迁移,然后完全切换到云端,或者需要某个过渡期,并且在本地和AWS上同时保持数据最新,这意味着需要开发每日在本地和AWS之间同步数据。前者更简单也更有意义,但后者更常见并且有更多的断点。我将在这里涵盖两种情况。

问题描述

需求通常很简单:

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

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

  • 不要过快地采纳“只是复制我们现有的数据,稍后再处理”的想法。我的意思是,是的,这是你可以做的最简单的事情,而且可以很快地完成,但这有可能导致一个根本性的架构问题,后期将无法在没有对大多数新的HTML标签进行重构的情况下解决。想象一下,云生态系统与本地生态系统完全不同。随着时间的推移,将引入几项新服务。自然地,人们将开始以完全不同的方式使用它们。在云中以1:1的方式复制本地状态几乎从来都不是一个好主意。也许在你的特殊情况下可以,但一定要再三核实。
  • 对需求提出一些有意义的疑问,例如:
    • 谁将是新平台的典型用户?在本地环境中,可能是一个事务性的业务用户;在云中,可能是一个数据科学家或数据仓库分析师,或者数据的主要用户可能是一个服务(例如Databricks,Glue,machine learning models等)。
    • 在过渡到云端后,预计日常工作会保留吗?如果不保留,预计会有何变化?
    • 你计划随着时间的推移大量增加数据吗?很可能答案是肯定的,因为这通常是迁移到云端的最重要的原因。一个新的数据模型应该为此做好准备。
  • 期望最终用户考虑一些常见的、预期的查询,这些查询将来自用户对新数据库的查询。这将决定现有HTML标签需要多大程度上进行更改,以保持性能相关。
  • 设置迁移

    一旦选择了目标数据库并且数据模型已经令人满意地讨论完毕,下一步是熟悉一下AWS Schema Conversion Tool。这个工具在以下几个方面都能派上用场:

    1. 分析并提取源数据模型。SCT将读取当前本地数据库中的内容,并生成一个源数据模型供使用。
    2. 基于目标数据库建议一个目标数据模型结构。
    3. 生成目标数据库部署脚本以安装目标数据模型(根据工具从源数据库中找到的信息)。这将生成部署脚本,执行后,云端数据库将准备好从本地数据库加载数据。
    参考:AWS Documentation

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

    首先,几乎不应该直接使用输出结果。我认为它更像是参考结果,你可以根据自己对数据的理解和目的进行调整,以及数据在云端的使用方式。

    其次,之前用户可能选择表格时希望快速获得有关某个具体数据领域的结果。但是现在,数据可能是为了进行分析而选择的。例如,之前在本地数据库中工作的数据库索引现在将变得无用,肯定不会提高与这种新使用相关的数据库系统的性能。同样地,您可能希望在目标系统上以与源系统之前不同的方式对数据进行分区。

    此外,在迁移过程中进行一些数据转换可能是不错的选择,基本上意味着更改某些表的目标数据模型(使其不再是1:1的副本)。随后,转换规则将需要实施到迁移工具中。

    配置迁移工具

    如果源数据库和目标数据库是相同类型的(例如,Oracle本地数据库与AWS上的Oracle,PostgreSQL与Aurora PostgreSQL等),那么最好使用具体数据库原生支持的专用迁移工具(例如,数据泵导出和导入,Oracle Goldengate等)。

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

    参考:AWS Documentation

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

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

    DMS任务配置是以一种用户友好的格式完成的,如JSON

    现在,在最简单的场景中,你只需要在目标数据库上运行部署脚本并启动DMS任务。但是实际上情况要复杂得多。

    一次性完整数据迁移

    执行最简单的情况是一次性将整个数据库迁移到目标云数据库。那么基本上,所需的操作如下:

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

    如果DMS的配置做得好,这种情况下不会发生任何问题。每个源表都将被选取并复制到AWS目标数据库中。唯一需要关注的是活动的性能以及确保每个步骤的大小适当,以避免由于存储空间不足而导致失败。

    每日增量同步

    事情从这里开始变得复杂。我的意思是,如果世界是理想的,那么一切可能会一直很顺利。但现实世界从来都不是理想的。

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

    • 全量加载 – 上述默认模式和描述的模式。当启动或按计划启动DMS任务时,DMS任务会开始执行。一旦完成,DMS任务就完成了。
    • Change Data Capture (CDC) – 在此模式下,DMS任务持续运行。DMS会在表级别扫描源数据库以检查是否有变化。如果发生变化,它会根据与更改表相关的DMS任务中的配置立即尝试在目标数据库中复制更改。

    选择CDC时,您需要再做出一个选择 – 即CDC将如何从源数据库提取增量更改。

    #1. Oracle Redo Logs Reader

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

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

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

    #2. AWS DMS Log Miner

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

    根据源数据库的大小和每日变更的数量,在最理想的情况下,您可能会实现从本地Oracle数据库到AWS云数据库的几乎实时增量数据同步。

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

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

    当出现问题时,无论何时

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

    DMS只能以一定的速度处理重做日志。无论DMS的实例数量如何执行您的任务,都不重要。每个DMS实例仍然以单一定义的速度读取重做日志,并且每个实例都必须整体读取它们。即使使用Oracle重做日志或 miner也是如此。两者都有此限制。

    如果源数据库在一天内包含大量更改,使得Oracle重做日志变得非常庞大(例如每天超过500GB),那么CDC就无法正常工作。复制将无法在当天结束之前完成。它将在第二天带来一些未处理的工作,第二天已经等待复制的一组新更改。未处理数据的量将不断增长。

    在这种特殊情况下,CDC不是一个选择(经过多次性能测试和尝试后)。确保至少将当前日期的所有增量更改在当天同步的唯一方法是采取以下方式:

    • 将不经常使用的非常庞大的表分开,并仅每周复制一次(例如在周末进行)。
    • 将不是非常庞大但仍然庞大的表的复制配置为在多个DMS任务之间分割;一个表最终由10个或更多独立的DMS任务并行迁移,确保DMS任务之间的数据分割是不同的(在此处涉及自定义编码)并且每天执行它们。
    • 增加更多(在这种情况下最多4个)DMS实例,并均匀地将DMS任务分配给它们,这意味着不仅按表的数量来分配,还按大小来分配。

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

    这不是一个完美的解决方案,但它仍然存在,并且即使经过多年,仍然以同样的方式工作。所以,也许这并不是一个糟糕的解决方案。😃

类似文章