(课堂笔记)数据迁移(Sqoop迁移)Sqoop = 关系型数据库 ↔ Hadoop 的数据传输工具

本文系统梳理了数据迁移的核心知识与实践方法。


主要内容包括:

1)数据迁移概念(类比搬家过程)及应用场景(国产化替代、数仓建设等);

2)标准化三步流程:模型迁移(注意数据类型/分区差异)、数据迁移(Shell/Sqoop两种方式)、数据验证(4维度校验);

3)重点工具Sqoop的实战指南(参数详解、并行原理、批量脚本);

4)完整的数据验证方案(行数比对、MD5校验等);

5)面试高频问题解析。


文章提供可操作的练习任务,强调迁移过程中数据类型转换、并行优化和严格验证的重要性,适合开发者快速掌握这一关键技术。

这是非常实用的数据迁移 笔记,我帮你重新梳理优化,让你理解为什么做、怎么做、注意事项


这个知识点在面试和实际项目中都非常重要。


📚 数据迁移 笔记优化版


一、什么是数据迁移?(一句话理解)

数据迁移 = 把老系统的数据&脚本搬到新平台

通俗类比:

  • 你家搬新房:旧家具→打包→运输→搬到新家→摆放整齐

  • 数据迁移:旧库数据→抽取→转换→写入新库→验证正确


二、为什么要做数据迁移?(背景)

2.1 国产化替代(你笔记里提到的)

text

复制代码
美国限制高科技产品出口
       ↓
国内企业不能用Oracle/IBM等商业软件
       ↓
必须换成国产数据库(华为GaussDB、阿里OceanBase、TiDB等)
       ↓
需要把老系统数据迁移到新平台

2.2 其他场景

场景 说明
数仓建设 业务库 → 数仓ODS层
技术升级 Hadoop 2.x → 3.x
云迁移 自建机房 → 阿里云/腾讯云
合并拆分 公司合并,数据整合

三、数据迁移三步走(核心框架)

text

复制代码
第1步:模型迁移(建表)
    ↓
第2步:历史数据及脚本迁移(导数据)
    ↓
第3步:数据验证(对账)

3.1 模型迁移(表迁移)

做什么: 在目标库创建同等结构的表

注意点:

注意点 说明 例子
数据类型差异 不同数据库类型不同 MySQL的INT → Hive的INT Oracle的NUMBER → Hive的DECIMAL
分区/分桶 Hive特有的优化手段 按日期分区:PARTITIONED BY (dt STRING)
存储格式 不同格式性能不同 文本格式 → Parquet/ORC(列式存储)
字符集 避免中文乱码 统一用UTF-8

示例:MySQL → Hive 数据类型映射

MySQL类型 Hive类型 注意
INT INT 直接对应
BIGINT BIGINT 直接对应
VARCHAR(n) STRING Hive用STRING
DATETIME STRING 存成字符串,或用TIMESTAMP
DECIMAL(10,2) DECIMAL(10,2) 保持一致

3.2 历史数据及脚本迁移

做什么:

  1. 把老数据导出来,导进新库

  2. 把ETL脚本重写(适配新平台)

注意点:

注意点 说明 解决方案
字符集编码 避免乱码 统一UTF-8,导出时指定字符集
迁移效率 数据量大时很慢 用Sqoop/DataX并行迁移,分配资源
脚本逻辑 SQL方言不同 Oracle PL/SQL → Hive SQL重写

3.3 数据验证(最重要!)

做什么: 确保迁移后的数据准确无误

验证维度:

text

复制代码
维度1:行数验证
   源表行数 == 目标表行数

维度2:内容验证
   抽样对比数据内容是否一致

维度3:关键指标验证
   SUM(金额)、COUNT(DISTINCT 用户) 等指标对比

维度4:业务逻辑验证
   跑几个业务SQL,看结果是否一致

四、数据迁移两种方式对比

方式 工具 适用场景 优点 缺点
Shell脚本 MySQL + Hive命令 小数据量、简单迁移 灵活、可控 慢、不支持并行
ETL工具 Sqoop、DataX 大数据量、生产环境 快、支持并行、断点续传 需要学习工具

