sqoop生产常见问题及优化总结

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: sqoop开发中遇见的一些常见问题,供大家参考。

Sqoop作为一种重要的数据同步工具,在大数据中具有重要地位。在前期数仓建设中,尤其是DB库(MySQL)数据同步时,对Sqoop生产中遇到的常见问题进行总结并做好记录以便后续查看。

1、Sqoop 空值问题

Hive中的null在底层是以“\N”来存储,而MySQL中的null在底层就是null,这就导致了两边同步数据时存储不一致问题。Sqoop在同步的时候应该严格保证两端的数据格式、数据类型一致,否则会带来异常。


方法1:依赖自身参数

(1)导出数据时采用--input-null-string和--input-null-non-string两个参数。

(2)导入数据时采用--null-string和--null-non-string。


方法2:建表时修改hive底层存储,修改为''(空字符串)

在hive导出时,给需要导出的表创建一张临时表,该表和Mysql同步的表、字段、类型等严格一致,将需要导出的数据插入到该表中,在建立该临时表的时候将hive中Null底层存储“/N”修改为''(空字符串)。具体可添加下面代码

ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' with serdeproperties('serialization.null.format' = '')

例如:

drop table table_name;


CREATE TABLE IF NOT EXISTS table_name(

id int,

name string)

PARTITIONED BY (`partition_date` string)

ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' with serdeproperties('serialization.null.format' = '')

location 'hdfs://nameservice1/user/hive/warehouse/ods.db/table_name'

;

  • 然后将需要导出的数据插入到该临时表中
  • 最后采用sqoop导出命令将数据导出到Mysql

导入数据同理

我们sqoop导数任务采用的是第二种方案,虽然比较麻烦,但是能够减少sqoop带来的一些不必要的麻烦,而且也比较容易定位问题,逻辑清晰,sqoop导出的时候只需要写基本的导出命令即可,这样sqoop很容易做成一个通用的脚本来调度。


2、Sqoop 数据一致性问题

(1):如在Sqoop在导出到Mysql时,使用4个Map任务,过程中有2个任务失败,那此时MySQL中存储了另外两个Map任务导入的数据,此时运营正好看到了这个报表数据。而开发工程师发现任务失败后,会调试问题并最终将全部数据正确的导入MySQL,那后面老板再次看报表数据,发现本次看到的数据与之前的不一致,这在生产环境是不允许的。这是由于Sqoop将导出过程分解为多个事务,因此失败的导出作业可能会导致将部分数据提交到数据库。 这可能进一步导致后续作业由于某些情况下的插入冲突而失败,或导致其他作业中的重复数据。 您可以通过--staging-table选项指定登台表来解决此问题,该选项充当用于暂存导出数据的辅助表,分阶段数据最终在单个事务中移动到目标表。


--staging-table方式

(建立临时表,通过sqoop导入到临时表,成功之后再把临时表的数据通过事务导入到mysql的业务数据表,Sqoop在导入导出数据时,通过建立临时表可以解决好多问题,所以要学会巧用临时表)使用--staging-table选项,将hdfs中的数据先导入到临时表中,当hdfs中的数据导出成功后,临时表中的数据在一个事务中导出到目标表中(也就是说这个过程要不完全成功,要不完全失败)。为了能够使用staging这个选项,staging表在运行任务前或者是空的,要不就使用clear-staging-table配置,如果staging表中有数据,并且使用了--clear-staging-table选项,sqoop执行导出任务前会删除staging表中所有的数据。

注意–direct导入时staging方式是不可用的,使用了—update-key选项时staging方式也不能用。

sqoop export --connect jdbc:mysql://ip:3306/dabases

--username root  \

--password pwd  \

--table table_name  \

--columns id,name,dt \

--fields-terminated-by "\t"  \

--export-dir "/user/hive/warehouse/db.ods/table_name_${day}"  \

--staging-table table_name_tmp  \

--clear-staging-table  \

--input-null-string '\N' \


3、数据倾斜问题

sqoop的数据分割策略不够优秀导致的数据倾斜:

sqoop 抽数的并行化主要涉及到两个参数:num-mappers:启动N个map来并行导入数据,默认4个;split-by:按照某一列来切分表的工作单元。要避免数据倾斜,对split-by指定字段的要求是int类型同时数据分布均匀,满足这样的要求的表只有极少数的有自增主键的表才能满足。核心思想就是自己生成一个有序且均匀的自增ID,然后作为map的切分轴,这样每个map就可以分到均匀的数据,可以通过设置map的个数来提高吞吐量。

