Category: 数据库


使用DMT工具迁移北京区域的数据库

在前面的blog《将Oracle数据库迁移到AWS云的方案》中谈到了多种将Oracle数据库从数据中心迁移到AWS云中的方法。其中 使用DMS服务迁移的方法简单实用,也支持异构数据库的迁移,很多朋友都想使用这种方法完成迁移。但是在北京区域不支持DMS服务,如何实现类似的迁移工作呢?其实在北京区域支持使用Database Migration Tool(DMT)来迁移数据库,DMT工具是DMS服务的前身,它是安装在Windows上的一个软件,迁移前只需要获取DMT工具的AMI,然后简单的配置后,就可以进行数据迁移了。本文主要讨论如何使用DMT将Oracle迁移到Amazon RDS数据库,示例的场景如下图所示:

在建立客户本地数据中心与AWS连接的时候,考虑到安全性问题,我们建议您通过VPN或者企业专线来建立数据库之间的连接,您只需确保您本地数据库端口(例如Oracle端口1521)对外可访问。如果您的业务对安全性要求较高,需要传输的数据量较大,同时,要求以较快速度传输的时候,可以采用专线迁移,但是这种方法成本较高,您需要根据您的业务需求来选择是通过VPN还是企业专线迁移。

在介绍DMT数据库迁移之前,我们首先介绍一下DMT迁移工具支持的数据库类型以及对源和目标数据库的限制:DMT目前支持将Oracle、SQL Server、MySQL、SAP Sybase以及PostgreSQL作为源或目标数据库,您也可以将Amazon Redshift作为您的目标数据库。同时,DMT也支持异构数据库的迁移,例如将Oracle迁移到MySQL。

DMT工具为我们迁移数据库提供了巨大的便利,然而,它也有一些限制条件,下表主要介绍DMT支持的三种常用关系型数据库版本以及相关限制条件。如果您需要了解更多有关DMT迁移数据库信息,请参考DMT用户手册:

https://s3.cn-north-1.amazonaws.com.cn/rdmt/RDS+Migration+Tool+User+Guide.pdf

使用DMT迁移主要有下面几个步骤:

(1)获取DMT的AMI

(2)启动DMT的AMI

(3)登陆DMT服务器

(4)配置服务器

(5)访问DMT工具

(6)迁移数据

1.获取DMT的AMI

如果您有数据库数据需要导出或者导入到AWS 北京区域中,首先您需要获取DMT的AMI镜像,然后根据镜像启动EC2服务器。获取DMT的镜像有两种方式:

(1)和支持您当前AWS账号的商务人员联系,他能帮您在后台申请访问DMT AMI的权限。

(2)您也可以自己在Support Center 中开case。在AWS Console中访问Support Center的方式如下图所示:

2.启动DMT的AMI

当您有能访问DMT的AMI以后,登陆您的AWS账号,进入Services->EC2->AMI的界面,选择“Private images”列表,就可以看到有一个Amazon_RDS_Migration_Tool的记录,这就是最新的迁移工具,如下图所示:

选择DMT点击上方的“Lunch”按钮,启动一个已经安装好DMT工具的服务器。接下来您需要配置您实例的类型、大小、实例所在VPC以及安全组和密钥等信息。具体配置步骤请参考官方文档:http://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/EC2_GetStarted.html

需要注意的是:

(1)在选择DMT服务器所在VPC的时候,尽量选择源或者目标数据库所在的VPC创建DMT服务器,这样可以加快迁移的速度。

(2)在配置安全组的时候,您的安全组应该允许RDP协议和https协议。由于DMT服务器是Windows Server服务器,因此您需要使用Windows远程桌面连接访问,此时需要RDP协议,source指定当前需要连接客户端的IP或者IP段。DMT工具可以通过浏览器来访问,因此需要设置https协议的安全组,如下图所示:

3.登陆DMT服务器

启动DMT服务器,并下载私钥后,就可以登陆DMT服务器了,如下图所示,当您的服务器状态显示为running,并且通过健康检查后,您的服务器就可以正常访问了。如下图所示:

选择您的DMT服务器,然后点击Connect,显示如下界面:

在此步骤中,您需要根据下载的私钥获取登陆Windows的密码。点击 get Password,显示如下图所示界面:

输入您前面下载的私钥的文件全部内容,点击 Decrypt Password后,您在界面上可以看到Administrator的密码,请记录下这个密码。下面就可以登陆服务器了。

本例中是使用MAC的Windows远程终端软件来访问DMT服务器,如果您使用Windows客户端,访问过程类似,输入远程DMT服务器的DNS名称,输入用户名和密码并连接。

连接上DMT终端后,您会看到Windows Server 2012的桌面如下图所示,桌面上有DMT工具。

连接到远程终端后,您可以根据需要修改访问Windows的密码,修改密码可以在控制面板中完成,界面如下:

4. 配置服务器

登陆到DMT服务器后,在界面上有Database Migration Tool Documentation的目录,进入目录并下载QuickStart Guide.下载过程中如果出现如下错误,请添加授信站点或者配置服务器解决错误。

下载Quick Start Guide和PDF阅读软件。

打开QuickStart Guide如下图所示,您可以按照您数据库的类型(Oracle, MySQL等)选择相应的驱动程序。

本例中由于迁移的是Oracle数据库,安装Oracle的驱动和客户端相对复杂,下面会详细解释如何安装Oracle驱动,其他驱动的安装请参考文档。点击Quick Start Guide中的Oracle Instant Client后面的链接后,出现如下界面(需要您有Oracle账号才能下载软件):

下载Instant Client Package-Basic: All files required to run OCI….的文件,也就是上图第一个黄色方框中的文件。

下载Instant Client Package-ODBC驱动,如上图第二个黄色方框。由于DMT安装在Windows Server上,因此有很多安全的限制,如果遇到禁止下载的错误,可以参照下图:

