如何从mysql把大量数据迁移到hive中

以下是基于实践总结的MySQL大数据量导入Hive的完整方案,涵盖工具选择、操作步骤及优化策略:


🔧 一、核心工具选择

  1. Sqoop(推荐)

    • 优势:Hadoop官方工具,支持增量导入、并行度控制、自动类型映射
    • 适用场景:TB级数据迁移,需精细控制并行任务
    sqoop import --connect jdbc:mysql://ip:3306/db \
      --username root --password 123456 \
      --table orders --hive-import \
      --hive-database ods --hive-table orders \
      --split-by id -m 8  # 按id分区,启动8个Map任务
    
  2. DataX(阿里开源)

    • 优势:网状直连架构(无HDFS中转),支持断点续传
    • 适用场景:实时性要求较高的分钟级同步
    // job.json 配置示例
    "reader": {
      "name": "mysqlreader",
      "parameter": { "username": "root", "password": "xxx", "column": ["*"], ... }
    },
    "writer": {
      "name": "hdfswriter",
      "parameter": {"path": "/user/hive/warehouse/ods.db/orders", "fileType": "orc"...}
    }
    
  3. Spark SQL(编程灵活)

    • 优势:可自定义ETL逻辑,适合复杂清洗场景
     
     // 初始化SparkSession
     val spark = SparkSession.builder()
       .appName("CSV to MySQL")
       .master("local[*]")
       .getOrCreate()
     // 读取CSV文件(含表头,自动推断类型)
     val df = spark.read
       .option("header", "true")
       .option("inferSchema", "true")
       .option("sep", "|@|")  // 关键分隔符配置
       .csv("data/room2_202507020934.csv")
     // MySQL连接配置
     val jdbcUrl = "jdbc:mysql://localhost:3306/hivedata?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8"
     val properties = new java.util.Properties()
     properties.put("user", "root")
     properties.put("password", "123456")
     properties.put("driver", "com.mysql.cj.jdbc.Driver")
     // 写入MySQL(追加模式)
     df.write.mode("append").jdbc(jdbcUrl, "room2", properties)
     spark.stop()
    
    


###  📦 二、全量同步流程
#### 步骤1:Hive建表
```sql
CREATE EXTERNAL TABLE IF NOT EXISTS ods.orders(
 id BIGINT COMMENT '订单ID',
 amount DOUBLE COMMENT '金额'
) PARTITIONED BY (dt STRING)  -- 按天分区
STORED AS ORC LOCATION '/data/orders';  

步骤2:Sqoop全量导入

sqoop import \
  --connect jdbc:mysql://ip:3306/source_db \
  --table orders \
  --hive-import --hive-table ods.orders \
  --hive-partition-key dt --hive-partition-value 20240501  # 指定分区

步骤3:验证数据一致性

-- 对比MySQL与Hive行数
SELECT 'MySQL', COUNT(*) FROM source_db.orders
UNION ALL
SELECT 'Hive', COUNT(*) FROM ods.orders WHERE dt='20240501'; 

🔄 三、增量同步方案

  1. 基于时间戳

    sqoop import \
      --query "SELECT * FROM orders WHERE update_time > '2024-05-01' AND \$CONDITIONS" \
      --incremental lastmodified --check-column update_time --last-value '2024-05-01' 
    
  2. 基于自增ID

    sqoop import \
      --incremental append --check-column id --last-value 1000000 
    
  3. Binlog实时同步(高级)

    • 工具:Canal + Kafka → Spark Streaming → Hive
    • 延迟:秒级,需维护Java堆栈

⚡ 四、性能优化技巧

  1. 并行度控制

    • -m 16:根据集群规模调整Map任务数(避免YARN资源争抢)
    • --split-by created_at:选择高基数字段保证数据均匀
  2. 压缩与存储优化

    --compress --compression-codec org.apache.hadoop.io.compress.SnappyCodec  # 传输压缩
    --hive-drop-import-delims  # 删除MySQL特殊字符避免Hive解析失败
    
  3. 错误容忍机制

    --skip-dist-cache  # 跳过分布式缓存(避免小文件问题)
    --fetch-size 10000  # 每次JDBC读取行数
    

❌ 五、常见问题解决

  1. 中文乱码

    • 在MySQL连接串追加参数:
      jdbc:mysql://ip/db?useUnicode=true&characterEncoding=UTF-8
    • Hive表字符集:ALTER TABLE ods.orders SET SERDEPROPERTIES ('serialization.encoding'='UTF-8');
  2. 数据类型映射异常

    • MySQL的DATETIME → Hive的TIMESTAMP
    • MySQL的TINYINT(1) → Hive的BOOLEAN(需显式转换)
  3. 权限问题

    • 确保Hive服务账号有HDFS写入权限:
      hadoop fs -chmod -R 777 /user/hive/warehouse/ods.db 
      

💡 六、方案选型建议

场景 推荐工具 优势
初次全量导入 (>1TB) Sqoop 分区负载均衡,易监控
增量同步 (延迟小时级) DataX 无中间存储,资源消耗低
实时同步 (秒级延迟) Canal+Spark 端到端低延迟
复杂清洗 Spark SQL 可嵌入Python/Scala代码

💡 终极提示:超10亿数据表建议先按日期分区再分桶,显著提升后续查询性能

posted @ 2025-07-01 22:39  ARYOUOK  阅读(261)  评论(0)    收藏  举报