セルフビルドの Hadoop クラスターから Alibaba Cloud 上の E-MapReduce (EMR) クラスターにデータを移行します。このガイドでは、オンプレミスまたは Elastic Compute Service (ECS) でホストされている Hadoop クラスターから EMR への、Hadoop 分散ファイルシステム (HDFS) データ、Hive メタデータ、Apache Flume ストリーム、ジョブ、および Presto 設定のエンドツーエンドの移行について説明します。
移行シナリオ
EMR は、以下の移行パスをサポートしています。
|
ソース環境 |
移行パス |
|
オンプレミス (IDC) の Hadoop クラスター |
Object Storage Service (OSS) または Express Connect を介して EMR に移行 |
|
ECS 上のセルフビルド Hadoop クラスター |
ネットワーク相互接続を介して EMR に移行 |
HDFS でサポートされている増分アップストリームデータソースには、ApsaraDB RDS の増分データと Apache Flume が含まれます。
前提条件
開始する前に、以下を確認してください。
-
ソースクラスターとターゲットクラスター間のネットワーク接続 (ネットワーク接続の確立をご参照ください)
-
ソースクラスターの NameNode の IP アドレス (HA が設定されている場合はアクティブな NameNode を使用)
-
ソースクラスターの ACL 設定ステータス (
dfs.permissions.enabledおよびdfs.namenode.acls.enabled) -
ソースクラスターで実行されている Hive のバージョン
-
Hive メタストアのデータベースタイプ (MySQL) と接続認証情報
移行フェーズ
|
フェーズ |
タスク |
説明 |
|
1 |
ネットワーク接続の確立 |
ソースクラスターとターゲットクラスターのネットワークを接続 |
|
2 |
DistCp でデータをコピー (完全および増分) |
|
|
3 |
Hive メタストアデータのエクスポート、変換、インポート |
|
|
4 |
デュアルライト Flume 構成の設定 |
|
|
5 |
新しいクラスターでジョブを適合させ、テスト |
|
|
6 |
Presto の Hive コネクタプロパティを更新 |
|
|
7 |
レポートを通じてデータ整合性を検証 |
ネットワーク接続の確立
ソースクラスターの環境に基づいて接続方法を選択します。
オンプレミス IDC から VPC へ
オンプレミス IDC 内のセルフビルド Hadoop クラスターは、以下のいずれかの方法で EMR に接続できます。
|
方法 |
説明 |
|
OSS ベースの移行 |
データを OSS にアップロードし、EMR クラスターからアクセスします。 |
|
Express Connect |
オンプレミス IDC と EMR クラスターが存在する Virtual Private Cloud (VPC) との間に専用接続を確立します。 |
ECS ホストクラスターから VPC へ
VPC ネットワークは論理的に分離されています。ECS 上のセルフビルド Hadoop クラスターを VPC ベースの EMR クラスターに接続するには、ネットワークタイプに合った方法を選択します。
クラシックネットワークから VPC へ
ECS の ClassicLink メソッドを使用して、クラシックネットワークと VPC ネットワークを相互接続します。詳細な手順については、「ClassicLink 接続の構築」をご参照ください。
VPC から VPC へ
最適な接続性を確保するために、ソースクラスターと同じリージョンとゾーンに新しい EMR クラスターを作成します。
HDFS データの移行
DistCp (分散コピー) を使用して、完全および増分 HDFS データを移行します。ソースクラスターとターゲットクラスターのネットワークが相互接続された後、distcp を実行します。
DistCp を実行する前に、書き込み中断戦略を決定してください。
-
完全同期 — 短時間、アプリケーションの書き込みを停止する必要があります。完全同期コマンドを実行する前に、ソースクラスターへのすべての業務書き込みを停止します。これにより、デュアルライトおよびデュアルカウントモードを有効にするか、コピー完了後にトラフィックを直接新しいクラスターに切り替えることができます。
-
増分同期 (
-updateフラグを使用) — 書き込みを停止する必要はありません。移行ウィンドウ中に増分同期を使用して、サービスの中断を最小限に抑えます。
以下の「パフォーマンスに関する考慮事項」テーブルの「サービスカットオーバー」行で、このトレードオフに関する追加情報を提供します。
完全データ同期
次のコマンドを実行して、HDFS データの完全コピーを実行します。
増分データ同期
次のコマンドを実行して、変更されたデータのみを同期します。
hadoop distcp -pbugpcax -m 1000 -bandwidth 30 -update -delete hdfs://oldclusterip:8020/user/hive/warehouse /user/hive/warehouse
DistCp パラメーターリファレンス
|
パラメーター |
説明 |
|
|
ソースクラスターの NameNode の IP。複数の NameNode で HA が設定されている場合は、アクティブな NameNode を指定します。 |
|
|
ファイル属性を保持します。フラグ |
|
|
マップタスクの数。クラスターの容量とデータ量に基づいてサイズを決定します。たとえば、2,000 CPU コアのクラスターでは 2,000 マップを指定できます。 |
|
|
マップタスクごとのコピー速度を制限します (MB/s)。個々のマップのレプリカコピーレートを制御します。 |
|
|
ソースファイルとターゲットファイルのチェックサムとファイルサイズを検証します。サイズが異なる場合、ソースファイルがターゲットを上書きします。デュアルライト期間中の増分同期にこのフラグを使用します。 |
|
|
ソースクラスターに存在しなくなったファイルをターゲットクラスターから削除します。 |
パフォーマンスに関する考慮事項
|
要因 |
ガイダンス |
|
クラスターの帯域幅とサイズ |
移行速度は、クラスターの帯域幅とクラスターのサイズに依存します。関与するファイルが多いほど、チェックサムの検証に時間がかかります。 |
|
大容量データ |
最初にいくつかのディレクトリを同期して、必要な合計時間を見積もります。 |
|
バッチ処理 |
計画されたウィンドウ内で移行が終了しない場合は、ディレクトリを小さなバッチに分割し、一度に 1 つずつ同期します。 |
|
サービスカットオーバー |
完全データ同期では、デュアルライトとデュアルカウントを有効にするために短時間のサービス停止が必要です。その後、トラフィックを新しいクラスターに切り替えることができます。 |
HDFS 権限設定
HDFS データを移行する前に、以下を確認してください。
-
ソースクラスターに ACL ルールがあるか、またそれらのルールを同期する必要があるかを確認します。
-
dfs.permissions.enabledとdfs.namenode.acls.enabledがソースクラスターとターゲットクラスターの両方で同一に設定されていることを確認します。これらの設定への変更は即座に有効になります。
ACL ルールを同期する必要がある場合:
-
権限と ACL を同期するために、
distcpコマンドの-pパラメーターにpとaフラグを含めます。 -
distcpがクラスターが ACL をサポートしていないと報告した場合、そのクラスターには ACL ルールが設定されていませんでした。-
ターゲットクラスターに ACL サポートがない場合: ACL 設定を追加し、NodeManager を再起動します。
-
ソースクラスターが ACL をサポートしていない場合: ACL の同期は不要です。
-
Hive メタデータの移行
Hive メタデータは通常 MySQL に保存されます。移行中、2 つの調整が必要です。
-
ロケーションの置換: すべてのテーブルとパーティションのロケーションで、HDFS の
nameservicesプレフィックスを更新します。 -
Hive バージョンの整合: ソースクラスターが古い Hive バージョンを実行している場合、メタストアスキーマをアップグレードします。
EMR でサポートされている Hive メタストアタイプ
EMR は 3 つの Hive メタストア設定をサポートしています。
|
タイプ |
説明 |
|
統合メタストア |
EMR が ApsaraDB RDS を管理します。各ユーザーは専用のスキーマを持ちます。 |
|
セルフビルド ApsaraDB RDS |
メタストア用に独自の ApsaraDB RDS インスタンスを管理します。 |
|
ECS 上のセルフビルド MySQL |
メタストア用に ECS インスタンス上で MySQL を実行します。 |
操作手順
ソースクラスターとターゲットクラスター間の完全なデータ整合性を保証するために、エクスポートを開始する前にソースクラスターの Hive メタストアサービスを停止してください。移行が完了したら、ソースクラスターのメタストアサービスを再起動し、その後新しいクラスターでジョブを送信します。
-
ターゲットクラスターのメタストアデータベースを削除します。
DROP DATABASE xxx; -
ソースクラスターのメタストアをエクスポートします。
mysqldumpを実行して、テーブル構造とデータをエクスポートします。 -
ロケーションプレフィックスを置換します。 Hive メタデータは、
dfs.nameservicesプレフィックス (例:hdfs://mycluster:8020/) を持つロケーション情報を保存します。EMR クラスターは、nameservices プレフィックスとしてemr-clusterを使用します。すべての出現箇所を置換します。sed -i 's|hdfs://oldcluster:8020/|hdfs://emr-cluster/|g' hive_databases.sql -
ターゲットクラスターの Hive メタストアサービスを停止します。 EMR クラスター管理インターフェイスから
hivemetastoreサービスを停止します。 -
ターゲットメタストアにデータベースを作成します。 ターゲットメタストアにログインし、データベースを作成します。
-
変更されたデータをインポートします。 エクスポートされたデータ (ロケーションプレフィックスが更新されたもの) をターゲットメタストアにインポートします。
-
Hive メタストアスキーマをアップグレードします (必要な場合)。 ソースクラスターが古い Hive バージョンを実行している場合、Apache Hive のアップグレードスクリプトを順に実行してスキーマを最新の状態にします。アップグレードスクリプトは Apache Hive メタストアアップグレードスクリプト (MySQL) で入手できます。たとえば、Hive 1.2 から 2.3.0 にアップグレードするには、次のスクリプトを順に実行します。これらのスクリプトはテーブルを作成し、フィールドを追加し、コンテンツを変更します。既に存在するテーブルやフィールドに関するエラーは安全に無視できます。
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 -
メタデータを検証します。 すべてのメタデータ更新が完了したら、Hive メタストアサービスを再起動します。その後、コマンドラインから
hiveコマンドを実行してデータベースとテーブルをクエリし、情報が正しいことを確認します。
Flume ストリームの移行
HDFS データと Hive メタデータが移行された後、新しいクラスターに書き込むように Flume を設定します。
デュアルライト設定のセットアップ
新しい EMR クラスターで Flume サービスを開始し、ソースクラスターと同じルールで設定します。これにより、Flume が両方のクラスターに同時に書き込むデュアルライト設定が作成されます。
パーティションのタイミングの管理
デュアルライトの開始タイミングを慎重に制御します。新しいクラスターの同期は、Flume が新しい時間パーティションを開始するときに開始する必要があります。
-
Flume が 1 時間ごとにテーブルを同期する場合、次の時間パーティションが始まる前に新しいクラスターで Flume 同期サービスを開始します。
-
以前のパーティションからの不完全なデータは、DistCp による完全な HDFS データ同期でカバーされます。
-
デュアルライトが有効になった後に生成された新しいデータは再同期されません。
データをパーティション分割する際、新しく書き込まれたデータをデータ同期ディレクトリに配置しないでください。
ジョブの移行
ソースクラスターとターゲットクラスターのバージョン差 (Hadoop、Hive、Spark、または MapReduce) が大きい場合は、必要に応じてジョブを再構築します。
トラブルシューティング
ゲートウェイノードの OOM
ゲートウェイノードがメモリ不足になった場合は、ヒープサイズを増やします。
/etc/ecm/hive-conf/hive-env.sh を編集し、以下を変更します。
export HADOOP_HEAPSIZE=512
宛先:
export HADOOP_HEAPSIZE=1024
ジョブ実行メモリの不足
2 つの設定がジョブのメモリ割り当てを制御します。
|
パラメーター |
説明 |
デフォルト |
推奨 |
|
|
マップタスクの JVM 起動パラメーター。最大ヒープメモリを設定します。超過すると、JVM は |
|
|
|
|
YARN コンテナのメモリ制限。NodeManager によって強制されます。コンテナがこの制限を超えると、NodeManager はそれを終了します。 |
- |
|
ジョブ設定でこれらの値を設定します。
set mapreduce.map.java.opts=-Xmx3072m;
set mapreduce.map.memory.mb=3840;
Presto 設定の移行
ソースクラスターが Presto を使用している場合、EMR クラスター上の Hive コネクタ設定ファイルを更新します。詳細については、「Presto Hive コネクタドキュメント」をご参照ください。
次の Hive プロパティを更新します。
|
プロパティ |
値 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
データの検証
すべての移行フェーズが完了したら、ソースクラスターとターゲットクラスターのデータを比較するレポートを生成してレビューし、移行を検証します。
付録:Hive アップグレードスクリプトの例 (1.2 から 2.3)
次の例は、Hive をバージョン 1.2 から 2.3 にアップグレードする際に実行される SQL ステートメントを示しています。これらのスクリプトは、EMR クラスターの /usr/lib/hive-current/scripts/metastore/upgrade/mysql/ にあります。
-- ステップ 1: 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);
-- ステップ 2: 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;
-- ステップ 3: 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;
-- ステップ 4: 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);