1.数据迁移前期准备
1、迁移总数据量有多少?
2、新老集群之间的带宽有多少?能否全部用完?为了减少对线上其他业务的影响最多可使用多少带宽?
3、如何限制迁移过程中使用的带宽?
4、迁移过程中,哪些文件可能发生删除,新增数据的情况?哪些目录可能会发生新增文件的情况?
5、迁移后的数据一致性校验怎么做?
6、迁移后的HDFS文件权限如何跟老集群保持一致?
7、如果集群开启安全认证(Kerberos)如何迁移?
2.迁移方案
1.迁移数据量评估
通过 hdfs dfs -du -h /
命令查看各目录总数据量。按业务划分,统计各业务数据总量。
2.制定迁移节奏
由于数据量大,带宽有限,HDFS 中的文件每天随业务不断变化,所以在文件变化之前全部迁移完成是不现实的。建议 按业务、分目录、分批迁移。
3.迁移工具选择
使用 Hadoop 自带数据迁移工具 Distcp,只需要简单的命令即可完成数据迁移。
命令示意:hadoop distcp hdfs://nn1:8020/data hdfs://nn2:8020/
4.迁移时间评估
由于老集群每天仍然在使用,为了减小对线上业务的影响,尽量选择老集群低负载运行的时间段来进行数据迁移。
5.对新老集群之间的网络进行硬件改造
咨询运维同事,新老集群之间的最大传输带宽是多少,如果带宽跑满的话会不会影响线上其他业务。
能否对新老集群之间的网络进行硬件改造,例如通过新老集群之间搭网线的方式来提升网络传输的带宽并消除对其他线上业务的影响。
6.数据迁移状况评估
在完成上面所有准备之后,先尝试进行小数据量的迁移,可以先进行100G的数据迁移、500G的数据迁移、1T的数据迁移,以评估数据迁移速率并收集迁移过程中遇到的问题。
7、如果集群开启Kerberos认证
如果允许,在迁移之前对两个集群之间做Kerberos互信。
3.迁移工具Distcp
工具使用很简单,只需要执行简单的命令即可开始数据迁移,可选参数如下:
hadoop distcp 源HDFS文件路径 目标HDFS文件路径
hadoop distcp hdfs://nn1:8020/data hdfs://nn2:8020/
1.Distcp的原理是什么?
Distcp的本质是一个MapReduce任务,只有Map阶段,没有Reduce阶段,具备分布式执行的特性。在Map任务中从老集群读取数据,然后写入新集群,以此来完成数据迁移。
2.迁移期间新老两个集群的资源消耗是怎样的?
Distcp是一个MapReduce任务,如果在新集群上执行就向新集群的Yarn申请资源,老集群只有数据读取和网络传输的消耗。一般执行数据迁移时,由于新集群不承担任务运行,都会在新集群上执行迁移命令。
3.如何提高数据迁移速度?
Distcp提供了 -m 参数来设置map任务的最大数量(默认20),以提高并发性。注意这里要结合最大网络传输速率来设置。
4.带宽如何限制?
Distcp提供了-bandwidth 参数来控制单个Map任务的最大带宽,单位是MB。
5.迁移之后的数据一致性怎么校验?
Distcp负责进行CRC校验,可以通过-skipcrccheck参数来跳过校验来提供性能。
6.迁移之后的文件权限是怎样的?
Distcp提供了-p 参数来在新集群里保留状态(rbugpcaxt)(复制,块大小,用户,组,权限,校验和类型,ACL,XATTR,时间戳)。如果没有指定-p 参数,权限是执行MapReduce任务的用户权限,迁移完成以后需要手动执行chown命令变更。
7.迁移的过程中老集群目录新增了文件,删除了文件怎么办?
把握好迁移节奏,尽量避免这些情况的出现。Distcp在任务启动的时候就会将需要copy的文件列表从源HDFS读取出来。如果迁移期间新增了文件,新增的文件会被漏掉。删除文件会导致改文件copy失败,可以通过 -i 参数忽略失败。
8.迁移中遇到文件已存在的情况怎么办?
Distcp提供了-overwrite 参数来覆盖已存在的文件。
9.迁移了一半,任务失败了怎么办?
删除掉新集群中的脏数据,重新执行迁移命令。不加-overwrite参数,来跳过已存在的文件。
10.遇到需要对一个文件增量同步怎么办?
Distcp提供-append参数将源HDFS文件的数据新增进去而不是覆盖它。
4.Kerberos互信
参考:Ambari2.7.3+HDP3.1.0配置Kerberos互信
5.数据快照
如果HDFS数据迁移文件时刻变化,比如说Hive外表做数据迁移,当Hive外表实时写入时,对应HDFS的数据文件时刻变化,此时再做数据迁移,就需要对数据做快照,然后使用 Distcp 命令进行数据迁移。其余雷同,涉及到HDFS文件时刻变化的, 都需要先做快照,再迁移。
数据快照相关操作命令如下(注意:必须使用超级管理员hdfs用户):
# 启用快照:
[hdfs@manager ~]$ hdfs dfsadmin -allowSnapshot /tmp
Allowing snapshot on /tmp succeeded
# 创建快照
[hdfs@manager ~]$ hdfs dfs -createSnapshot /tmp snapshot_1
Created snapshot /tmp/.snapshot/snapshot_1
# 查看快照
[hdfs@manager ~]$ hdfs dfs -ls /tmp/.snapshot
Found 1 items
drwxrwxrwx - hdfs hdfs 0 2021-07-14 16:34 /tmp/.snapshot/snapshot_1
# 重命名快照
[hdfs@manager ~]$ hdfs dfs -renameSnapshot /tmp snapshot_1 snapshot_2
[hdfs@manager ~]$ hdfs dfs -ls /tmp/.snapshot
Found 1 items
drwxrwxrwx - hdfs hdfs 0 2021-07-14 16:34 /tmp/.snapshot/snapshot_2
# 删除快照
[hdfs@manager ~]$ hdfs dfs -deleteSnapshot /tmp snapshot_2
6.Distcp迁移
前提条件:迁移数据时的用户,需要在clusterA和clusterB集群都有对应的权限。
本次迁移示例,数据文件不再变化,不需要生成快照。
hadoop distcp \
-Dmapreduce.job.hdfs-servers.token-renewal.exclude=clusterA \ # 失败IP或者修改为hostname
-Dmapred.job.queue.name=default \ # 指定运行迁移命令的队列
-Dmapreduce.map.memory.mb=4096 \ # Map Container 的内存上限
-Dmapred.map.max.attempts=5 \ # 每个mapTask最大尝试次数
-numListstatusThreads 20 \ # 用于构建文件清单的线程数(最多40个)
-bandwidth=200 \ # 以MB为单位指定每个映射的带宽
-m 600 \ # map 最大数量
-prbugpcaxt \ # 保留属性复制数,块大小,用户,组,权限,校验和类型、ACL、XATTR,修改和访问时间
-i \ # 忽略失败的task
-skipcrccheck \ # 忽略CRC校验(防止源,目标集群hdfs版本不一致导致任务失败)
-log /tmp/20210714 \ # 保存distcp执行日志的路径(默认HDFS路径)
hdfs://clusterA:8020/AAA/data \ # 源地址
hdfs://clusterB:8020/BBB/data # 目标地址
# 如果想通过后台命令执行
nohup time hadoop distcp \
-Dmapreduce.job.hdfs-servers.token-renewal.exclude=manager.insight.com \
-Dmapred.job.queue.name=default \
-Dmapreduce.map.memory.mb=4096 \
-Dmapred.map.max.attempts=5 \
-numListstatusThreads 20 \
-bandwidth=200 \
-m 600 \
-prbugpcaxt \
-i \
-skipcrccheck \
-log /tmp/2021071410 \
hdfs://manager.insight.com:8020/distcpdir \
hdfs://manager.inspur.com:8020/ \
>> /root/distcp.log 2>&1 &
# 查看命令
jobs