选择Internet,然后点击Customer level。

选择Downloads,然后Enable下载,就可以正常下载Oracle的软件了。

下载完成后,basic和odbc的包如上图所示。

创建 c:\oracle目录,将目录作为解压的目录,选中 basic-windows的文件,然后解压到oracle目录,如下图示:

选中odbc的压缩包,然后解压到c:\oracle

解压后的文件目录结构大致如下:

选中 odbc_install.exe并运行,如下图:

选择run,默认没有反应是正常状态 。

将变量 C:\oracle\instantclient_12_1添加到Path变量中,如下图所示:

增加TNS_ADMIN变量如下图所示:

在本例中,增加的变量TNS_ADMIN和变量Path的值相同。

5.访问DMT工具

先使用界面上的工具Stop Amazon RDS Migration Service停止DMT服务。这样避免刚才设置的环境变量没有应用DMT工具中。

在点击在桌面点击下面图标启动DMT服务。

启动后,如果见到下面的窗口:

表示启动成功。

选择图标就可以启动DMT的Web访问客户端,如下图所示:

见到Console的界面,表示DMT服务启动成功。DMT的console可以在服务器上访问,也可以在客户端访问,在外网访问只需要获取到DMT服务器的Public DNS,使用下面格式URL从外网访问DMT console。

https://your-public-dns/AmazonRDSMigrationConsole

访问console后,会弹出如下界面,输入访问windows的用户名和密码。

输入登陆系统的用户名和密码并登陆,显示如下界面:

在界面中使用Manage Database创建Source和Target数据库,创建Task就可以开始迁移您的数据库了。

6.使用DMT迁移数据

当您通过前面的步骤能够正确地访问DMT工具,说明配置基本成功,下面就可以通过DMT迁移您的数据库了。

Step1: 配置源数据库连接信息

点击上图中的Manage Databases->Add Database,输入数据库类型为Oracle,填好具体URL及数据库的Role信息,示例信息如下:

参数说明:

Name:给需要迁移的数据库定义一个名称,可以根据需要定义。

Description:给需要迁移的数据库一个详细的描述。

Role:需要迁移数据库的角色,如果是迁移中的源数据库,则选择SOURCE,如果是迁移中的目标数据库,则选择TARGET.

Connection String:对于传统Oracle数据库的格式为 ip:port/sid

User name:数据库连接的用户名

Password:数据库连接的密码

Step2: 配置目标RDS数据库连接信息

配置目标RDS数据库信息如下:

RDS的Connection String的格式为:

<database-name>.<rds-endpoint>:<port>/<sid>

Step 3:检查Source和Target数据库的归档模式和Supplemental Log

由于DMT工具可以捕捉数据库日志,将源数据库的变化复制到目标数据库,这种复制方式要求源和目标数据库都是归档的数据库,并且需要Supplemental Log的设置。

使用SQL PLUS连接源数据库,如果数据库处于非归档模式,则将数据库改为归档模式。

运行下面语句,修改Supplemental Log设置:

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

Database altered.

使用Oracle SQL Developer或者其他客户端工具连接RDS目标数据库,运行下面的语句:

exec rdsadmin.rdsadmin_util.alter_supplemental_logging(‘ADD’);

Step 4:创建Task

在主界面上点击“New Task”,如下图所示:

Task options: 定义复制的类型,Full Load表示将当前的表和数据拷贝到目标数据库。Apply Changes表示将当前时刻到停止复制前的日志变化同步到目标数据库。如果两个都选择,表示同步数据,并将捕捉到的数据库变化复制到目标数据库。

Step 5:定义Task

将Source和Target数据库的图标,拖入到左边的流程图中,如下图所示,我们定义了将OracleSourceDB复制到RDSDatabase中。

定义好流程后,点击Table Selection选择需要复制哪些表。如下图所示:

在此图中,我们复制的是TEST.T_USERS表。您也可以使用Patterns的方式匹配表名。

点击Task中的Run按钮,很快数据库就开始迁移了。

7. 错误诊断

(1)如果在测试数据库时出现oci.dll无法加载的错误,如下图所示:

这个错误一般说明你没有将instance client的路径配置到path变量中去。此时只需要配置好变量,然后停止并启动DMT服务就可以了。

(2)ORA-12170: TNS: Connect timeout occurred [122307] OCI error.

如果出现此错误,说明DMT工具连接数据库超时,此时请检查RDS数据库的Security Group是否开启了DMT服务器的1521端口的访问,或者检查数据库的防火墙等网络设置,确保DMT服务器能够正常访问Oracle服务器。

作者介绍:

蓝勇

AWS解决方案架构师,负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内的应用和推广,在DR解决方案、数据仓库、RDS服务、企业应用、自动化运维等方面有着广泛的设计和实践经验。在加入AWS之前,在甲骨文中国担任资深售前工程师,负责售前方案咨询和架构设计,在数据库,中间件,大数据及企业应用方面有丰富经验。

杨婉洁

亚马逊AWS解决方案架构师实习生,喜欢编程,熟悉Java、C++、JSP、HTML以及关系型数据库。曾在学校和企业参与数据分析项目,熟悉各类数据分析的算法。热爱大数据、云计算。

使用Oracle Data Pump将数据库迁移到AWS的RDS Oracle数据库

1.Oracle数据库的迁移方法

如何将Oracle数据库从数据中心迁移到AWS云上是DBA经常遇到的问题,迁移Oracle数据库有多种方式:

(1)使用AWS DMS服务迁移

(2)使用Oracle SQL Developer迁移

(3)使用Oracle Data Pump迁移

(4)使用Oracle Export/Import迁移

(5)使用Oracle SQL Loader迁移

如果需要了解不同的迁移方法,可以参考 博客《Oracle数据库迁移到AWS云的方案》 。

2.使用Oracle Data Pump迁移

