All Products
Search
Document Center

E-MapReduce:E-MapReduce data migration solution

Last Updated:Jul 24, 2026

Migrate data from a self-built Hadoop cluster to an E-MapReduce (EMR) cluster on Alibaba Cloud. This guide covers end-to-end migration of HDFS data, Hive metadata, Apache Flume streams, jobs, and Presto configurations from on-premises or Elastic Compute Service (ECS)-hosted Hadoop clusters to EMR.

Migration scenarios

EMR supports the following migration paths:

Source environment

Migration path

On-premises (IDC) Hadoop cluster

Migrate through OSS or Express Connect to EMR

Self-built Hadoop cluster on ECS

Migrate through network interconnection to EMR

Supported incremental upstream data sources for Hadoop Distributed File System (HDFS) include ApsaraDB RDS incremental data and Apache Flume.

Prerequisites

Before you begin, make sure that you have:

  • Network connectivity between the source and target clusters (see Establish network connectivity)

  • The NameNode IP address of the source cluster (use the active NameNode if HA is configured)

  • The ACL configuration status of the source cluster (dfs.permissions.enabled and dfs.namenode.acls.enabled)

  • The Hive version running on the source cluster

  • The Hive metastore database type (MySQL) and connection credentials

Migration phases

Phase

Task

Description

1

Establish network connectivity

Connect the source and target cluster networks

2

Migrate HDFS data

Copy data with DistCp (full and incremental)

3

Migrate Hive metadata

Export, transform, and import Hive metastore data

4

Migrate Flume streams

Set up dual-write Flume configuration

5

Migrate jobs

Adapt and test jobs on the new cluster

6

Migrate Presto configuration

Update Hive connector properties for Presto

7

Validate data

Verify data integrity through reports

Establish network connectivity

Choose a connectivity method based on your source cluster environment.

On-premises IDC to VPC

A self-built Hadoop cluster in an on-premises IDC can connect to EMR through one of the following methods:

Method

Description

OSS-based migration

Upload data to Object Storage Service (OSS) and access it from the EMR cluster.

Express Connect

Establish a dedicated connection between your on-premises IDC and the Virtual Private Cloud (VPC) where your EMR cluster resides.

ECS-hosted clusters to VPC

VPC networks are logically isolated. To connect a self-built Hadoop cluster on ECS to a VPC-based EMR cluster, choose the method that matches your network type.

Classic network to VPC

Use the ECS ClassicLink method to interconnect the classic network and the VPC network. For detailed steps, see Build a ClassicLink connection.

VPC to VPC

Create the new EMR cluster in the same region and zone as the source cluster for optimal connectivity.

Migrate HDFS data

Use DistCp (Distributed Copy) to migrate full and incremental HDFS data. Run distcp after the source and target cluster networks are interconnected.

Important

Before running DistCp, decide on your write-interruption strategy:

  • Full synchronization — Requires a brief application write stop. Halt all business writes to the source cluster before running the full sync command. This allows you to enable dual-write and dual-counting mode, or switch traffic directly to the new cluster after the copy completes.

  • Incremental synchronization (using the -update flag) — Does not require stopping writes. Use incremental sync during the migration window to minimize service interruption.

The "Service cutover" row in the Performance considerations table below provides additional context on this trade-off.

Full data synchronization

Run the following command to perform a full copy of HDFS data:

Incremental data synchronization

Run the following command to synchronize only changed data:

hadoop distcp -pbugpcax -m 1000 -bandwidth 30 -update -delete hdfs://oldclusterip:8020/user/hive/warehouse /user/hive/warehouse

DistCp parameter reference

Parameter

Description

hdfs://oldclusterip:8020

The NameNode IP of the source cluster. If HA is configured with multiple NameNodes, specify the active NameNode.

-p

Preserves file attributes. The flags bugpcax preserve block size, user, group, permissions, checksum, ACL, and xattr. The default replica count is 3. To keep the original replica count, add r (for example, -prbugpcax). To skip permissions and ACL sync, remove p and a.

