이 연재글은 Database Migration 실습의 5번째 글입니다.

DMS

AWS 서비스 중엔 DMS라는 재미있는 서비스가 있습니다. DMS는 AWS Database Migration Service(AWS DMS)의 약자로서 소스 데이터 스토어에서 대상 데이터 스토어로 마이그레이션하는 데 사용할 수 있는 웹 서비스입니다.

서비스를 운영하다보면 특정한 DB에서 다른 DB나 이종의 스토어로 데이터를 이관해야 하는 경우가 종종 발생 합니다. 자체 솔루션을 가지고 있지 않은경우 프로그래머나 DBA가 수작업으로 노가다를 해야하고 마이그레이션 이후 검증도 해야 하는 대단히 고된 작업입니다. 대용량 마이그레이션이 필요할 경우 서비스를 몇시간 이상 중단하고 작업해야 하는 것은 덤입니다.

이러한 상황에서 Solution이 될 수 있는것이 DMS입니다. AWS DMS는 마이그레이션 프로젝트와 관련된 어렵거나 지루한 작업 중 많은 부분을 맡아 처리합니다. 또한 대상 스토어에 대한 깊은 지식이 없는 개발자도 손쉽게 데이터 이관을 할 수 있습니다. 놀라운 점은 DB to DB 뿐만 아니라 상당히 다양한 서비스로 데이터를 이관할 수 있도록 기능을 제공한다는 점 입니다. Source Endpoint로 사용 가능한 서비스와 Target Endpoint로 사용가능한 서비스는 다음과 같습니다.

Source Endpoint 호환 데이터 베이스

https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Introduction.Sources.html

  • Amazon Aurora(MySQL 호환 데이터 원본으로 지원됨) MySQL
  • Amazon Aurora(PostgreSQL 호환 데이터 원본으로 지원됨) PostgreSQL
  • Amazon DocumentDB(MongoDB와 호환)
  • Amazon S3
  • Linux, UNIX 및 Windows용 IBM Db2 LUW
  • MariaDB(MySQL 호환 데이터 원본으로 지원됨) 버전 10.0.24 ~ 10.0.28, 10.1, 10.2 및 10.3, 10.3.13, 10.4.
  • Microsoft Azure SQL 데이터베이스.
  • Microsoft SQL Server
  • MongoDB 버전 3.x 및 4.0.
  • MySQL
  • Oracle
  • PostgreSQL
  • SAP Sybase ASE

Target Endpoint 호환 데이터 베이스

https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Introduction.Targets.html

  • Amazon Aurora(MySQL 호환 데이터 원본으로 지원됨) MySQL
  • Amazon Aurora MySQL Serverless
  • Amazon Aurora(PostgreSQL 호환 데이터 원본으로 지원됨) PostgreSQL
  • Amazon Aurora PostgreSQL Serverless
  • Amazon DocumentDB(MongoDB와 호환)
  • Amazon DynamoDB
  • Amazon Kinesis
  • Amazon Neptune
  • Amazon Redshift
  • Amazon S3
  • Elasticsearch Service
  • Kafka
  • MariaDB
  • Microsoft SQL Server
  • MySQL
  • Oracle
  • PostgreSQL
  • SAP Sybase ASE

Migration을 위한 단계별 작업

DMS는 다음과 같은 3가지 요소를 설정함으로서 마이그레이션 작업을 수행할 수 있습니다.

Replication Instance (복제 인스턴스 생성)

Source Database에서 Target Database로 이관 하는 작업을 수행하는 서버 인스턴스 입니다. 마이그레이션 성능에 따라 여러가지 서버 사양을 선택하여 생성할 수 있습니다.

Endpoint (마이그레이션 대상 설정)

Source 및 Target Database에 접근하기 위한 Endpoint 정보입니다. (Source/Destination Database의 host 및 id/password와 같은 접속 정보) 생성한 Endpoint는 Replication Instance에서 연결 가능한지 테스트 할 수 있습니다.

Migration Tasks (마이그레이션 작업 설정)

위에서 생성한 Replication Instance와 Source/Target Endpoint정보를 이용하여 마이그레이션 작업을 만들고 수행합니다. Migration Task를 사용하면 마이그레이션할 스키마와 마이그레이션 유형을 지정할 수 있습니다. 기존 데이터를 마이그레이션하거나, 지속적 변경 사항을 복제하거나, 또는 데이터 변경 사항만 복제할 수 있습니다.

Mysql Database -> Kafka Topic Migration 실습

DMS를 사용하면 소스와 대상의 데이터 베이스 엔진이 다른 이기종 간의 데이터 마이그레이션이 가능합니다. 실습에서는 Aurora Mysql Database에서 MSK(Managed Service Apache Kafka)로의 데이터 마이그레이션을 진행해 보겠습니다.

이미 Database와 Kafka가 준비된 상황이라면 Step1,2는 생략해도 됩니다.

Step1. Aurora Mysql DataBase 생성