五、方式一:Shell脚本迁移(你笔记里的)

5.1 完整流程解析

bash

复制代码
#!/bin/bash

#### Step 1:在目标库建表
hive -e "
use a2608;
drop table if exists hive_chongzhi;
create table hive_chongzhi(
    id int,
    ename string,
    amount int,
    dt string
)
row format delimited fields terminated by '\t'   # 字段分隔符
"

#### Step 2:获取源端数据到中间文件
mkdir -p /home/hadoop/2608/test

# 导出MySQL数据,去掉表头
mysql -e "select * from lee.t_chongzhi order by id" > /home/hadoop/2608/test/data
sed -i '1d' /home/hadoop/2608/test/data   # 删除第一行(列名)

#### Step 3:加载数据到Hive
hive -e "
use a2608;
load data local inpath '/home/hadoop/2608/test/data' into table hive_chongzhi
"

#### Step 4:数据校验
# 4.1 导出Hive数据
rm -rf /home/hadoop/2608/test/data_bak
hadoop fs -get '/user/hive/warehouse/a2608.db/hive_chongzhi/data' '/home/hadoop/2608/test/data_bak'

# 4.2 行数对比
lin_1=$(cat /home/hadoop/2608/test/data | wc -l)
lin_2=$(cat /home/hadoop/2608/test/data_bak | wc -l)

if [ $lin_1 -eq $lin_2 ]; then
    echo "hive 表数据行数跟 mysql 表数据行数一致!"
fi

# 4.3 随机抽样10条对比内容
flag=0
for((i=1;i<=10;i++)); do
    x=$[$RANDOM % $lin_1 + 1]  # 随机行号
    con_1=$(cat /home/hadoop/2608/test/data | head -$x | tail -1)
    con_2=$(cat /home/hadoop/2608/test/data_bak | head -$x | tail -1)
    
    if [ "$con_1" != "$con_2" ]; then
        flag=1
    fi
done

if [ $flag -eq 0 ]; then
    echo "源库跟目标库抽样对比无差异!"
else
    echo "数据比对有问题,请检查"
fi

5.2 这个脚本的问题(面试可以说)

问题 说明 改进方案
全量导出到本地 数据量大时磁盘爆了 用Sqoop直接导入HDFS
单线程 速度慢 用Sqoop的-m参数并行
随机抽样不严谨 可能漏掉问题数据 全量MD5比对或用工具

六、方式二:Sqoop迁移(生产推荐)

6.1 Sqoop是什么?

Sqoop = 关系型数据库 ↔ Hadoop 的数据传输工具

text

复制代码
MySQL/Oracle/PostgreSQL ←→ Sqoop ←→ HDFS/Hive/HBase

6.2 单表迁移示例

bash

复制代码
sqoop import \
--connect jdbc:mysql://192.168.5.100:3306/lee \
--username root \
--password 123456 \
--table emp \
--fields-terminated-by "\t" \
--lines-terminated-by "\n" \
--hive-import \
--hive-overwrite \
--create-hive-table \
--delete-target-dir \
--hive-database a2608 \
--hive-table hive_emp \
-m 1

6.3 参数详解(背下来)

参数 作用 例子
--connect 数据库连接URL jdbc:mysql://ip:3306/db
--username 用户名 root
--password 密码 123456
--table 要导入的表 emp
--fields-terminated-by 列分隔符 "\t"(制表符)
--hive-import 导入到Hive 不加则导入HDFS
--hive-overwrite 覆盖已有数据 慎用!
--create-hive-table 自动创建Hive表 会自动映射类型
--hive-database Hive数据库名 a2608
--hive-table Hive表名 hive_emp
-m 并行度 -m 4(4个并发)

6.4 并行迁移原理

bash

复制代码
# 指定主键和并行度
sqoop import \
--connect jdbc:mysql://... \
--table emp \
--split-by id \        # 按id字段切分
-m 4                    # 4个并发