本文主要讨论使用Oracle Data Pump将Oracle数据库迁移到RDS数据库。示例数据库的信息如图。

 

下面是模拟在数据中心的Oracle11g源数据库中创建用户和表,并将源数据库迁移到AWS云中RDS Oracle 11g数据库的全过程。

步骤一:初始化源数据库并使用Data Pump导出

(1)使用SQL Plus登录源Oracle数据库

sqlplus / as sysdba

(2)创建用户test

create user test identified by welcome1;

(3)为新创建用户grant权限(实际使用请给用户grant合适的权限)

grant dba to test;

(4)为用户test创建表

create table test.aa(id varchar(20) not null primary key,name varchar2(30));

(5)为表插入数据并commit

SQL> insert into test.aa values(‘1111′,’1111name’);

1 row created.

SQL> insert into test.aa values(‘2222′,’2222name’);

1 row created.

SQL> commit;

Commit complete.

(6)在源数据库所在的Linux上逐级创建下面文件目录

mkdir /home/oracle/datapump/datafiles

(7)在SQLPlus中创建数据库Directory

create directory dpump_dir as ‘/home/oracle/datapump/datafiles’;

grant read,write on directory dpump_dir to test;

(8)使用expdp命令导出test用户的所有表

expdp test1/welcome123 directory=dpump_dir dumpfile=test.dmp

expdp test1/welcome123 directory=dpump_dir dumpfile=test1.dmp

步骤二:使用SQL Plus连接RDS数据库,并创建数据库目录对象

(1)在源数据库上配置RDS数据库的tnsnames

cd $ORACLE_HOME/network/admin

vi tnsnames.ora

输入tnsnames的内容如下:

ORARDS=(description=(address_list=(address = (protocol = TCP)(host =    RDS_HOST_NAME)(port = RDS_PORT)) )(connect_data =(SID=RDS_SID)))

(2)使用SQLPLUS连接远程RDS数据库

sqlplus oracle/welcome1@ORARDS

(3)使用tnsping检查RDS连接信息

如果连接有错误,可以使用下面命令查看通讯是否正常

tnsping “(description=(address_list=(address = (protocol = TCP)(host = RDS_HOST_NAME)(port = RDS_PORT)))(connect_data =(SID= RDS_SID)))”

tnsping应该返回“OK (xx msec)”类似文字。

如果tnsping不通请检查RDS对应的security group,RDS的security group中应当允许当前服务器通过TCP协议访问RDS数据库的端口。

(4)创建目标RDS的directory对象

exec rdsadmin.rdsadmin_util.create_directory(‘dpump_dir1’);

创建成功后退出连接RDS的SQL Plus客户端。

步骤三:将源数据库Data Pump导出的文件上传到RDS数据库

(1)连接源数据库并创建database link

create database link to_rds connect to oracle identified by welcome1 using ‘(description=(address_list=(address = (protocol = TCP)(host = RDS_HOST_NAME)(port = RDS_PORT)))(connect_data =(SID=RDS_SID)))’;

(2)运行DBMS_FILE_TRANSFER包将数据传输到RDS服务器的目录

BEGIN

DBMS_FILE_TRANSFER.PUT_FILE(

source_directory_object       => ‘dpump_dir1’,

source_file_name              => ‘test.dmp’,

destination_directory_object  => ‘dpump_dir1’,

destination_file_name         => ‘test.dmp’,

destination_database          => ‘to_rds’

);

END;

步骤四:通过impdp命令将远程的RDS数据库文件导入

(1)在源数据库服务器上运行impdp命令导入数据

impdp  oracle@ORARDS dumpfile=test.dmp directory=dpump_dir1 full=y

执行完毕检查test用户和相关的表。

3.    总结

从上面的过程我们可以看到,将一个Oracle数据库迁移到RDS的过程并不复杂,如果源数据库很大,由于需要导出数据、将数据上传到RDS的Data Pump目录、导入数据,迁移的过程也会比较长。上述过程假设了我们生产数据库的业务有足够的停机时间,在迁移过程中数据不会变化。如果迁移过程中,源数据库会发生变化,那么我们就需要同步数据中心和RDS数据库间的日志了。

如果源数据库很大,我们也可以在AWS上启动一台中间服务器,并在中间服务器上安装Oracle的客户端软件,将源数据库的Data Pump导出文件分片然后scp复制、Tsunami UDP加速上传等方式将文件上传到中间服务器,然后上传到RDS的Data Pump目录,这样能加速迁移的过程。

作者介绍:

蓝勇

AWS解决方案架构师,负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内的应用和推广,在DR解决方案、数据仓库、RDS服务、企业应用、自动化运维等方面有着广泛的设计和实践经验。在加入AWS之前,在甲骨文中国担任资深售前工程师,负责售前方案咨询和架构设计,在数据库,中间件,大数据及企业应用方面有丰富经验。

使用AWS的数据库迁移DMS服务

前面博客《Oracle数据库迁移到AWS云的方案》介绍了AWS数据库迁移的几种基本方法,本文主要介绍如何使用AWS的DMS服务完成数据库的迁移。

1.DMS服务介绍

为了使用户更容易的将数据库迁移到云中,AWS已经在海外区域推出了AWS Database Migration Service服务,如果您的数据库在海外,DMS可以在源数据库不停机的情况下,帮您将数据迁移到AWS云中。DMS的功能非常强大,支持同构数据库的迁移(如Oracle迁移到Oracle),也支持异构数据库直接的迁移,如Oracle到Mysql等)。在数据库迁移期间,源数据库无需停机,并且能将迁移期间数据的更改持续复制到目标数据库。因此迁移完成后,您只需在短暂的停机时间内直接切换数据库,从而保证业务数据的完整性。
在中国BJS区域,还没有推出DMS服务,但是提供了Database Migration Tool(DMT)工具,您可以使用DMT工具来完成数据库迁移。

2.使用DMS完成迁移

