【问题标题】:Sqoop - Data splittingSqoop - 数据拆分
【发布时间】:2016-08-30 18:07:09
【问题描述】:

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

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

另一个问题是

sqoop 导入 --connect jdbc:mysql://myserver:1202/ --username=u1 --password=p1 --query 'Select * from emp where empid

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

谢谢....

【问题讨论】:

    标签: hadoop sqoop


    【解决方案1】:

    你的理解有些差距。

    首先,并行度由-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 列并使用查询找到它的 ma​​xmin 值:

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

    看到它用(1 = 1) 替换了$CONDITIONS

    在我们的例子中,最小值、最大值是 1 和 100。

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

    使用下限“empId >= 1”和上限“empId

    使用下限“empId >= 25”和上限“empId

    使用下限“empId >= 50”和上限“empId

    使用下限 'empId >= 75' 和上限 'empId

    现在$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 个问题。如果我理解正确并且查询的条件类似于 empid
    • @Ajay 你可以给--split-by 中的任何列(不一定是主键)。但建议使用非字符串列。
    • 感谢开发者......真的很有帮助。我们可以使用这个语句导入数据Select deptid, avg(salary) from emp group by deptid 吗?如果值不统一,sqoop 如何将工作平均分配给所有映射器?
    • @Ajay 它将简单地将查询分成几部分(根据映射器的数量)。某些映射器可能不携带任何数据。为了获得良好的效率,按列拆分应该是均匀的。
    • @Ajay 当 sqoop 想要获取元数据时,这很简单,它会在此处触发像 select deptid, avg(salary) from emp group by deptid where (1 = 0) 这样的查询,其中 1=0 为 false,因此不会获取任何记录,而只会获取 元数据。当它需要获取所有记录时,它会输入1=1,这是真的,所以所有记录都会被获取
    【解决方案2】:

    您的查询“Select * from emp where empid

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-12
      • 1970-01-01
      • 2023-01-27
      • 2021-05-11
      • 2014-01-13
      • 2019-06-10
      • 2013-02-05
      • 2020-02-23
      相关资源
      最近更新 更多