建议:

数据量500w以下使用4个map即可。

数据量500w以上使用8个map即可,太多会对数据库加压,造成其他场景使用性能降低。如果是为了专门导数据,和下游计算的并行度,可以适当调大。

例如:

通常可以指定split-by 对应的自增ID 列,然后使用–num-mappers或者-m指定map的个数,即并发的抽取进程数量。但是有时候会碰到很多的表没有添加自增ID或者,整数型的主键,或者 主键分布不均,反而会拖慢整个job的进程。

  • 根据sqoop源码的设计,我们可以使用–query语句中添加自增ID,作为split-by的参数,与此同时通过设置的自增ID的范围可以设置boundary

代码:

```bash

--query 方式:涉及参数  --query、--split-by、--boundary-query


--query: select col1、 col2、 coln3、 columnN from (select ROWNUM() OVER() AS INC_ID, T.* from table T where xxx )  where $CONDITIONS

--split-by: INC_ID

--boundary-query: select 1 as MIN , sum(1) as MAX from table where xxx

完整语法代码:

password-file通过 echo -n “password content” > passsword-file 方式得到,这样不会包含异常字符。

sqoop import --connect $yourJdbConnectURL  \

--username $yourUserName

--password-file  file;///localpasswordFile  or hdfs relative Path

--query "" \

--split-by "" \

-m 8 \

-boundary-query “select 1 as min , sum(1) as max from table where  xx” \

--other parames

参考链接:sqoop 并行抽取数据,同时解决数据倾斜_bymain的博客-CSDN博客


4、Map task并行度设置大于1的问题

并行度导入数据的 时候 需要指定根据哪个字段进行切分 该字段通常是主键或者是自增长不重复的数值类型字段,否则会报下面的错误。

错误日志:

Import failed: No primary key could be found for table. Please specify one with --split-by or perform a sequential import with ‘-m 1’.

就是说当map task并行度大于1时,下面两个参数要同时使用:

–split-by id指定根据id字段进行切分

–m n指定map并行度n个

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7月前
|
SQL 分布式计算 监控
Sqoop数据迁移工具使用与优化技巧:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入解析Sqoop的使用、优化及面试策略。内容涵盖Sqoop基础,包括安装配置、命令行操作、与Hadoop生态集成和连接器配置。讨论数据迁移优化技巧,如数据切分、压缩编码、转换过滤及性能监控。此外,还涉及面试中对Sqoop与其他ETL工具的对比、实际项目挑战及未来发展趋势的讨论。通过代码示例展示了从MySQL到HDFS的数据迁移。本文旨在帮助读者在面试中展现Sqoop技术实力。
569 2
|
数据采集 SQL 分布式计算
数据处理 、大数据、数据抽取 ETL 工具 DataX 、Kettle、Sqoop
数据处理 、大数据、数据抽取 ETL 工具 DataX 、Kettle、Sqoop
1470 0
|
SQL Oracle 关系型数据库
sqoop的导入导出以及where条件过滤数据导出
sqoop的导入导出以及where条件过滤数据导出
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-21 Sqoop 数据迁移工具 简介与环境配置 云服务器 ETL工具 MySQL与Hive数据互相迁移 导入导出
Hadoop-21 Sqoop 数据迁移工具 简介与环境配置 云服务器 ETL工具 MySQL与Hive数据互相迁移 导入导出
95 3
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
110 0
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
51 0
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
60 0
|
6月前
|
SQL 关系型数据库 MySQL
基于Hive的天气情况大数据分析系统(通过hive进行大数据分析将分析的数据通过sqoop导入到mysql,通过Django基于mysql的数据做可视化)
基于Hive的天气情况大数据分析系统(通过hive进行大数据分析将分析的数据通过sqoop导入到mysql,通过Django基于mysql的数据做可视化)
254 0
|
7月前
|
SQL Java 数据库
Sqoop【付诸实践 02】Sqoop1最新版 全库导入 + 数据过滤 + 字段类型支持 说明及举例代码(query参数及字段类型强制转换)
【2月更文挑战第10天】Sqoop【付诸实践 02】Sqoop1最新版 全库导入 + 数据过滤 + 字段类型支持 说明及举例代码(query参数及字段类型强制转换)
359 0
|
7月前
|
分布式计算 关系型数据库 Hadoop
使用Sqoop将数据从Hadoop导出到关系型数据库
使用Sqoop将数据从Hadoop导出到关系型数据库