使用DMS服务必须确保源或目标数据库有一个在AWS云中。 使用DMS服务的步骤如下:

步骤一:Create migration

登陆AWS全球区域的Console,选择DMS,点击“Create migration”,我们便来到了“welcome”界面,从该界面我们可以看到,通过DMS进行数据迁移我们至少需要一个源数据库、目标数据库和复制实例。当然,DMS 也支持多个源数据库向一个目标数据库的迁移以及单个源数据库向多个目标数据库的迁移。迁移时,数据通过一个运行在复制实例上的任务将源数据库复制到目标数据库。点击“Next”进行复制实例的创建。

步骤二:创建“Replication Instance”

您在进行数据库迁移过程中的第一个任务是创建具有足够存储空间和处理能力的复制实例,通过复制实例来执行您分配的任务并将数据从您的源数据库迁移到目标数据库。此实例所需的大小取决于您要迁移的数据和您需要执行的任务量。具体配置参数见下表1。

如果您需要为网络和加密设置值,请选择高级选项卡。具体参数见表2。

步骤三:创建数据库连接

当您在创建复制实例时,您可以指定源和目标数据库。源数据库和目标数据库可以在AWS的EC2上,也可以是AWS的关系数据库服务(RDS)的DB实例或者本地数据库。在设置源和目标数据库时,             具体参数可以参见表3。您也可以通过高级选项卡来设置连接字符串和加密密钥的值。

等图示上部分的显示变成”Replication instance created successfully”并且“Run test“按钮变成正常,然后测试,确保测试结果为”Connection tested Successfully”,由于需要从AWS服务端连接测试数据库,因此需要设置好security group,设置的security group必须确保复制实例能够访问源和目标数据库。需要的话,可以短暂的将security group 1521 的访问设置为 0.0.0.0/0,测试成功后,点击”Next”按钮。

步骤四:创建“task”

当源数据库和目标数据库建立连接后,您需要创建一个任务来指定哪些表需要迁移,使用目标架构来映射数据并且在目标数据库中创建新表。作为创建任务的一部分,您可以选择迁移类型:迁移现有数据、迁移现有数据并复制正在进行的更改,或只复制更改的数据。

如果选择”Migrate existing data and replicate data changes”选项需要打开Task Settings 中的supplemental loging开关。在Table Mapping中Schema to Migrate选择“Oracle”,点击“Create Task”。

当您创建的task状态从creating变为ready的时候,您的task便创建好了。点击该“task”并点击上方的“Start/Resume”,您数据迁移任务便开始了!

数据库迁移完成后,目标数据库在您选择的时间段内仍会与源数据库保持同步,使您能够在方便的时候切换数据库。

3.总结

从上面过程我们可以看到,只需要简单的配置,DMS就可以帮助我们完成数据库的迁移任务,并且DMS服务是免费的,迁移过程中用到的资源是收费的。

作者介绍:

蓝勇

AWS解决方案架构师,负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内的应用和推广,在DR解决方案、数据仓库、RDS服务、企业应用、自动化运维等方面有着广泛的设计和实践经验。在加入AWS之前,在甲骨文中国担任资深售前工程师,负责售前方案咨询和架构设计,在数据库,中间件,大数据及企业应用方面有丰富经验。

Oracle数据库迁移到AWS云的方案

当前云已经成为常态,越来越多的企业希望使用云来增加基础设施的弹性、减轻基础设施的维护压力,运维的成本等。很多企业使用云碰到的难题之一是如何将现有的应用迁移到云上,将现有应用的中间件系统、Web系统及其他组件迁移到云上相对容易,一般只需要重新部署或复制即可,但如何将数据库迁移到AWS云中,是很多企业需要面对的一个难题。由于数据库的种类繁多,本文将以Oracle数据库为例,介绍将数据中心的Oracle迁移到云中的基本知识,不同方法涉及的迁移过程,请参考后续的博客。

1.云中数据库的模式

如果要在云中使用Oracle数据库,有两种选择:

  • EC2服务器模式

使用AWS的EC2服务器,在EC2服务器上手工安装Oracle数据库软件,用户需要自己准备Oracle的License,这和用户自己在机房安装Oracle数据库类似。如果在中国以外的区域,用户也可以使用AWS Marketplace里面的不同版本的Oracle镜像,直接初始化Oracle数据库,这种情况你也需要自己准备Oracle的License。

  • RDS模式

Amazon Relational Database Service (Amazon RDS) 是一种 AWS提供的Web 服务,可以让我们更轻松地在云中设置、 操作和扩展关系数据库,减少管理关系型数据库复杂的管理任务。RDS包括了Oracel、SQL Server、My SQL,等多种数据库引擎,你可以根据需要选择数据库的类型。

根据我们使用模式的不同,能选择的迁移方式也不同。

2.逻辑迁移和物理迁移

数据库的迁移可以分为逻辑迁移和物理迁移两种方式:

  • 逻辑迁移

逻辑迁移一般只是迁移数据库表、视图及其它数据库对象,不要求源库和目标库在底层的存储及表空间完全一致。逻辑迁移适用于EC2服务器模式和RDS模式。

逻辑迁移一般使用Dump/Load+Log Apply的方式,使用Dump工具将数据库对象从源数据库导出,然后Load到目标数据库,最后根据需要同步数据库日志。

  • 物理迁移

物理迁移可以让迁移的源库和目标库在底层的存储文件、存储介质、表空间、用户等信息完全一致。物理迁移适用于EC2服务器模式。

物理迁移(Oracle)一般是使用RMan等物理备份+Log Apply的方式,使用RMan等工具备份数据库,然后在目标系统还原数据库,最后根据需要同步日志。

3.日志同步

在迁移数据库过程中,如果我们的业务有足够停机时间,可以将源数据库设置成只读数据库,然后使用Dump/Load或者备份/还原的方式来创建目标库。因为源库是只读的,迁移过程中源库不会发生变化,因此只需要根据源库数据创建目标库,无需日志的同步。

