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.enabledanddfs.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 |
Copy data with DistCp (full and incremental) |
|
|
3 |
Export, transform, and import Hive metastore data |
|
|
4 |
Set up dual-write Flume configuration |
|
|
5 |
Adapt and test jobs on the new cluster |
|
|
6 |
Update Hive connector properties for Presto |
|
|
7 |
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.
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
-updateflag) — 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 |
|
|
The NameNode IP of the source cluster. If HA is configured with multiple NameNodes, specify the active NameNode. |
|
|
Preserves file attributes. The flags |
|
|
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. |
|
|
Throttle the copy speed per map task (in MB/s). Controls the replica copy rate for each individual map. |
|
|
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. |
|
|
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:
-
Check whether the source cluster has ACL rules and whether those rules should be synchronized.
-
Confirm that
dfs.permissions.enabledanddfs.namenode.acls.enabledare 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
pandaflags in the-pparameter of thedistcpcommand to sync permissions and ACLs. -
If
distcpreports 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
nameservicesprefix 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
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.
-
Delete the target cluster metastore database.
DROP DATABASE xxx; -
Export the source cluster metastore. Run
mysqldumpto export the table structure and data: -
Replace location prefixes. Hive metadata stores location information with a
dfs.nameservicesprefix (for example,hdfs://mycluster:8020/). The EMR cluster usesemr-clusteras its nameservices prefix. Replace all occurrences:sed -i 's|hdfs://oldcluster:8020/|hdfs://emr-cluster/|g' hive_databases.sql -
Stop the Hive metastore service on the target cluster. Stop the
hivemetastoreservice from the EMR cluster management interface. -
Create the database on the target metastore. Log on to the target metastore and create the database.
-
Import the modified data. Import the exported data (with updated location prefixes) into the target metastore:
-
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 -
Verify the metadata. After all metadata updates are complete, restart the Hive metastore service. Then run the
hivecommand 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.
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 |
|
|
JVM startup parameters for map tasks. Sets the maximum heap memory. When exceeded, the JVM throws an |
|
|
|
|
Memory limit for the YARN container, enforced by NodeManager. When a container exceeds this limit, NodeManager terminates it. |
- |
|
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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);