Mysql Database에서 DMS를 사용하여 마이그레이션을 하려면 binary logging(binlog)이 활성화 되어있어야 합니다. parameter_group을 하나 생성하여 Database 생성시 관련 설정을 적용해 줍니다.

AWS Service – RDS – Parameter groups – Create parameter group을 클릭하여 새로운 parameter group을 생성합니다. 이때 Type은 DB Cluster Parameter Group을 선택해야 합니다. Group name과 Description은 적당한 내용을 입력하여 생성합니다.

생성한 parameter_group의 상세 정보로 들어가면 다음과 같은 화면이 나오는데 filter에 binlog_format이라고 입력합니다. 그러면 다음과 같이 1개의 항목이 나오는데 Edit Parameter를 클릭하여 Values를 ROW로 변경하고 저장합니다. 아래 그림은 설정 완료한 상태입니다.

Aurora Database를 생성합니다. AWS Service – RDS – Create database를 클릭하여 Aurora Mysql Database를 생성합니다. 실습에서는 대부분 기본 설정을 사용합니다.

Capacity type은 Provisioned를 선택합니다. Serverless의 경우 아직은 Source 데이터베이스로 사용할 수 없습니다.

Templates 정보는 데이터베이스 이름과 접속할 계정 정보를 설정할 수 있습니다. 적당한 값을 입력합니다.

DB instance size는 테스트이므로 제일 작은 사양을 선택합니다. Availability & durability는 기본 설정을 사용합니다.

Connectivity 정보도 대부분 기본값을 사용합니다. 실습에서는 로컬 PC에서 접속할 수 있도록 Public access는 Yes로 설정합니다.

Additional configration을 클릭하여 항목을 엽니다. 항목 중 DB Cluster parameter group을 위에서 설정한 Parameter group 설정으로 변경합니다. 나머지 값들은 기본 설정을 사용합니다.

Create database를 클릭하여 DB를 생성합니다. 생성하는데 시간이 걸리므로 바로 Step2를 진행합니다.

Step2. MSK(Managed Service Kafka) 생성

AWS Service – MSK로 이동합니다. Kafka를 생성하기전 Cluster Configuration을 하나 생성합니다.

Cluster configurations – Create cluster configuration을 클릭합니다. General 항목은 알맞게 입력하고 Configuration properties for revision 1의 code 항목에서 auto.create.topics.enable=true로 설정하고 Create를 클릭하여 설정을 저장합니다.

이제 MSK를 생성합니다. Clusters – Create Cluster를 클릭합니다.

Create cluster with custom settings 를 선택합니다.

General – Cluster name에 적당한 이름을 입력합니다.

Configuration – Use a custom configuration을 선택 후 위에서 생성한 Configuration을 선택합니다.

실습에서는 기본 VPC를 사용합니다. Numbers of Zones는 2를 선택합니다. First Zone, Second Zone은 알맞게 선택합니다.

Broker type은 최소 사양인 kafka.t3.small을 선택합니다. Number of brokers per Zone은 1을 입력합니다.

EBS storage volume per broker는 1GiB를 입력합니다.

Encryption – Within the cluster – Enable encryption within the cluster는 체크 해제합니다.

나머지 설정은 기본값을 사용하고 Create cluster를 클릭하여 생성합니다. msk 생성에도 시간이 오래 걸리므로 Step3를 진행합니다.

Step3. Replication Instance 생성

AWS Service – Database Migration Service – Replication instances 로 이동합니다.

Create replication instance를 클릭합니다.

Name에는 적당한 이름을 입력하고 Instance class는 실습이므로 최소 사양을 선택합니다.

VPC 는 default를 선택합니다.

나머지 설정은 기본값을 사용합니다. Create를 클릭하여 생성합니다.

Step4. Source/Target Endpoint 생성

이 단계부터는 Aurora Database와 MSK(kafka)가 생성 완료 된 상태에서 진행 가능합니다. 먼저 Source endpoint를 생성합니다.

Source Endpoint 생성

Endpoint – Create Endpoint를 클릭합니다. Select RDS DB instance를 선택하고 아래 셀렉트 박스에서 위에서 생성한 DB를 선택합니다.

Database 접속을 위한 정보를 입력합니다.

Test endpoint connection(optional)를 클릭하여 펼칩니다. VPC는 기본을 선택하고 Replication Instance는 위에서 생성한 Instance를 선택하고 Run test를 클릭합니다. status 상태가 success 인것을 확인한다음 Create를 클릭하여 Endpoint를 생성합니다.

Target Endpoint 생성

Endpoint – Create Endpoint를 클릭합니다. 이번엔 Target endpoint를 선택합니다.

Endpoint identifier에는 적당한 이름을 입력합니다. Target engine은 Kafka를 선택합니다. Broker정보는 위에서 생성한 MSK의 broker정보를 입력합니다. Topic에는 마이그레이션 정보를 저장할 Topic이름을 입력합니다. 입력하지 않으면 시스템이 default(kafkadefaulttopic) topic을 생성합니다.