在迁移数据库过程中,如果我们的业务没有足够的停机时间,此时除了要使用Dump/Load或备份还原的方式迁移已有数据,还需要将迁移过程中变化的数据同步到目标数据库,此时需要日志同步的工具。

4.Oracle数据库同步的方法

将Oracle数据库迁移到AWS云中主要有下面几种方法:

迁移Oracle数据库有多种方式,本文主要介绍以下五种,这五种方式都是逻辑迁移:

(1)使用AWS DMS服务迁移

AWS在中国以外的区域提供了数据库迁移DMS服务,支持同构和异构数据库间的迁移,也支持日志的同步。在中国区可以使用AWS提供的DMT(Database Migration Tool)工具完成同构或异构数据库间的迁移。

DMS适合于迁移中小型的数据库。

(2)使用Oracle SQL Developer迁移

Oracle提供的SQL Developer工具里面提供了迁移功能,适合于迁移数据较少的数据库。SQL Developer可以在Oracle的官网里免费下载。

(3)使用Oracle Data Pump迁移

使用Oracle Data Pump工具将数据库导出,复制数据到目标平台,最后使用Data Pump将数据导入到目标数据库。数据量较大或数据少的库都可以使用这种方式。

(4)使用Oracle Export/Import迁移

这种方式和Oracle Data Pump方式类似,需要使用Oracle导入/导出实用工具。

(5)使用Oracle SQL Loader迁移

使用Oracle SQL Loader的方式可以让数据导入的过程更快、效率更高。

5.日志同步的方法

如果要实现不停机的迁移,就需要使用日志同步的工具,Oracle数据库支持多种不同的工具同步日志:

  • DMS同步日志

AWS的DMS服务有同步日志的选项,可以使用DMS来同步日志。

  • GoldenGate工具

可以使用Oracle的GoldenGate工具,支持同步日志到EC2上的Oracle服务器和RDS数据库。

  • 其它第三方日志复制工具

根据数据库的使用情况,我们也可以尝试其他第三方的同步工具,如SharePlex等。

6.总结

我们在将数据库从数据中心迁移到AWS云的时候,需要根据数据库的大小、业务允许的停机时间、网络的带宽等多种因素选择我们的迁移方案,每种迁移的具体步骤请参考后续博客。

作者介绍:

蓝勇

AWS解决方案架构师,负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内的应用和推广,在DR解决方案、数据仓库、RDS服务、企业应用、自动化运维等方面有着广泛的设计和实践经验。在加入AWS之前,在甲骨文中国担任资深售前工程师,负责售前方案咨询和架构设计,在数据库,中间件,大数据及企业应用方面有丰富经验。

手把手教你调校AWS PB级数据仓库

什么是一个好的数据仓库?
Redshift是AWS云计算中的一个完全托管的,PB级别规模的数据仓库服务。即使在数据量非常小的时候(比如几百个GB的数据)你就可以开始使用Redshift,Redshift集群可以随着你数据的增加而不断扩容,甚至达到PB级。云计算中数据仓库的优势非常明显,不需要license,不需要预先配置非常大的数据仓库集群,扩容简单,仅仅需要为你实际所使用的数据仓库付费。
Redshift作为一个企业级数据仓库完全支持SQL语法,无学习成本,支持很多种客户端连接,包括各种市场上的BI工具,报表以及数据分析工具。

Redshift的概览
Redshift通过支持大规模并行处理(MPP),列式存储,对不同列数据使用不同数据压缩算法,关系型数据仓库(SQL),灵活的扩容管理等众多优点,兼顾了数仓性能,同时也考虑学习成本及使用成本。

Redshift系统架构及要点
图1,Redshift系统架构图

  • 主节点负责客户端与计算节点之间的所有通讯,编译代码并负责将编译好的代码分发给各个计算节点处理,负责分配数据到不同的计算节点,主节点对客户不可见的,无需客户管理主节点的压力,更重要的是主节点免费。
  • 计算节点是具体的干活的,并处理好的任务送给主节点进行合并后返回给客户端应用程序。每个计算节点都有自己独立的CPU,内存以及直连存储。Redshift集群规模大小通常就是指计算节点的个数以及计算节点机器类型。
  • 节点分片是指将计算节点被分成若干的分片,根据计算节点类型不同,每个节点包含的分片数量不同,通常1个vCPU对应一个分片,ds2的机型除外。每个分片都会分配独立的内存及存储资源,接受来自主节点分配的任务。分片跟另外一个重要概念Dist Key紧密相关, 这里先提一下,接下来会具体介绍Dist Key。
  • 排序键(Sort Key)是一个顺序键,即Redshift会根据这个键来将数据按顺序存储在硬盘上。Redshift的查询优化程序(只要理解有这么个东西存在就好,客户不需要任何维护,对客户也是透明的)也会根据这个排序来进行执行查询优化计划。这是Redshift性能调优的一个非常重要的参数。
  • 分配键(Distribution Key)是控制加载到表的数据如何分布在各个计算节点的一个键,有好几种分布的风格,接下来会重点讲到,这是Redshift调优的非常重要的另外一个参数。

Redshift的几个常用最佳实践
选择最佳排序键

  • 如果最近使用的数据查询频率最高,则指定时间戳列作为排序键的第一列;
  • 如果您经常对某列进行范围筛选或相等性筛选,则指定该列作为排序键;
  • 如果您频繁联接表,则指定联接列作为排序键和分配键;

熟悉Redshift的朋友可能知道可以指定多列作为排序键,而且排序键还有两种方式,组合式和交叉式。限于篇幅的原因,在接下来的调优测试中我们采用的是某一列作为排序键,如果有对其他排序键风格感兴趣的朋友,可以单独联系我们进行讨论。

选择最佳分配键

