Sqoop
是 Apache
基础提供的一种工具,在大数据世界中通常用于异构关系数据库 (RDBMS
) 和 Hadoop 分布式文件系统 (HDFS)
之间的导入-导出数百万条记录
。这种数据传输可能导致不同的加载时间,从几分钟到几个小时不等。此方案是全世界数据工程师在引擎盖下查看微调设置的情况。性能调整
的目标是在更短的时间内加载更多数据,从而提高效率并减少网络超时时数据丢失的机会。
通常,Sqoop 的性能调整可以通过:
控制并行性
控制数据传输过程
控制并行性
Sqoop
适用于在Hadoop
中实现的 MapReduce
编程模型。Sqoop
并行导入大多数关系数据库的数据。每个作业的map
任务数决定了其并行性。通过控制并行性,我们可以处理数据库上的负载,从而处理其性能。以下是 Sqoop
作业中利用并行性的几种方法:
更改mapper的数量
默认情况下,典型的 Sqoop
作业会启动四个mappers
。为了优化性能,将mapper任务(并行进程)增加到整数值 8
或 16
可以显示某些数据库中性能的增强。
通过使用 -m或参数–num-mappers,我们可以在 Sqoop
中设置并行性的程度。例如,将映射器的数量更改为 10:
sqoop import
--connect jdbc:mysql://mysql.example.com/sqoop \
--username sqoop \
--password sqoop \
--table cities \
--num-mappers 10
需要记住的一些事情是,mapper
任务的数量应该小于可能的最大并行数据库连接数。并行性程度的增加应小于 MapReduce
群集中可用的增加程度。
按查询拆分
执行并行导入时,Sqoop
需要一个条件,通过该标准可以拆分工作负载。Sqoop
使用拆分列拆分工作负荷。默认情况下,Sqoop
将标识表中的primary key
(如果存在),并用作拆分列
。从数据库中检索拆分列的低值和高值,并且映射任务对总范围的均匀大小的组件进行操作。
参数根据指定的mapper
数量统一拆分列数据。--split-by
的语法由以下方法提供:
sqoop import
--connect jdbc:mysql://mysql.example.com/sqoop \
--username sqoop \
--password sqoop \
--table cities \
--split-by city_id
控制数据传输过程
提高性能的一个流行方法是管理我们导入和导出数据的方式。以下是几种方法:
批处理
批处理意味着在导出数据时,可以将相关的 SQL
语句分组到批处理中。
JDBC 接口公开了一个 API,用于在具有多个值集的准备语句中执行批处理。使用--batch
参数,Sqoop
可以利用此优势。此 API 存在于所有 JDBC
驱动程序中,因为它是 JDBC 接口所需的。
默认情况下,在 Sqoop
中禁用批处理。使用 --batch
参数启用 JDBC 批处理。
sqoop export
--connect jdbc:mysql://mysql.example.com/sqoop \
--username sqoop \
--password sqoop \
--table cities \
--export-dir /data/cities \
--batch
提取大小
可以一次导入的默认记录数为1000
。可以使用 Fetch
大小参数覆盖这一点,该参数用于指定 Sqoop
一次可以使用以下语法导入的记录数:
sqoop import
--connect jdbc:mysql://mysql.example.com/sqoop \
--username sqoop \
--password sqoop \
--table cities \
--fetch-size=n
其中n表示 Sqoop
一次必须获取的条目数。
根据可用内存和带宽,可以增加提取大小参数的值,即需要读取的数据量。
直接模式
默认情况下,Sqoop
导入过程使用 JDBC
,它提供合理的跨供应商导入通道支持。但是,某些数据库可以通过使用特定于数据库的实用程序实现更高的性能,因为它们经过优化,可提供最佳的传输速度,同时减少数据库服务器的压力。
通过提供--direct
参数,Sqoop
被迫尝试使用直接导入通道。此通道的性能可能高于使用 JDBC
。
sqoop import \
--connect jdbc:mysql://mysql.example.com/sqoop \
--username sqoop \
--password sqoop \
--table cities \
--direct
此快速导入具有多种限制。例如,并非所有数据库都有可用的本机实用程序。此模式并非适用于每个受支持的数据库。
Sqoop
仅对 MySQL
和 PostgreSQL
直接提供支持。
自定义边界查询
如之前所见,通过拆分统一分布数据
以进行导入。如果列具有非均匀值,则如果单独使用拆分参数时未获得所需结果,则可以使用边界查询。
理想情况下,我们使用min(id) 和 max(id) 以及表名配置边界查询参数。
sqoop import \
--connect jdbc:mysql://mysql.example.com/sqoop \
--username sqoop \
--password sqoop \
--query 'SELECT normcities.id, \
countries.country, \
normcities.city \
FROM normcities \
JOIN countries USING(country_id) \
WHERE $CONDITIONS' \
--split-by id \
--target-dir cities \
--boundary-query "select min(id), max(id) from normcities"
此处由 Sqoop
在内部使用,并将展开以选取城市表的最小 ID 和最大 ID 来拆分数据。通过使用自定义值,可以派生高效拆分数据
,从而在一般方面提高性能。$CONDITIONS
结论
性能调整的目标是在不损害资源的情况下实现显著的性能。希望使用上述技术,我们应该能够提高效率,并显著缩短数据传输时间。