# Sqoop会生成4个查询:
# SELECT * FROM emp WHERE id >= 1 AND id < 2500
# SELECT * FROM emp WHERE id >= 2500 AND id < 5000
# SELECT * FROM emp WHERE id >= 5000 AND id < 7500
# SELECT * FROM emp WHERE id >= 7500 AND id <= 10000

6.5 批量迁移所有表

bash

复制代码
#!/bin/bash

# 获取MySQL中所有表名
mysql -e "use lee;show tables;" | grep -v "Tables_in_lee" | while read line;
do
    sqoop import \
    --connect jdbc:mysql://192.168.5.100:3306/lee \
    --username root \
    --password 123456 \
    --table $line \
    --fields-terminated-by "\t" \
    --hive-import \
    --hive-overwrite \
    --create-hive-table \
    --delete-target-dir \
    --hive-database a2608 \
    --hive-table hive__${line} \   # 加前缀
    -m 1
done

七、数据验证的完整方案

7.1 行数验证(最简单)

sql

复制代码
-- MySQL
SELECT COUNT(*) FROM t_chongzhi;

-- Hive
SELECT COUNT(*) FROM hive_chongzhi;

7.2 关键指标验证

sql

复制代码
-- 验证金额总和
-- MySQL
SELECT SUM(amount) FROM t_chongzhi;

-- Hive
SELECT SUM(amount) FROM hive_chongzhi;

-- 验证唯一值数量
SELECT COUNT(DISTINCT user_id) FROM t_user;
SELECT COUNT(DISTINCT user_id) FROM hive_user;

7.3 全量MD5验证(最严谨)

bash

复制代码
# 导出MySQL数据并计算MD5
mysql -e "SELECT * FROM t_chongzhi ORDER BY id" > mysql_data.txt
md5sum mysql_data.txt

# 导出Hive数据并计算MD5
hive -e "SELECT * FROM hive_chongzhi ORDER BY id" > hive_data.txt
md5sum hive_data.txt

# 对比两个MD5值

7.4 自动化验证脚本

bash

复制代码
#!/bin/bash

# 配置
MYSQL_TABLE="t_chongzhi"
HIVE_TABLE="hive_chongzhi"
DB="a2608"

# 1. 行数对比
mysql_count=$(mysql -e "SELECT COUNT(*) FROM $MYSQL_TABLE" | tail -1)
hive_count=$(hive -e "SELECT COUNT(*) FROM $DB.$HIVE_TABLE" | tail -1)

if [ $mysql_count -eq $hive_count ]; then
    echo "✅ 行数一致: $mysql_count"
else
    echo "❌ 行数不一致: MySQL=$mysql_count, Hive=$hive_count"
    exit 1
fi

# 2. 金额总和对比
mysql_sum=$(mysql -e "SELECT SUM(amount) FROM $MYSQL_TABLE" | tail -1)
hive_sum=$(hive -e "SELECT SUM(amount) FROM $DB.$HIVE_TABLE" | tail -1)

if [ "$mysql_sum" == "$hive_sum" ]; then
    echo "✅ 金额总和一致: $mysql_sum"
else
    echo "❌ 金额总和不一致: MySQL=$mysql_sum, Hive=$hive_sum"
fi

echo "✅ 数据验证通过"

八、面试重点(背下来)

Q1:你们做过数据迁移吗?怎么做的?

做过。我们当时要把MySQL的业务库迁移到Hive数仓。主要分三步:

  1. 模型迁移:在Hive建同样的表,注意数据类型和分区

  2. 数据迁移:用Sqoop并行导入,设置合理的并行度

  3. 数据验证:对比行数、关键指标、抽样内容

Q2:Sqoop和DataX的区别?

维度 Sqoop DataX
作者 Apache 阿里
支持数据库 多(MySQL/Oracle/PostgreSQL) 更丰富(30+)
性能
社区 活跃 国内活跃