选择表分配方式的目的是通过在执行查询前将数据放在需要的位置来最大程度地减小重新分配步骤的影响,最好这个查询不需要二次移动数据。

分配键有三种风格,均匀分布(Even),键分布(Key),全分布(All),默认是均匀分布。

  • 根据共同列分配事实数据表和一个维度表;

事实数据表只能有一个分配键。任何通过其他键联接的表都不能与事实数据表并置。根据联接频率和联接行的大小选择一个要并置的维度。将维度表的主键和事实数据表对应的外键指定为 DISTKEY。

  • 根据筛选的数据集的大小选择最大的维度;

只有用于联接的行需要分配,因此需要考虑筛选后的数据集的大小,而不是表的大小。

  • 在筛选结果集中选择基数高的列;

例如,如果您在日期列上分配了一个销售表,您可能获得非常均匀的数据分配,除非您的大多数销售都是季节性的。但是,如果您通常使用范围受限谓词进行筛选以缩小日期期间的范围,则大多数筛选行将位于有限的一组切片上并且查询工作负载将偏斜。

  • 将一些维度表改为使用 ALL 分配;

如果一个维度表不能与事实数据表或其他重要的联接表并置,您可以通过将整个表分配到所有节点来大大提高查询性能。使用 ALL 分配会使存储空间需求成倍增长,并且会增加加载时间和维护操作,所以在选择 ALL 分配前应权衡所有因素。

优化COPY,提高数据加载速度
当你将要数据加载到Redshift的某个表时,不要让单个输入文件过大,最好是将这些输入文件切成多份,具体数量最好是跟分片数量匹配,这样可以充分利用所有分片,配合分配键能达到最佳效果。

图2,COPY输入的最优方式

让COPY选择自动压缩
作为数据仓库,Redshift通常会需要大量导入数据,这时使用做多的,效率最好的是COPY命令。在使用COPY时建议将COMPUPDATE参数设置为ON,这样数据在加载进库时是自动压缩的,好处是可以节省存储空间,提高查询的速度,不过这会增加数据加载进表的时间,这个可以根据你的业务需求,再具体衡量。

Redshift调优实战
测试结论

  1. 选择合适的排序键,分配键,及自动压缩对表的查询速度,存储效率很大提升。本次测试中,优化后查询速度有高达75%的提升,存储空间节省50%。
  2. 相同节点类型情况下,多节点性能比单节点性能提升明显。本次测试中,采用了4节点与单节点对比,4节点查询速度比单节点提升75%。
  3. 节点数量相同的情况下,dc系列节点的查询速度比ds系列节点的查询速度要快。本次测试中,采用了dc1.large和ds1.xlarge两种节点类型进行对比,dc系列节点的查询速度比ds系列快20% 。
  4. 使用JOIN与不使用JOIN查询速度无明显差别。本次测试中,三个不同的查询及对应的JOIN查询,在查询速度上的差别非常小。这部分的详细测试结果,请参见附录一。
  5. 查询速度达到一定值时,再增加节点对查询优化的效果有限。本次测试中,在相同环境中,将节点数量从8个dc1.large节点增加到12个dc1.large节点,三个查询只有一个查询的速度有一定提升,其他2个查询速度基本没有太大变化。这部分的详细测试结果,请参见附录二。

图3,调优前后性能对比图

备注:性能对比图从三个方面进行了对比,数据加载速度表存储空间查询的速度。本次测试的原始数据放在AWS Oregon S3,Redshift也在Oregon区域。

 

测试场景
表1,本次测试中用到的表及表的大小

图4,本次测试中表之间的关系

测试步骤

注意:本次测试步骤已假设Redshift集群已启动,且用户知道如何通过JDBC方式连接Redshift集群。

Before(不做任何优化):

  1. 创建表(不指定排序键和分配键);
  2. 加载数据(不进行自动压缩);
  3. 查询Redshift中各个表的存储空间;
  4. 执行三种不同查询,均取第2次查询所耗时间;
  5. 相同条件,使用JOIN查询所耗时间;

After(指定排序键和分配键,加载数据时进行了自动压缩):

  1. 删除表;
  2. 创建表(指定排序键和分配键);
  3. 加载数据(根据不同数据类型选择合适的压缩算法);
  4. 查询Redshift中各个表的存储空间;
  5. 执行三种不同查询,均取第2次查询所耗时间;
  6. 相同条件,使用JOIN查询所耗时间;

测试截图
图5,单个节点(ds1.xlarge)的数据加载时间(优化前)

图6,单个节点(ds1.xlarge)的数据加载时间(优化后)

图7,单个节点(ds1.xlarge)的数据存储空间(优化前)

图8,单个节点(ds1.xlarge)的数据存储空间(优化后)

图9,单个节点(ds1.xlarge)的查询时间(优化前)

图10,单个节点(ds1.xlarge)的查询时间(优化后)

图11,4个节点(ds1.xlarge)的数据加载时间(优化前)

图12,4个节点(ds1.xlarge)的数据加载时间(优化后)

图13,4个节点(ds1.xlarge)的数据存储空间(优化前)

图14,4个节点(ds1.xlarge)的数据存储空间(优化后)

图15,4个节点(ds1.xlarge)的查询时间 (优化前)

图16,4个节点(ds1.xlarge)的查询时间 (优化后)

图17,4个节点(dc1.large)的数据加载时间 (优化前)

图18,4个节点(dc1.large)的数据加载时间 (优化后)

图19,4个节点(dc1.large)的数据存储空间 (优化前)

图20,4个节点(dc1.large)的数据存储空间 (优化后)

图21,4个节点(dc1.large)的查询时间 (优化前)

图22,4个节点(dc1.large)的查询时间 (优化后)

 

本次测试中用到的命令参数
Before (优化前)

CREATE TABLE part

