关于sqoop --split-by 及 -m的理解

本文探讨了使用 Sqoop 导入数据到 Hive 时遇到的一个常见问题:数据量异常放大,具体表现为源数据表中的一条记录在目标表中被重复多次。文章详细分析了该现象的原因,并给出了两种解决方案,一种是调整 split-by 参数配置,另一种是通过限制 map 任务数量来规避此问题。
部署运行你感兴趣的模型镜像
场景:

sqoop import --connect jdbc:postgresql://...../..... --username ....  --query "select * from retail_tb_order_qiulp_test where status = 'TRADE_FINISHED' or status = 'TRADE_CLOSED' or status = 'TRADE_CLOSED_BY_TAOBAO' and \$CONDITIONS"  --hive-import -m 6 --hive-table custom_analyse_db.retail_tb_order_main --hive-overwrite --hive-partition-key part --hive-partition-value qiulp --target-dir /user/qiulp/test1 --split-by tid
注意红色字体部分, retail_tb_order_qiulp_test表原有1000条数据,导入hive后成了6000条,是map的倍数关系。
如下图,一条数据在hive中有6条相同的数据:

理解
1.split-by 根据不同的参数类型有不同的切分方法,如int型,Sqoop会取最大和最小split-by字段值,然后根据传入的num-mappers来 确定划分几个区域。比如select max(split_by),min(split-by) from得到的max(split-by)和min(split-by)分别为1000和1,而num-mappers(-m)为2的话,则会分成两个区域 (1,500)和(501-1000),同时也会分成2个sql给2个map去进行导入操作,分别为select XXX from table where split-by>=1 and split-by<500和select XXX from table where split-by>=501 and split-by<=1000.最后每个map各自获取各自SQL中的数据进行导入工作。

2.当split-by不是int型时出现如上场景中的问题。目前想到的解决办法是:将-m 设置称1,split-by不设置,即只有一个map运行,缺点是不能并行map录入数据。(注意,当-m 设置的值大于1时,split-by必须设置字段)

3.split-by即便是int型,若不是连续有规律递增的话,各个map分配的数据是不均衡的,可能会有些map很忙,有些map几乎没有数据处理的情况
  • 大小: 185.4 KB

您可能感兴趣的与本文相关的镜像

Kotaemon

Kotaemon

AI应用

Kotaemon 是由Cinnamon 开发的开源项目,是一个RAG UI页面,主要面向DocQA的终端用户和构建自己RAG pipeline

03-30
<think>好的,用户的问题是关于如何将MySQL数据导入到HDFS中,并且有特定的要求。让我先仔细看一下他们的需求。 首先,用户提供的示例中有三个不同的导入方式,分别是简单导入、指定目录和指定查询。现在他们的编程要求是需要将hdfsdb数据库中的学生姓名和年龄导入到HDFS的指定目录/user/root/hdfsdb3,使用一个MapReduce任务,并且字段以-分隔。同时,他们可能还参考了之前的例子,需要注意语法是否正确。 我需要回忆Sqoop命令的各个参数。根据用户提供的例子,当使用--query时,必须包含where $CONDITIONS,并且如果指定了-m 1,可能不需要split by,因为只有一个mapper。另外,字段分隔符使用--fields-terminated-by参数,这里应该设为'-'。 用户可能需要注意的几个点:数据库连接是否正确,用户名密码是否正确,表名是否正确,查询的字段是否存在,以及HDFS目录是否有写入权限。此外,如果表没有主键,可能需要添加--split-by或者强制使用-m 1,这里用户已经指定了-m 1,所以没问题。 现在需要组合这些参数。命令结构应该是这样的:sqoop import加上连接信息,然后--query指定查询语句,注意where $CONDITIONS的存在,--target-dir指定目录,-m 1设置mapper数量,--fields-terminated-by设置分隔符。另外,可能需要检查是否有其他需要的参数,比如是否要删除目标目录,但用户的需求中没有提到,所以可以暂时忽略。 可能的错误点包括:忘记添加$CONDITIONS,或者在查询语句中没有正确使用引号。需要确保SQL语句用单引号包裹,并且$CONDITIONS是必要的。此外,字段名是否正确,比如学生姓名和年龄对应的列名是否是stu_name和age,可能需要用户确认,但根据前面的例子,可能列名是正确的。 综上所述,正确的命令应该包括这些部分:连接字符串、用户名密码、--query参数、target目录、字段分隔符、mapper数量。然后给出示例命令,并解释每个参数的作用,确保用户理解每个部分的意义。</think>以下是满足编程要求的Sqoop导入命令及分步说明: ```bash sqoop import \ --connect jdbc:mysql://127.0.0.1:3306/hdfsdb \ --username root \ --password 123123 \ --query 'SELECT stu_name, age FROM student WHERE $CONDITIONS' \ --target-dir /user/root/hdfsdb3 \ --fields-terminated-by '-' \ -m 1 ``` **参数解析:** 1. `--connect`:指定MySQL数据库连接地址,格式为$jdbc:mysql://主机:端口/数据库$[^3] 2. `--username`/`--password`:数据库认证凭据 3. `--query`:自定义查询语句,必须包含$WHERE $CONDITIONS$占位符[^2] 4. `--target-dir`:指定HDFS存储路径$"/user/root/hdfsdb3"$ 5. `--fields-terminated-by`:设置字段分隔符为短横线$"-"$ 6. `-m 1`:指定使用1个MapTask,避免并行处理导致数据分割问题[^1] **验证操作:** ```bash hdfs dfs -ls /user/root/hdfsdb3 hdfs dfs -cat /user/root/hdfsdb3/part-m-00000 ``` **注意事项:** - 若表无主键必须通过`-m 1`禁用并行导入 - 查询语句必须使用单引号包裹,确保$CONDITIONS占位符不被解析[^4] - 字段名需与数据库表实际列名严格匹配
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值