Q3:数据量很大(TB级)怎么迁移?

  1. 用Sqoop并行(-m 参数设置10-20个并发)

  2. 按日期分批迁移(如每天的数据单独迁移)

  3. 避开业务高峰期(凌晨执行)

  4. 用压缩传输(--compress)

Q4:迁移过程中数据不一致怎么办?

  1. 先暂停迁移

  2. 找出不一致的行(用JOIN对比)

  3. 分析原因(类型转换?字符集?)

  4. 修复后重新迁移这部分数据

  5. 全部验证通过后再切换业务

Q5:你们迁移的频次?

历史数据一次性迁移(全量),增量数据按天同步(每天凌晨)


九、你今天必须动手做的练习

练习1:Sqoop单表迁移

bash

复制代码
# 1. 确认MySQL有测试表
mysql -uroot -p123456 -e "SELECT * FROM lee.t_chongzhi"

# 2. 用Sqoop迁移到Hive
sqoop import \
--connect jdbc:mysql://192.168.5.100:3306/lee \
--username root \
--password 123456 \
--table t_chongzhi \
--hive-import \
--hive-database a2608 \
--hive-table hive_chongzhi \
--fields-terminated-by "\t" \
-m 1

# 3. 验证Hive表
hive -e "SELECT * FROM a2608.hive_chongzhi"

练习2:编写验证脚本

bash

复制代码
# 写一个脚本,对比MySQL和Hive的行数
# 提示:用mysql -e 和 hive -e 获取count

练习3:处理增量数据

bash

复制代码
# 假设每天有新数据,怎么只迁移昨天的数据?
# 提示:用--where参数
sqoop import \
  --where "dt = '2025-05-28'" \
  --table t_chongzhi

📌 总结:数据迁移核心要点

text

复制代码
┌─────────────────────────────────────────────┐
│           数据迁移三步走                      │
├─────────────────────────────────────────────┤
│ 1. 模型迁移                                   │
│    → 数据类型、分区、存储格式、字符集           │
├─────────────────────────────────────────────┤
│ 2. 数据迁移                                   │
│    → 小数据:Shell脚本                        │
│    → 大数据:Sqoop/DataX并行                  │
├─────────────────────────────────────────────┤
│ 3. 数据验证                                   │
│    → 行数对比、指标对比、内容抽样、MD5全量      │
└─────────────────────────────────────────────┘

🎯 你现在需要做什么

  1. 确认教室环境:Sqoop是否已安装?

    bash

    复制代码
    which sqoop
    sqoop version
  2. 跑通Sqoop示例 :把MySQL的t_chongzhi表迁移到Hive

  3. 把报错或结果发我,我帮你解决

告诉我:

  • Sqoop命令执行成功了吗?

  • Hive里有数据了吗?

  • 行数对比一致吗?

相关推荐
Irene199115 小时前
Sqoop 快速入门指南(在关系型数据库之间高效批量传输数据)
sqoop
Irene19912 天前
正确停止 Sqoop 任务:yarn application -kill(直接 kill 进程会触发重启,且可能导致状态不一致)
hadoop·sqoop
Irene19914 天前
Sqoop 安装完整教程(基于 WSL2 + Ubuntu 24.04)
hadoop·ubuntu·sqoop
WL_Aurora13 天前
Sqoop数据迁移工具从入门到精通
hive·hadoop·sqoop
snpgroupcn1 个月前
通过退役17套SAP ECC历史系统,降低道达尔能源的SAP数据相关风险
云计算·数据迁移·sap ecc
Navicat中国1 个月前
Navicat 企业版数据传输是否支持达梦 → OceanBase迁移?数据迁移报错
数据库·oceanbase·达梦·navicat·数据迁移·数据传输
张青贤1 个月前
ETCD数据迁移
数据库·etcd·数据迁移·apisix网关
snpgroupcn1 个月前
企业级数据退役!陶氏42TB SAP ERP数据归档
数据迁移·数据归档·sap系统退役
NineData2 个月前
MySQL到StarRocks 同步链路中的建表、DDL 跟随与数据校验
运维·数据库·starrocks·mysql·数据迁移·数据库管理工具·ninedata