(

p_partkey     INTEGER NOT NULL,

p_name        VARCHAR(22) NOT NULL,

p_mfgr        VARCHAR(6) NOT NULL,

p_category    VARCHAR(7) NOT NULL,

p_brand1      VARCHAR(9) NOT NULL,

p_color       VARCHAR(11) NOT NULL,

p_type        VARCHAR(25) NOT NULL,

p_size        INTEGER NOT NULL,

p_container   VARCHAR(10) NOT NULL

);

CREATE TABLE supplier

(

s_suppkey   INTEGER NOT NULL,

s_name      VARCHAR(25) NOT NULL,

s_address   VARCHAR(25) NOT NULL,

s_city      VARCHAR(10) NOT NULL,

s_nation    VARCHAR(15) NOT NULL,

s_region    VARCHAR(12) NOT NULL,

s_phone     VARCHAR(15) NOT NULL

);

CREATE TABLE customer

(

c_custkey      INTEGER NOT NULL,

c_name         VARCHAR(25) NOT NULL,

c_address      VARCHAR(25) NOT NULL,

c_city         VARCHAR(10) NOT NULL,

c_nation       VARCHAR(15) NOT NULL,

c_region       VARCHAR(12) NOT NULL,

c_phone        VARCHAR(15) NOT NULL,

c_mktsegment   VARCHAR(10) NOT NULL

);

CREATE TABLE dwdate

(

d_datekey            INTEGER NOT NULL,

d_date               VARCHAR(19) NOT NULL,

d_dayofweek          VARCHAR(10) NOT NULL,

d_month              VARCHAR(10) NOT NULL,

d_year               INTEGER NOT NULL,

d_yearmonthnum       INTEGER NOT NULL,

d_yearmonth          VARCHAR(8) NOT NULL,

d_daynuminweek       INTEGER NOT NULL,

d_daynuminmonth      INTEGER NOT NULL,

d_daynuminyear       INTEGER NOT NULL,

d_monthnuminyear     INTEGER NOT NULL,

d_weeknuminyear      INTEGER NOT NULL,

d_sellingseason      VARCHAR(13) NOT NULL,

d_lastdayinweekfl    VARCHAR(1) NOT NULL,

d_lastdayinmonthfl   VARCHAR(1) NOT NULL,

d_holidayfl          VARCHAR(1) NOT NULL,

d_weekdayfl          VARCHAR(1) NOT NULL

);

CREATE TABLE lineorder

(

lo_orderkey          INTEGER NOT NULL,

lo_linenumber        INTEGER NOT NULL,

lo_custkey           INTEGER NOT NULL,

lo_partkey           INTEGER NOT NULL,

lo_suppkey           INTEGER NOT NULL,

lo_orderdate         INTEGER NOT NULL,

lo_orderpriority     VARCHAR(15) NOT NULL,

lo_shippriority      VARCHAR(1) NOT NULL,

lo_quantity          INTEGER NOT NULL,

lo_extendedprice     INTEGER NOT NULL,

lo_ordertotalprice   INTEGER NOT NULL,

lo_discount          INTEGER NOT NULL,

lo_revenue           INTEGER NOT NULL,

lo_supplycost        INTEGER NOT NULL,

lo_tax               INTEGER NOT NULL,

lo_commitdate        INTEGER NOT NULL,

lo_shipmode          VARCHAR(10) NOT NULL

);

copy customer from ‘s3://lyz/redshift/customer’

credentials ‘aws_access_key_id= your-key;aws_secret_access_key=your-secret-key’

gzip compupdate off region ‘us-west-2’;

 

copy dwdate from ‘s3://lyz/redshift/dwdate’

credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘

gzip compupdate off region ‘us-west-2’;

 

copy lineorder from ‘s3://lyz/redshift/lineorder’

credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘

gzip compupdate off region ‘us-west-2’;

 

copy part from ‘s3://lyz/redshift/part’

credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘

gzip compupdate off region ‘us-west-2’;

 

copy supplier from ‘s3://lyz/redshift/supplier’

credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘

gzip compupdate off region ‘us-west-2’;

 

select count(*) from LINEORDER;

select count(*) from PART;

select count(*) from  CUSTOMER;

select count(*) from  SUPPLIER;

select count(*) from  DWDATE;

 

select stv_tbl_perm.name as table, count(*) as mb

from stv_blocklist, stv_tbl_perm

where stv_blocklist.tbl = stv_tbl_perm.id

and stv_blocklist.slice = stv_tbl_perm.slice

and stv_tbl_perm.name in (‘lineorder’,’part’,’customer’,’dwdate’,’supplier’)

group by stv_tbl_perm.name

order by 1 asc;

 

— Query 1

— Restrictions on only one dimension.

select sum(lo_extendedprice*lo_discount) as revenue

from lineorder, dwdate

where lo_orderdate = d_datekey

and d_year = 1997

and lo_discount between 1 and 3

and lo_quantity < 24;

 

— Query 2

— Restrictions on two dimensions

 

select sum(lo_revenue), d_year, p_brand1

from lineorder, dwdate, part, supplier

where lo_orderdate = d_datekey

and lo_partkey = p_partkey

and lo_suppkey = s_suppkey

and p_category = ‘MFGR#12’

and s_region = ‘AMERICA’

group by d_year, p_brand1

order by d_year, p_brand1;

 

— Query 3

— Drill down in time to just one month

 

select c_city, s_city, d_year, sum(lo_revenue) as revenue

from customer, lineorder, supplier, dwdate

where lo_custkey = c_custkey

and lo_suppkey = s_suppkey

and lo_orderdate = d_datekey

and (c_city=’UNITED KI1′ or

c_city=’UNITED KI5′)

and (s_city=’UNITED KI1′ or

s_city=’UNITED KI5′)

and d_yearmonth = ‘Dec1997’

group by c_city, s_city, d_year

order by d_year asc, revenue desc;

After(优化后):

drop table part cascade;

drop table supplier cascade;

drop table customer cascade;

drop table dwdate cascade;