-m

Number of map tasks. Size this based on your cluster capacity and data volume. For example, a cluster with 2,000 CPU cores can specify 2,000 maps.

-bandwidth

Throttle the copy speed per map task (in MB/s). Controls the replica copy rate for each individual map.

-update

Verifies the checksum and file size of source and target files. If sizes differ, the source file overwrites the target. Use this flag for incremental synchronization during dual-write periods.

-delete

Removes files from the target cluster that no longer exist in the source cluster.

Performance considerations

Factor

Guidance

Cluster bandwidth and size

Migration speed depends on cluster bandwidth and cluster size. The more files involved, the longer checksum verification takes.

Large data volumes

Synchronize a few directories first to estimate the total time required.

Batch processing

If migration does not finish within the planned window, split directories into smaller batches and synchronize them one at a time.

Service cutover

Full data synchronization requires a brief service stop to enable dual-write and dual-counting, after which you can switch traffic to the new cluster.

HDFS permission configuration

Before migrating HDFS data, verify the following:

  1. Check whether the source cluster has ACL rules and whether those rules should be synchronized.

  2. Confirm that dfs.permissions.enabled and dfs.namenode.acls.enabled are configured identically on both the source and target clusters. Changes to these settings take effect immediately.

If ACL rules need to be synchronized:

  • Include the p and a flags in the -p parameter of the distcp command to sync permissions and ACLs.

  • If distcp reports that the cluster does not support ACLs, the ACL rule was not configured on that cluster.

    • Target cluster missing ACL support: Add the ACL configuration and restart NodeManager.

    • Source cluster does not support ACL: No ACL synchronization is required.

Migrate Hive metadata

Hive metadata is typically stored in MySQL. During migration, two adjustments are required:

  • Location replacement: Update the HDFS nameservices prefix in all table and partition locations.

  • Hive version alignment: Upgrade the metastore schema if the source cluster runs an earlier Hive version.

Supported Hive metastore types in EMR

EMR supports three Hive metastore configurations:

Type

Description

Unified metastore

EMR manages ApsaraDB RDS. Each user has a dedicated schema.

Self-built ApsaraDB RDS

You manage your own ApsaraDB RDS instance for the metastore.

Self-built MySQL on ECS

You run MySQL on an ECS instance for the metastore.

Procedure

Important

