Sqoop - 数据分割

时间:2016-05-05 04:27:48

标签: hadoop sqoop

Sqoop能够使用--query子句从多个表中导入数据,但不清楚它是否能够在查询之下导入。

  

从deptid的emp group中选择deptid,avg(salary)

另一个问题是

  

sqoop import --connect jdbc:mysql:// myserver:1202 / --username = u1   --password = p1 --query'选择* from emp where empid< 1123和$ CONDITIONS' - split-by empid --target-dir / uname / emp / salary

$ CONDITIONS和split-by用于执行并行处理,或者我们可以说有效地导入数据。以前根据条件拆分行,然后在主键上使用最小和最大逻辑。这两个($CONDITIONS, split-by)之间有什么区别。如果我们在同一个sqoop语句中使用两者,哪个子句会获得优先级?

...谢谢

2 个答案:

答案 0 :(得分:7)

你的理解存在一些差距。

首先,并行度由-m <n>--num-mappers <n>控制。默认情况下,--num-mappers的值为4。

其次,--split-by <column-name>将根据列名分割您的任务。

第三,$CONDITIONS,sqoop在内部使用它来实现这个分裂任务。

示例,您触发了一个查询:

sqoop import --connect jdbc:mysql://myserver:1202/ --username u1 --password p1 --query 'select * from emp where $CONDITIONS' --split-by empId --target-dir /temp/emp -m 4

说,我的empId从1- 100统一分发。

现在,sqoop将使用--split-by列,并使用查询找到 max min 值:

  

SELECT MIN(empId), MAX(empId) FROM (Select * From emp WHERE (1 = 1) ) t1

$CONDITIONS替换为(1 = 1)

在我们的例子中,min,max值为1和100。

由于映射器数量为4,sqoop将我的查询分为4个部分。

  

使用下限'empId&gt; = 1'和上限'empId&lt;创建输入拆分25'

     

使用下限'empId&gt; = 25'和上限'empId&lt;创建输入拆分50'

     

使用下限'empId&gt; = 50'和上限'empId&lt;创建输入拆分75'

     

使用下限'empId&gt; = 75'和上限'empId&lt; = 100'创建输入拆分

现在$CONDITIONS将再次出现。它被上面的范围查询所取代。

第一个映射器会像这样触发查询:

  

Select * From emp WHERE empId >= 25' AND 'empId < 50

以及其他3位地图制作者。

聚合所有映射器的结果并将其写入最终的HDFS目录。

关于您的查询:

select deptid, avg(salary) from emp group by deptid

您将指定

  

--query 'select deptid, avg(salary) from emp group by deptid where $CONDITIONS'

它将首先转换为

  

select deptid, avg(salary) from emp group by deptid where (1 = 0)

获取列元数据。

我相信这个查询不会在RDBMS中运行。在Mysql中直接尝试以上查询(拥有Where (1 = 0) )。

因此,您将无法使用此查询来使用Sqoop获取数据。

Sqoop用于更简单的SQL查询。

答案 1 :(得分:1)

您的查询,'选择* from emp where empid&lt; 1123和$ CONDITIONS'非常适合将数据从RDBMS导入HDFS。

即使$ CONDITIONS在where子句中首先计算为1 = 0,如果在控制台上看到Sqoop导入日志,您实际上会看到另一个SQL Val边界查询正在替换$ CONDITIONS,其中1 = 1将传递查询因此可以导入数据。

请注意,Sqoop CAN甚至可以导入像连接这样的中等复杂SQL查询。我不确定它是否可以支持高度复杂的SQL查询,因为我自己没有测试过它。