drop table lineorder cascade;

 

CREATE TABLE part (

p_partkey     integer             not null sortkey distkey,

p_name        varchar(22)      not null,

p_mfgr           varchar(6)      not null,

p_category    varchar(7)      not null,

p_brand1      varchar(9)      not null,

p_color          varchar(11)      not null,

p_type           varchar(25)      not null,

p_size            integer             not null,

p_container   varchar(10)     not null

);

 

CREATE TABLE supplier (

s_suppkey                 integer        not null sortkey,

s_name        varchar(25)    not null,

s_address     varchar(25)    not null,

s_city             varchar(10)    not null,

s_nation         varchar(15)    not null,

s_region        varchar(12)    not null,

s_phone       varchar(15)    not null)

diststyle all;

 

CREATE TABLE customer (

c_custkey     integer        not null sortkey,

c_name        varchar(25)    not null,

c_address     varchar(25)    not null,

c_city             varchar(10)    not null,

c_nation         varchar(15)    not null,

c_region        varchar(12)    not null,

c_phone       varchar(15)    not null,

c_mktsegment      varchar(10)    not null)

diststyle all;

 

CREATE TABLE dwdate (

d_datekey            integer       not null sortkey,

d_date               varchar(19)   not null,

d_dayofweek       varchar(10)   not null,

d_month            varchar(10)   not null,

d_year               integer       not null,

d_yearmonthnum       integer            not null,

d_yearmonth          varchar(8)           not null,

d_daynuminweek       integer       not null,

d_daynuminmonth      integer       not null,

d_daynuminyear       integer       not null,

d_monthnuminyear     integer       not null,

d_weeknuminyear      integer       not null,

d_sellingseason      varchar(13)    not null,

d_lastdayinweekfl    varchar(1)    not null,

d_lastdayinmonthfl   varchar(1)    not null,

d_holidayfl          varchar(1)    not null,

d_weekdayfl          varchar(1)    not null)

diststyle all;

 

CREATE TABLE lineorder (

lo_orderkey                   integer         not null,

lo_linenumber           integer             not null,

lo_custkey                 integer             not null,

lo_partkey                  integer             not null distkey,

lo_suppkey                integer             not null,

lo_orderdate              integer             not null sortkey,

lo_orderpriority          varchar(15)     not null,

lo_shippriority            varchar(1)      not null,

lo_quantity                 integer             not null,

lo_extendedprice       integer             not null,

lo_ordertotalprice      integer             not null,

lo_discount                integer             not null,

lo_revenue                integer             not null,

lo_supplycost            integer             not null,

lo_tax                         integer             not null,

lo_commitdate         integer         not null,

lo_shipmode              varchar(10)     not null

);

 

copy customer from ‘s3://lyz/redshift/customer’

credentials ‘aws_access_key_id=your-key;aws_secret_access_key=your-secret-key’

gzip region ‘us-west-2’;

 

copy dwdate from ‘s3://lyz/redshift/dwdate’

credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘

gzip region ‘us-west-2’;

 

copy lineorder from ‘s3://lyz/redshift/lineorder’

credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘

gzip region ‘us-west-2’;

 

copy part from ‘s3://lyz/redshift/part’

credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘

gzip region ‘us-west-2’;

 

copy supplier from ‘s3://lyz/redshift/supplier’

credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘

gzip region ‘us-west-2’;

 

select stv_tbl_perm.name as table, count(*) as mb

from stv_blocklist, stv_tbl_perm

where stv_blocklist.tbl = stv_tbl_perm.id

and stv_blocklist.slice = stv_tbl_perm.slice

and stv_tbl_perm.name in (‘lineorder’,’part’,’customer’,’dwdate’,’supplier’)

group by stv_tbl_perm.name

order by 1 asc;

 

— Query 1

— Restrictions on only one dimension.

select sum(lo_extendedprice*lo_discount) as revenue

from lineorder, dwdate

where lo_orderdate = d_datekey

and d_year = 1997

and lo_discount between 1 and 3

and lo_quantity < 24;

 

— Query 2

— Restrictions on two dimensions

 

select sum(lo_revenue), d_year, p_brand1

from lineorder, dwdate, part, supplier

where lo_orderdate = d_datekey

and lo_partkey = p_partkey

and lo_suppkey = s_suppkey

and p_category = ‘MFGR#12’

and s_region = ‘AMERICA’

group by d_year, p_brand1

order by d_year, p_brand1;

 

— Query 3

— Drill down in time to just one month

 

select c_city, s_city, d_year, sum(lo_revenue) as revenue

from customer, lineorder, supplier, dwdate

where lo_custkey = c_custkey

and lo_suppkey = s_suppkey

and lo_orderdate = d_datekey

and (c_city=’UNITED KI1′ or

c_city=’UNITED KI5′)

and (s_city=’UNITED KI1′ or

s_city=’UNITED KI5′)

and d_yearmonth = ‘Dec1997’

group by c_city, s_city, d_year

order by d_year asc, revenue desc;

附录一
图23,查询1所耗时间,8节点(dc1.large)

图24,查询1使用JOIN所耗时间,8节点(dc1.large)

图25,查询2所耗时间,8节点(dc1.large)

图26,查询2使用JOIN所耗时间,8节点(dc1.large)

图27,查询3所耗时间,8节点(dc1.large)

图28,查询3使用JOIN所耗时间,8节点(dc1.large)

附录二
图29,查询1所耗时间,12节点(dc1.large)

图30,查询2所耗时间,12节点(dc1.large)

图31,查询3所耗时间,12节点(dc1.large)

作者介绍:

郑进佳

亚马逊AWS解决方案架构师,在加入AWS之前,在多家跨国公司有着超过7年的架构设计和项目管理的经验,对AWS云端高可用架构有着深刻的理解,以及对企业级应用如何迁移到云端的架构设计有实战方面的经验。