To guarantee complete data consistency between the source and target clusters, stop the Hive metastore service on the source cluster before starting the export. Once the migration is complete, restart the metastore service on the source cluster and then submit jobs on the new cluster.

  1. Delete the target cluster metastore database.

       DROP DATABASE xxx;
  2. Export the source cluster metastore. Run mysqldump to export the table structure and data:

  3. Replace location prefixes. Hive metadata stores location information with a dfs.nameservices prefix (for example, hdfs://mycluster:8020/). The EMR cluster uses emr-cluster as its nameservices prefix. Replace all occurrences:

       sed -i 's|hdfs://oldcluster:8020/|hdfs://emr-cluster/|g' hive_databases.sql
  4. Stop the Hive metastore service on the target cluster. Stop the hivemetastore service from the EMR cluster management interface.

  5. Create the database on the target metastore. Log on to the target metastore and create the database.

  6. Import the modified data. Import the exported data (with updated location prefixes) into the target metastore:

  7. Upgrade the Hive metastore schema (if required). If the source cluster runs an earlier Hive version, run the Apache Hive upgrade scripts in sequence to bring the schema up to date. Upgrade scripts are available at: Apache Hive metastore upgrade scripts (MySQL) For example, to upgrade from Hive 1.2 to 2.3.0, run the following scripts in order: These scripts create tables, add fields, and modify content. Errors about tables or fields that already exist can be safely ignored.

       upgrade-1.2.0-to-2.0.0.mysql.sql
       upgrade-2.0.0-to-2.1.0.mysql.sql
       upgrade-2.1.0-to-2.2.0.mysql.sql
       upgrade-2.2.0-to-2.3.0.mysql.sql
  8. Verify the metadata. After all metadata updates are complete, restart the Hive metastore service. Then run the hive command from the command line to query databases and tables and confirm that the information is correct.

Migrate Flume streams

After HDFS data and Hive metadata are migrated, set up Flume to write to the new cluster.

Set up dual-write configuration

Start the Flume service on the new EMR cluster and configure it with the same rules as the source cluster. This creates a dual-write setup where Flume writes to both clusters simultaneously.

Manage partition timing

Control the start timing of the dual-write carefully. The new cluster synchronization must begin when Flume starts a new time partition.

  • If Flume synchronizes tables hourly, start the Flume synchronization service on the new cluster before the next hourly partition begins.

  • Incomplete data from previous partitions is covered by the full HDFS data synchronization with DistCp.

  • New data generated after dual-write is enabled is not re-synchronized.

Important

Do not place newly written data into the data synchronization directory when partitioning data.

Migrate jobs

If the version differences between the source and target clusters are significant (Hadoop, Hive, Spark, or MapReduce), rebuild jobs as needed.

Troubleshooting

Gateway node OOM

If the Gateway node runs out of memory, increase the heap size.

Edit /etc/ecm/hive-conf/hive-env.sh and change:

export HADOOP_HEAPSIZE=512

to:

export HADOOP_HEAPSIZE=1024

Insufficient job execution memory

Two settings control job memory allocation:

Parameter

Description

Default

Recommended

mapreduce.map.java.opts

JVM startup parameters for map tasks. Sets the maximum heap memory. When exceeded, the JVM throws an OutOfMemoryError.

-Xmx200m

-Xmx3072m

mapreduce.map.memory.mb

Memory limit for the YARN container, enforced by NodeManager. When a container exceeds this limit, NodeManager terminates it.

-

3840

Set these values in your job configuration:

set mapreduce.map.java.opts=-Xmx3072m;
set mapreduce.map.memory.mb=3840;

Migrate Presto configuration

If the source cluster uses Presto, update the Hive connector configuration files on the EMR cluster. For more information, see Presto Hive connector documentation.

Update the following Hive properties:

Property

Value

connector.name

hive-hadoop2

hive.metastore.uri

thrift://emr-header-1.cluster-500148414:9083

hive.config.resources

/etc/ecm/hadoop-conf/core-site.xml, /etc/ecm/hadoop-conf/hdfs-site.xml

hive.allow-drop-table

true

hive.allow-rename-table

true

hive.recursive-directories

true

Validate data

After all migration phases are complete, verify the migration by generating and reviewing reports that compare the data in the source and target clusters.

Appendix: Hive upgrade script example (1.2 to 2.3)

The following example shows the SQL statements executed when upgrading Hive from version 1.2 to 2.3. These scripts are located at /usr/lib/hive-current/scripts/metastore/upgrade/mysql/ on the EMR cluster.

-- Step 1: Run upgrade-1.2.0-to-2.0.0.mysql.sql
source /usr/lib/hive-current/scripts/metastore/upgrade/mysql/upgrade-1.2.0-to-2.0.0.mysql.sql

CREATE TABLE COMPACTION_QUEUE (
  CQ_ID bigint PRIMARY KEY,
  CQ_DATABASE varchar(128) NOT NULL,
  CQ_TABLE varchar(128) NOT NULL,
  CQ_PARTITION varchar(767),
  CQ_STATE char(1) NOT NULL,
  CQ_TYPE char(1) NOT NULL,
  CQ_WORKER_ID varchar(128),
  CQ_START bigint,
  CQ_RUN_AS varchar(128),
  CQ_HIGHEST_TXN_ID bigint,
  CQ_META_INFO varbinary(2048),
  CQ_HADOOP_JOB_ID varchar(32)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE TXNS (
  TXN_ID bigint PRIMARY KEY,
  TXN_STATE char(1) NOT NULL,
  TXN_STARTED bigint NOT NULL,
  TXN_LAST_HEARTBEAT bigint NOT NULL,
  TXN_USER varchar(128) NOT NULL,
  TXN_HOST varchar(128) NOT NULL,
  TXN_AGENT_INFO varchar(128),
  TXN_META_INFO varchar(128),
  TXN_HEARTBEAT_COUNT int
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE HIVE_LOCKS (
  HL_LOCK_EXT_ID bigint NOT NULL,
  HL_LOCK_INT_ID bigint NOT NULL,
  HL_TXNID bigint,
  HL_DB varchar(128) NOT NULL,
  HL_TABLE varchar(128),
  HL_PARTITION varchar(767),
  HL_LOCK_STATE char(1) NOT NULL,
  HL_LOCK_TYPE char(1) NOT NULL,
  HL_LAST_HEARTBEAT bigint NOT NULL,
  HL_ACQUIRED_AT bigint,
  HL_USER varchar(128) NOT NULL,
  HL_HOST varchar(128) NOT NULL,
  HL_HEARTBEAT_COUNT int,
  HL_AGENT_INFO varchar(128),
  HL_BLOCKEDBY_EXT_ID bigint,
  HL_BLOCKEDBY_INT_ID bigint,
  PRIMARY KEY(HL_LOCK_EXT_ID, HL_LOCK_INT_ID),
  KEY HIVE_LOCK_TXNID_INDEX (HL_TXNID)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE INDEX HL_TXNID_IDX ON HIVE_LOCKS (HL_TXNID);

-- Step 2: Run upgrade-2.0.0-to-2.1.0.mysql.sql
source /usr/lib/hive-current/scripts/metastore/upgrade/mysql/upgrade-2.0.0-to-2.1.0.mysql.sql

CREATE TABLE TXN_COMPONENTS (
  TC_TXNID bigint,
  TC_DATABASE varchar(128) NOT NULL,
  TC_TABLE varchar(128),
  TC_PARTITION varchar(767),
  FOREIGN KEY (TC_TXNID) REFERENCES TXNS (TXN_ID)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- Step 3: Run upgrade-2.1.0-to-2.2.0.mysql.sql
source /usr/lib/hive-current/scripts/metastore/upgrade/mysql/upgrade-2.1.0-to-2.2.0.mysql.sql

CREATE TABLE IF NOT EXISTS `NOTIFICATION_LOG` (
  `NL_ID` BIGINT(20) NOT NULL,
  `EVENT_ID` BIGINT(20) NOT NULL,
  `EVENT_TIME` INT(11) NOT NULL,
  `EVENT_TYPE` varchar(32) NOT NULL,
  `DB_NAME` varchar(128),
  `TBL_NAME` varchar(128),
  `MESSAGE` mediumtext,
  PRIMARY KEY (`NL_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `PARTITION_EVENTS` (
  `PART_NAME_ID` bigint(20) NOT NULL,
  `DB_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
  `EVENT_TIME` bigint(20) NOT NULL,
  `EVENT_TYPE` int(11) NOT NULL,
  `PARTITION_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
  `TBL_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
  PRIMARY KEY (`PART_NAME_ID`),
  KEY `PARTITIONEVENTINDEX` (`PARTITION_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE COMPLETED_TXN_COMPONENTS (
  CTC_TXNID bigint NOT NULL,
  CTC_DATABASE varchar(128) NOT NULL,
  CTC_TABLE varchar(128),
  CTC_PARTITION varchar(767)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- Step 4: Run upgrade-2.2.0-to-2.3.0.mysql.sql
source /usr/lib/hive-current/scripts/metastore/upgrade/mysql/upgrade-2.2.0-to-2.3.0.mysql.sql

CREATE TABLE NEXT_TXN_ID (
  NTXN_NEXT bigint NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO NEXT_TXN_ID VALUES(1);

CREATE TABLE NEXT_LOCK_ID (
  NL_NEXT bigint NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO NEXT_LOCK_ID VALUES(1);