Test endpoint connection(optional)를 클릭하여 펼칩니다. VPC는 기본을 선택하고 Replication Instance는 위에서 생성한 Instance를 선택하고 Run test를 클릭합니다. status 상태가 success 인것을 확인한다음 Create를 클릭하여 Endpoint를 생성합니다.

Step5. Migration Task 생성 및 마이그레이션 작업 진행

이제 Task만 작성하면 마이그레이션을 수행할 수 있습니다.

Database migration tasks – Create task를 클릭합니다.

task identifier에는 알맞은 값을 입력합니다.
Replication instance, Source database endpoint, Target database endpoint는 위에서 생성한 정보를 선택합니다.

Mygration Type은 3가지가 있는데 알맞은 타입을 선택합니다.

  • Migrate existing data – 소스 엔드 포인트에서 대상 엔드 포인트로 일회성 마이그레이션을 수행합니다.
  • Migrate existing data and replicate ongoing changes – 소스에서 타겟으로 일회성 마이그레이션을 수행 한 다음 소스에서 타겟으로 데이터 변경 사항을 계속 복제합니다.
  • Replicate data changes only – 일회성 마이그레이션은 수행하지 않고 소스에서 대상으로 데이터 변경 사항만 계속 복제합니다.

Table mappings 세팅

Selection rule 항목에서는 Source database에서 마이그레이션할 대상을 선택할 수 있습니다. 설정에 따라 데이터 베이스 전체 테이블을 복제할 수도 있고 특정 테이블만 복제할 수도 있습니다.

Transformation rule에서는 마이그레이션 데이터에 대한 가공을 진행할 수 있습니다. 테이블 명을 변경한다던지 컬럼의 이름이나 데이터 타입을 변경할 수 있습니다.

Selection rule은 필수이므로 한가지 rule은 무조건 입력해야 합니다. 실습에서는 특정테이블 1개만 마이그레이션 하도록 rule을 생성하였습니다.
Create task를 클릭하여 task를 생성합니다. 생성이 완료되면 Actions – Restart/Resume을 선택하여 마이그레이션을 시작할 수 있습니다.

Step6. 마이그레이션 데이터 확인

마이그레이션이 완료되면 다음과 같이 Status가 Replication~~ ongoing으로 변경됩니다.

Table statistics 탭에서는 마이그레이션 된 테이블의 통계정보를 확인할 수 있습니다.

MSK(kafka) Topic에는 다음과 같은 포맷으로 메시지가 전달됩니다. data 항목에는 table의 정보가 json형태로 마이그레이션 되서 전달되고 metadata 항목에는 마이그레이션 데이터에 대한 기본 정보가 전달됩니다.

  • DDL : operation : drop-table, create-table
  • DML : operation : load, insert, update, delete
// drop-table
{
	"metadata":	{
		"timestamp":	"2020-11-26T13:27:02.482358Z",
		"record-type":	"control",
		"operation":	"drop-table",
		"partition-key-type":	"task-id",
		"schema-name":	"kwtoon",
		"table-name":	"gift"
	}
}
// create-table
{
	"metadata":	{
		"timestamp":	"2020-11-26T13:27:02.489854Z",
		"record-type":	"control",
		"operation":	"create-table",
		"partition-key-type":	"task-id",
		"schema-name":	"kwtoon",
		"table-name":	"gift"
	}
}
// load
{
	"data":	{
		"id":	1,
		"name":	"coupon",
		"created":	"2020-11-26T12:38:28Z"
	},
	"metadata":	{
		"timestamp":	"2020-11-26T13:27:02.498033Z",
		"record-type":	"data",
		"operation":	"load",
		"partition-key-type":	"primary-key",
		"schema-name":	"kwtoon",
		"table-name":	"gift"
	}
}
// insert
{
	"data":	{
		"id":	2,
		"name":	"coupon",
		"created":	"2020-11-26T12:38:28Z"
	},
	"metadata":	{
		"timestamp":	"2020-12-08T05:30:59.118012Z",
		"record-type":	"data",
		"operation":	"insert",
		"partition-key-type":	"schema-table",
		"schema-name":	"kwtoon",
		"table-name":	"gift"
	}
}
// update
{
	"data":	{
		"id":	1,
		"name":	"cash",
		"created":	"2020-11-26T12:38:28Z"
	},
	"metadata":	{
		"timestamp":	"2020-11-26T13:29:24.751256Z",
		"record-type":	"data",
		"operation":	"update",
		"partition-key-type":	"schema-table",
		"schema-name":	"kwtoon",
		"table-name":	"gift",
		"transaction-id":	8589934811
	}
}
// delete
{
	"data":	{
		"id":	1,
		"name":	"cash",
		"created":	"2020-11-26T12:38:28Z"
	},
	"metadata":	{
		"timestamp":	"2020-11-26T13:30:15.674865Z",
		"record-type":	"data",
		"operation":	"delete",
		"partition-key-type":	"schema-table",
		"schema-name":	"kwtoon",
		"table-name":	"gift",
		"transaction-id":	8589935097
	}
}
연재글 이동[이전글] Database Migration by Transactional Outbox Pattern