import工具从RDBMS向HDFS导入单独的表。表格中的每一行都表示为HDFS中的单独记录。记录能够存储为文本文件(每行一个记录),或以Avro或SequenceFiles的二进制表示形式存储。java
$ sqoop-import (generic-args) (import-args)
Hadoop的通用参数必须在前,然后是导入参数,导入参数的顺序随意。mysql
如下是链接数据库的相应参数:算法
--connect <jdbc-uri>:指定JDBC链接字符串。 --connection-manager <class-name>:指定要使用的链接管理器类。 --driver <class-name>:手动指定要使用的JDBC驱动程序类。 --hadoop-mapred-home <dir>:覆盖$ HADOOP_MAPRED_HOME--help打印使用说明。 --password-file:为包含认证密码的文件设置路径。 -P:从控制台读取密码。 --password <password>:设置验证密码。 --username <username>:设置验证用户名。 --verbose:在控制台打印更多信息。 --connection-param-file <filename>:提供链接参数的可选属性文件。 --relaxed-isolation:将链接事务隔离设置为对映射器未提交的读取。
如下是安全验证参数:sql
--validate:启用对复制数据的验证,仅支持单个表复制。 --validator <class-name>:指定要使用的验证程序类。 --validation-threshold <class-name>:指定要使用的验证阈值类。 --validation-failurehandler <class-name>:指定要使用的验证失败处理程序类。
如下是Sqoop在导入数据时,可选的控制导入数据内容的参数:shell
--append:将数据追加到HDFS中的现有数据集。 --as-avrodatafile:将数据导入Avro数据文件。 --as-sequencefile:将数据导入到SequenceFiles。 --as-textfile:以纯文本形式导入数据(Sqoop导入的默认方式)。 --as-parquetfile:将数据导入Parquet文件。 --boundary-query <statement>:边界查询用于建立分割。 --columns <col,col,col…>:从表中选择要导入列。 --delete-target-dir:删除导入目标目录(若是存在)。 --direct:若是数据库存在,则使用直接链接器。 --fetch-size <n>:一次从数据库读取的条目数。 --inline-lob-limit <n>:设置内联LOB的最大大小。 -m,--num-mappers <n>:使用n个map任务执行导入。 -e,--query <statement>:导入结果statement。 --split-by <column-name>:用于分割表单元的表格列。不能与--autoreset-to-one-mapper选项一块儿使用 。 --split-limit <n>:每一个拆分大小的上限。这仅适用于整数和日期列。对于日期或时间戳字段,它以秒计算。 --autoreset-to-one-mapper:若是表中没有主键而且没有提供分割列,导入应该使用一个mapper。不能与--split-by <col>选项一块儿使用。 --table <table-name>:导入的表名。 --target-dir <dir>:目标HDFS目录。 --temporary-rootdir <dir>:导入期间建立的临时文件的HDFS目录(覆盖默认的“_sqoop”)。 --warehouse-dir <dir>:表目的地的HDFS父级目录。 --where <where clause>:在导入过程当中使用WHERE子句。 -z,--compress:启用压缩。 --compression-codec <c>:使用Hadoop编解码器(默认gzip)。 --null-string <null-string>:要为字符串列写入空值的字符串。 --null-non-string <null-string>:要为非字符串列写入空值的字符串。 --null-string和--null-non-string参数都是可选的。若是未指定,那么字符串“null”将被使用。
如下是导入到Hive中时可选的参数:数据库
--hive-home <dir>:覆盖 $HIVE_HOME。 --hive-import:将表导入Hive(若是没有设置,则使用Hive的默认分隔符。) --hive-overwrite:覆盖Hive表中的现有数据。 --create-hive-table:若是设置,那么若是存在目标hivetable,做业将失败。默认状况下,此属性为false。 --hive-table <table-name>:设置导入到Hive时要使用的表名。 --hive-drop-import-delims:导入到Hive时,从字符串字段中删除\n、\r和\01。 --hive-delims-replacement:在导入到Hive时,将字符串字段中的\n、\r和\01替换为用户定义的字符串。 --hive-partition-key:分配到分区的Hive字段的名称。 --hive-partition-value <v>:做为该任务导入到Hive中的分区键的字符串值。 --map-column-hive <map>:覆盖从SQL类型到配置列的Hive类型的默认映射。若是在此参数中指定逗号,请使用URL编码的键和值,例如,使用DECIMAL(1%2C%201)而不是DECIMAL(1,1)。
如下是要导入HBase时可选的参数:apache
--column-family <family>:设置导入的目标列族。 --hbase-create-table:若是指定,则建立缺乏的HBase表。 --hbase-row-key <col>:指定哪一个输入列用做行键若是输入表包含复合键,那么<col>必须以a的形式出现,逗号分隔组合键、列表、属性。 --hbase-table <table-name>:指定要用做目标而不是HDFS的HBase表。 --hbase-bulkload:启用批量加载。
如下是要将数据导入Accumulo时可选的参数:编程
--accumulo-table <table-nam>:指定一个Accumulo表做为导入目标表。 --accumulo-column-family <family>:设置导入的目标列族 --accumulo-create-table:若是指定,则建立没有的Accumulo表。 --accumulo-row-key <col>:指定哪一个输入列用做行键 --accumulo-visibility <vis>:(可选)指定一个可见性标记以应用于插入到Accumulo中的全部行。默认是空字符串。 --accumulo-batch-size <size>:(可选)设置Accumulo写入缓冲区的大小(以字节为单位)。默认值是4MB。 --accumulo-max-latency <ms>:(可选)为Accumulo批处理写入器设置最大等待时间(以毫秒为单位)。缺省值是0。 --accumulo-zookeepers <host:port>:由Accumulo实例使用的Zookeeper服务器的逗号分隔列表。 --accumulo-instance <table-name>:目标Accumulo实例的名称。 --accumulo-user <username> :要导入为的Accumulo用户的名称。 --accumulo-password <password> :Accumulo用户的密码
Sqoop提供了两种文件格式用于存储导入的数据,分别是:分隔文本和SequenceFiles。缓存
分隔文本是默认的导入数据存储格式。也可使用--as-textfile参数显式指定。该方式将每一个基于字符串的表示形式的记录写入分割文件中,在各个行和列之间使用分隔符进行行列的划分。分隔符能够是逗号、制表符或其余字符。如下是基于分割文本导入数据的示例:安全
1,这里是一条消息,2010-05-01 2,新年快乐!,2010-01-01 3,另外一个消息,2009-11-12
分隔文本适用于大多数非二进制数据类型。它也支持其余工具的进一步操做,例如Hive。
SequenceFiles是一种二进制格式,它将单个记录存储在自定义的特定的数据类型记录中。这些数据类型表现为Java类。Sqoop会自动生成这些数据类型。这种格式支持二进制表示中全部数据的准确存储,适用于存储二进制数据(例如,VARBINARY列)或将主要由自定义MapReduce程序操做的数据。从SequenceFiles读取性能高于从文本文件读取数据,由于记录不须要被解析。
Avro数据文件是一种紧凑且高效的二进制格式,可与使用其余编程语言编写的应用程序进行交互操做。Avro还支持版本控制,以便在添加或删除列时,将之前导入的数据文件和新文件一块儿处理。
默认状况下,导入的数据未被压缩。可使用-z或--compress参数的deflate(gzip)算法来压缩数据,或使用--compression-codec参数指定Hadoop压缩编解码器。压缩能够用于SequenceFile,文本和Avro文件。
Sqoop以特定的方式处理大型对象(BLOB和CLOB列)。若是这个数据确实很大,那么这些列不该该像大多数列那样彻底具体化在内存中进行操做。相反,他们的数据是以流的方式处理的。大型对象能够内联存储其他的数据,在这种状况下,在每次访问时它们都彻底物化在内存中,或者它们能够存储在链接到主数据存储的辅助存储文件中。
默认状况下,小于16MB的大对象将内联存储到其余数据中。若是大小较大,则将它们存储在导入目标目录的_lobs子目录中的文件中。这些文件以针对大型记录存储优化的单独格式存储,能够容纳每一个记录最多2^63字节的记录。
lob溢出到单独文件的大小由--inline-lob-limit参数控制,该参数指定要保持内联的最大lob大小(以字节为单位)。若是将内联LOB限制设置为0,则全部大型对象都将放置在外部存储中。
--enclosed-by <char>:设置必需的字段包围字符。 --escaped-by <char>:设置转义字符。 --fields-terminated-by <char>:设置字段分隔符。 --lines-terminated-by <char>:设置行尾字符。 --mysql-delimiters:使用MySQL的默认分隔符集:字段:逗号(,)行:换行(\n)转义:反斜杠(\)包含:单引号(’)。 --optionally-enclosed-by <char>:设置字段包围字符。
导入数据到分隔文本时,分隔符的选择很重要。若是字符串包含的字符中出现了分隔符,那么会致使后续分析过程没法清晰地解析导入的数据。
例如,字符串"Hello, pleased to meet you"不该将字段结尾分隔符设置为逗号。
分隔符能够被指定为:
1.一个字符(--fields-terminated-by X)
2.一个转义字符(--fields-terminated-by \t)。支持的转义字符是:
\b(退格)、\n(新行)、\r(回车)、\t(制表符)、\"(双引号)、\\'(单引号)、\\(反斜杠)、\0(NUL)。
\0(NUL):表示在字段或行之间插入NUL字符,若是使用--enclosed-by、--optionally-enclosed-by或--escaped-by参数能够控制禁用/启用。
3.UTF-8字符代码点的八进制表示。形式为:\0ooo,其中OOO是八进制的值。
例如:--fields-terminated-by \001会产生^A字符。
4.UTF-8字符代码点的十六进制表示。形式为:\0xhhh,其中hhh是十六进制的值。
例如:--fields-terminated-by \0x10会产生回车符。
默认用于字段的分隔符是逗号(,),行数据的分隔符是换行符(\n),不用引号或者转义字符。
注意:若是在导入数据的字段中包含逗号或换行符,会致使数据分割模糊、不可分。为了明确解析,二者都必须启用。例如,经过--mysql-delimiters。
若是没法提供明确的分隔符,请使用包含字符和转义字符。包含字符和转义字符的组合能够明确地解析行。
例如:假设数据集的一列包含如下值:
Some string, with a comma. Another "string with quotes"
如下参数将提供能够明确解析数据的分隔符:
$ sqoop import --fields-terminated-by , --escaped-by \\ --enclosed-by '\"' ...
注意,为了防止shell破坏包含字符,使用单引号将参数值引发来。
以上命令应用于上述数据集的结果是:
"Some string, with a comma.","1","2","3"... "Another \"string with quotes\"","4","5","6"...
这里导入的字符串显示在附加列("1","2","3"等)的上下文中,以演示包含和转义的所有效果。只有在分隔符字符出如今导入的文本中时,包含字符才是必需的。所以能够将包含字符指定为可选:
$ sqoop import --optionally-enclosed-by '\"' (the rest as above)...
导入数据的结果将是如下形式:
"Some string, with a comma.",1,2,3... "Another \"string with quotes\"",4,5,6...
注意:
尽管Hive支持转义字符,但它不能处理换行字符的转义。此外,它不支持将可能包含内联字符串中的字段分隔符的字符括起来的概念。所以,建议您在使用Hive时,选择明确的字段和记录终止分隔符,而不须要转义和包含字符;这是因为Hive的输入解析能力有限。若是将数据导入Hive时不使用--escaped-by,--enclosed-by或--optionally-enclosed-by参数指定分隔符,则Sqoop将报警。
--mysql-delimiters参数是一个简短的参数,它使用mysqldump的默认分隔符。若是将mysqldump分隔符与direct模式(使用--direct)一块儿使用,则能够实现很是快速的导入。
分隔符的选择对于分割文本模式导入重要,使用--as-sequencefile导入到SequenceFiles仍然相关。生成类的toString()方法将使用前面指定的分隔符,所以输出数据的后续格式将依赖于选择的分隔符。
--input-enclosed-by <char>:设置必需的字段封闭器 --input-escaped-by <char>:设置输入转义字符 --input-fields-terminated-by <char>:设置输入字段分隔符 --input-lines-terminated-by <char>:设置输入的行尾字符 --input-optionally-enclosed-by <char>:设置字段包围字符
当Sqoop将数据导入到HDFS时,它会生成一个Java类,它能够从新解释它在进行分隔格式导入时建立的文本文件。分隔符的选择有以下参数:
--fields-terminated-by:此项将控制数据如何写入磁盘,以及生成的parse()方法如何从新解释这些数据。parse()方法使用的分隔符能够独立于输出参数,经过--input-fields-terminated-by来选择。
Sqoop旨在将数据库中的表导入HDFS。
要链接数据库须要使用--connect参数。此参数的值为要链接的数据库的地址,形式和数据库驱动地址同样。
例如:如下是链接MySQL数据库的命令。
$ sqoop import --connect jdbc:mysql://database.example.com/employees
Sqoop支持多种数据库。Sqoop会自动处理以jdbc:mysql://开头的链接字符串。Sqoop也可使用其余JDBC兼容的数据库。
步骤以下:
首先,为要导入的数据库类型下载相应的JDBC驱动的jar包。
而后,将jar包拷贝到$SQOOP_HOME/lib目录中。若是是用RPM或Debian的方式安装的话,目录为:/usr/lib/sqoop/lib。
最后,将数据库驱动类提供给Sqoop的--driver参数,做为此参数的值。
例如:常用的MySQL驱动:com.mysql.jdbc.Driver
$ sqoop import --driver com.mysql.jdbc.Driver \ --connect <connect-string> ...
例如:要链接到SQLServer数据库,首先要下载驱动jar包并将其拷贝到Sqoop lib路径中。而后运行Sqoop。命令以下:
$ sqoop import --driver com.microsoft.jdbc.sqlserver.SQLServerDriver \ --connect <connect-string> ...
使用JDBC链接到数据库时,可使用--connection-param-file选项经过属性文件选择性地指定额外的JDBC参数。这个文件的内容被解析为标准Java属性,并在建立链接时传递给驱动程序。
注意:经过可选属性文件指定的参数仅适用于JDBC链接。任何使用非JDBC链接的快速路径链接器都将忽略这些参数。
--username参数用来提供数据库的用户名。
Sqoop提供了几种不一样的提交密码的方法,下面详细描述数据库提供安全和不安全的密码提交方式。
将密码保存在具备400权限的用户主目录中的文件中,并使用--password-file参数指定该文件的路径,这是输入密码的首选方法。
Sqoop会从文件中读取密码,并使用安全的方式将它传递给MapReduce集群,而没必要在配置中公开密码。包含密码的文件能够位于本地磁盘或HDFS上。
例如:
$ sqoop import --connect jdbc:mysql://database.example.com/employees \ --username venkatesh --password-file ${user.home}/.password
注意:Sqoop将读取密码文件的所有内容用做密码。包括空格字符。须要确保密码文件仅包含属于密码的字符。
在命令行中,可使用echo -n来存储密码,这样将不会产生多余字符。
例如:存储secret为密码,可使用以下命令:
echo -n "secret" > password.file
提供密码的另外一种方式是使用-P参数,它将从控制台提示符处读取密码。
Hadoop 2.6.0提供了一个API来将密码存储与应用程序分开。有一个新的credential命令行工具来管理密码及其别名。密码与其别名一块儿存储在密码保护的密钥库中。密钥库密码能够经过环境变量提供给命令行的密码提示,也能够默认为软件定义的常量。Hadoop文档中有关于此功能的使用说明。
一旦使用Credential Provider工具存储密码而且Hadoop配置已经适当更新后,全部应用程序均可以选择使用别名代替实际密码,并在运行时解析别名以供使用密码。
因为用于存储凭证提供程序的密钥库或相似技术是经过组件共享的,所以各类应用程序,各类数据库和其余密码能够安全地存储在其中,而且只有别名才须要在配置文件中公开,从而保护密码免受可见。
若是Sqoop依赖的Hadoop支持这种功能的话,那么Sqoop也容许使用这种功能。此功能引入了一个新选项--password-alias来在命令行上提供别名,而不是实际的密码。此选项的参数值是与实际密码关联的存储器上的别名。用法示例以下所示:
$ sqoop import --connect jdbc:mysql://database.example.com/employees \ --username dbuser --password-alias mydb.password.alias
若是命令行的首选项不是此选项,则能够将别名保存在--password-file选项提供的文件中。除此以外,Sqoop配置参数org.apache.sqoop.credentials.loader.class应该设置为提供别名解析的类名:org.apache.sqoop.util.password.CredentialProviderPasswordLoader
示例用法以下(假设.password.alias具备真实密码的别名):
$ sqoop import --connect jdbc:mysql://database.example.com/employees \ --username dbuser --password-file ${user.home}/.password-alias
注意:
--password参数是不安全的,由于其余用户可能经过程序的输出从命令行参数中读取密码,密码仍然使用不安全的方式在MapReduce集群的节点之间传输。例如:
$ sqoop import --connect jdbc:mysql://database.example.com/employees \ --username aaron --password 12345
Sqoop一般以表格为单位的方式导入数据。导入的数据各个节点都是可选的,例如要导入的表、表中的字段、表中的数据等等。
--table参数用来选择要导入的表。
例如:--table employees。
该参数还能够标识数据库中的一张表或其余相似表的实体。
默认状况下,表格中的全部列都被选中用于导入。导入的数据以“天然顺序”写入HDFS。
例如:包含列A,B和C的表数据导入结果以下:
A1,B1,C1 A2,B2,C2 ...
导入的列是可选的,使用--columns参数控制列的数量以及排序。使用“,”号进行列分割。
例如:
--columns "name,employee_id,jobtitle"
导入的数据也是可选的,使用--where参数能够附加一个WHERE子句来选择要导入的数据。默认状况下,Sqoop生成表单的语句以下:
SELECT <column list> FROM <table name>
例如:--where "id > 400"。只有列id值大于400的行才会被导入。
默认状况下,sqoop使用select min(<split-by>),max(<split-by>) from <table name>查询找出建立分割的边界。在某些状况下,这个查询不是最优化的,因此可使用--boundary-query参数指定列做为边界。
Sqoop也能够导入任意SQL查询的结果集。除了使用的--table,--columns和--where参数,还能够指定--query的参数,其参数值为简单SQL语句。
导入查询结果集时,必须使用--target-dir参数指定目标目录。
若是要启动多个mapper并行执行导入的话,则每一个mapper都须要执行查询的语句,这样就须要Sqoop推断出每一个进程须要执行的任务边界,那么就须要使用--split-by指定一个列来进行任务边界判断的依据,这个列最好是整数类型并且没有跳跃值的列,这样可使每一个进程可以获得均分的任务。
例如:
$ sqoop import \ --query 'SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS' \ --split-by a.id --target-dir /user/foo/joinresults
或者,查询能够被执行一次并连续导入,方法是指定一个映射任务-m 1:
$ sqoop import \ --query 'SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS' \ -m 1 --target-dir /user/foo/joinresults
注意:
1.若是使用双引号(“)将查询语句引发来的话,则必须使用\$CONDITIONS进行转义,而不是$CONDITIONS, 转义以后shell才会将其视为shell变量。双引号查询语句以下所示:
"SELECT * FROM x WHERE a='foo' AND \$CONDITIONS"
2.在当前版本的Sqoop中使用SQL查询的功能仅限于简单查询,其中不能包含模糊查询和where子句中的OR条件。使用复杂的查询,可能会致使意想不到的结果。
从数据库导入数据的时候可使用-m或--num-mappers参数来增长导入任务的并行。这些参数中的每个参数值都是整数,该值与使用的并行度相对应。默认状况下,使用四个任务。有些数据库可能会经过将此值增长到8或16来提升性能。
注意:
1.不要将并行度提升到大于MapReduce集群中可用的最大数量,若是超过,任务将连续运行,并可能增长执行导入所需的时间。
2.不要将并行度设置的高于数据库能够合理支持的程度。例如:将100个并发客户端链接到数据库可能会增长数据库服务器的负载,从而致使性能受到影响。
在执行并行导入时,Sqoop须要一个能够分割工做负载的标准。Sqoop使用列来分割工做量。默认状况下,Sqoop将识别表中的主键列(若是存在)并将其用做拆分列。分割列的低值和高值从数据库中检索,而且mapper任务在总范围的大小均匀的份量上进行操做。
例如:有一个表的主键列id最小值为0,最大值为1000,而且Sqoop指向使用4个任务,则Sqoop将运行四个进程,每一个进程都执行以下的SQL语句:
SELECT * FROM sometable WHERE id >= lo AND id < hi
每一个mapper任务的(lo, hi)的值分别对应为(0,250),(250,500),(500,750)和(750,1001)。
若是主键的实际值在其范围内不均匀分布,则可能致使任务不平衡。应该明确地选择与--split-by参数不一样的列。
例如,--split-by employee_id。
Sqoop目前不能在多列索引上拆分。若是表格没有索引列,或者有多列键,那么必须手动选择拆分列。
可使用--split-limit参数替换--num-mapers参数。使用--split-limit参数会限制所建立的拆分部分的大小。若是建立的分割大小大于此参数中指定的大小,则分割将根据此限制调整大小,而且分割的数量也根据此 项变化。若是根据--num-mappers参数计算出的分割大小超过了--split-limit参数设置的大小,那么将增长实际的mapper数量。若是--split-limit 参数中指定的值为0或负数,则该参数将被所有忽略,分割大小将根据mapper的数量计算。
若是一个表没有定义主键而且--split-by <col>参数也没有指定,那么导入将会失败,除非使用--num-mappers 1选项或使用--autoreset-to-one-mapper选项将mapper的数量显式设置为1。--autoreset-to-one-mapper选项一般与import-all-tables工具一块儿使用,自动处理没有主键的表。
每次启动Sqoop做业时,Sqoop都会将$ SQOOP_HOME / lib文件夹中的jar包复制到做业缓存中。当由Oozie启动时则不用,由于Oozie使用它本身的Sqoop共享库,它将Sqoop依赖关系保留在分布式缓存中。Oozie将在第一个Sqoop做业期间对Sqoop依赖关系的每一个工做节点执行本地化,并将工做节点上的jar包重用于子做业。
在Oozie启动时使用Sqoop命令中的--skip-dist-cache选项,将跳过Sqoop复制依赖关系到做业缓存并保存大量I/O的步骤。
默认状况下,导入过程将使用供应商提供的JDBC导入通道。一些数据库可使用特定的数据移动工具以更高性能的方式执行导入。
MySQL提供的mysqldump工具能够很是快速地将数据从MySQL导出到其余系统。Sqoop能够经过--direct参数指定该工具导入,比使用JDBC性能更高。
默认状况下,Sqoop将数据导入HDFS中一个名为foo的目录中。
例如,用户名是someuser,则导入工具会将数据写入/user/someuser/foo/(files)中。
可使用--warehouse-dir参数调整导入的这个目录。
例如:
$ sqoop import --connnect <connect-str> --table foo --warehouse-dir /shared
该命令将数据写入目录/shared/foo/目录下的文件中。
能够明确地选择目标目录,以下所示:
$ sqoop import --connnect <connect-str> --table foo --target-dir /dest
上述命令将文件导入到/dest目录中。--target-dir与--warehouse-dir不相容。只能使用二者之一。
使用direct模式时,能够指定应传递给底层工具的其余参数。若是参数--是在命令行上 出现的,则--后的参数将直接发送到底层工具。
例如,如下内容将调整mysqldump使用的字符集:
$ sqoop import --connect jdbc:mysql://server.foo.com/db --table bar \ --direct -- --default-character-set=latin1
默认状况下,数据将导入到新的目标位置。若是目标目录已经存在于HDFS中,Sqoop将拒绝导入并覆盖该目录的内容。
若是使用--append参数,Sqoop会将数据导入临时目录,而后以不与该目录中现有文件名冲突的方式将文件重命名为正常目标目录。
默认状况下,Sqoop在mapper中导入数据使用读提交事务隔离。这可能不是全部ETL工做流程中的理想选择,而且可能但愿减小隔离保证。Sqoop使用--relaxed-isolation选项能够指定读取的事物隔离级别。
--read-uncommitted隔离级别不支持全部数据库(例如Oracle),所以指定选项--relaxed-isolation可能没法在全部数据库的支持。
Sqoop预先配置为将大多数SQL类型映射到适当的Java或Hive类型。默认映射可能并不适合每一个场景,可使用--map-column-java(用于更改映射到Java)或--map-column-hive(用于更改Hive映射)进行更改。
--map-column-java <mapping>:指定已配置列从SQL到Java类型的映射。 --map-column-hive <mapping>:指定从SQL到配置列Hive类型的映射。
Sqoop以<列名称> = <新类型>形式的逗号分隔映射列表。
例如:
$ sqoop import ... --map-column-java id = String,value = Integer
注意:在--map-column-hive选项中须要逗号分割,应使用URL编码的键和值,例如,使用DECIMAL(1%2C%201)而不是DECIMAL(1,1)。若是某些配置的映射不可用,Sqoop会抛出异常。
当sqoop从企业存储导入数据时,表名和列名可能不是有效的Java标识符或Avro/Parquet标识符。为了解决这个问题,sqoop将这些字符翻译为_做为建立的一部分。任何以_(下划线)字符开头的列名将被翻译为具备两个下划线字符。
例如:_AVRO将被转换为__AVRO。
在HCatalog导入的状况下,当映射到HCatalog列时,列名将转换为小写。
Sqoop提供了一种增量导入模式,可用于检索比之前导入的一组行更新的行数据。
如下参数控制增量导入:
--check-column (col):要导入某些行时要检查的列。(该列不能是CHAR/NCHAR/VARCHAR/VARNCHAR/LONGVARCHAR/LONGNVARCHAR类型)。 --incremental (mode):指定Sqoop如何肯定哪些行是新的。此项参数的值有append和lastmodified两个。 --last-value (value):指定先前导入中的检查列的最大值。
Sqoop支持两种方式的增量导入:append和lastmodified。可使用该--incremental参数来指定要执行的增量导入的方式。
append方式在导入表格时,必须指定起始行id列所对应的值。能够经过--check-column指定该行包含的列。Sqoop导入行的检查列的值是否大于--last-value参数指定的值。
Sqoop支持的备用表更新策略称为lastmodified模式。
当源表的行更新时,每次更新都会将最后更新的列的值设置为当前的时间戳,若是行检查的列的时间戳比--last-value指定的时间戳新,那么该行会被导入。
在增量导入结束时,--last-value应为后续导入指定的值打印到屏幕上。在运行后续导入时,--last-value会指定上次的值以确保导入新的数据。这是增量导入自动处理的,这也是执行循环增量导入的首选机制。
Sqoop的导入工具的主要功能是将数据上传到HDFS中的文件中。若是Hive Metastore与HDFS集群相关联,则Sqoop还能够将数据导入到Hive中,并执行CREATE TABLE语句来定义Hive中的数据布局。将数据导入Hive中很是简单,只须要在命令中加入--hive-import参数便可。
若是Hive中表已经存在,可使用--hive-overwrite参数指定要替换表。而后将数据导入HDFS或省略此步骤,Sqoop还将生成一个Hive脚本,其中包含CREATE TABLE语句和LOAD DATA INPATH语句。
脚本将在安装了Sqoop的机器上运行。若是安装了多个Hive,或者没有配置hive的环境变量$PATH,可使用--hive-home参数来指定Hive的安装目录。Sqoop的$PATH通常为:$HIVE_HOME/bin/hive
注意:将数据导入到Hive中不能使用--as-avrodatafile和--assequencefile两种文件的存储方式。
若是数据库的数据内容包含Hive的缺省行分隔符(\n和\r字符)或列分隔符(\01字符)的字符串字段,则使用Sqoop将数据导入到Hive中时会遇到问题。
可使用--hive-drop-import-delims选项在导入时删除这些字符,以保证数据与Hive的文本数据格式兼容。或者,可使用该--hive-delims-replacement选项在导入时将这些字符替换为自定义的字符串,以保证数据与Hive的文本数据格式兼容。
使用Hive的默认分隔符时使用这两个参数。
若是使用--hive-import参数并无设置分隔符,则使用Hive的默认分隔符:字段分隔符为^A,记录分隔符为\n。
Sqoop将默认导入NULL值做为字符串null。Hive使用字符串\N来表示NULL值,所以在将数据导入Hive中时NULL将没法被正确识别。
若是想要在数据导入Hive时正确地处理NULL,可使用参数--null-string和--null-non-string。
若是想要在数据导出Hive时正确的处理NULL,可使用参数--input-null-string和--input-null-non-string。
由于sqoop在生成的代码中须要使用这些参数,因此须要正确地将值转义\N为\\N:
$ sqoop import ... --null-string '\\N' --null-non-string '\\N'
Hive中使用的表名默认状况下与源表的名称相同。也可使用--hive-table选项控制输出表名称。
Hive能够将数据放入分区以提升查询性能。Sqoop能够经过指定--hive-partition-key和--hive-partition-value参数将数据导入Hive的特定分区。分区值必须是一个字符串。有关分区的更多详细信息,请参阅Hive文档。
--compress和--compression-codec选项能够将数据压缩以后导入Hive中。
压缩导入到Hive中的表格的一个缺点是压缩的编码不能切分,从而致使不能并行mapper任务处理。
lzop编解码器支持分割。使用此压缩编解码器导入表格时,Sqoop将根据索引文件自动的对数据进行切分并建立正确的Hive表格式。此功能目前必须使用lzop编解码器对表的全部分区进行压缩。
Sqoop支持HDFS和Hive以外的其余导入目标。Sqoop一样也支持将数据导入HBase中的表中。
若是目标表和列族不存在,则Sqoop做业将退出并显示错误。在运行导入以前,应该建立目标表。
也可使用--hbase-create-table参数,让Sqoop使用HBase配置中的默认参数建立目标表和列族(若是它们不存在)。
--hbase-table参数指定HBase接收数据的表。导入每一行的数据的操做都会转换为HBase Put操做。
每行的行键取自输入的一列,默认状况下,Sqoop将使用分隔列做为行键。若是没有指定分割列,它将使用源表的主键列(若是有的话)做为行键。
--hbase-row-key参数能够指定行键列。
若是导入的表具备联合主键,--hbase-row-key必须以逗号分隔联合主键。在这种状况下,HBase的行键将经过下划线分割联合主键的形式来生成。注意:只有--hbase-row-key在指定了参数的状况下,Sqoop才能正常导入具备联合主键的表。
--column-family参数指定列族,每一个输出列将被放置在同一个列族中。
注意:此参数与direct模式导入(参数--direct)不兼容。
Sqoop将当前全部值序列化为HBase,方法是将每一个字段转换为其字符串表示(就像在文本模式中导入HDFS同样),而后将此字符串的UTF-8字节插入到目标单元格中。Sqoop将跳过除行键列之外的全部列中包含空值的行。
--hbase-bulkload参数能够执行批量加载而不是直接写入,能够减轻HBase的负载。
Sqoop支持将数据导入Accumulo中。
因为本人对Accumulo这项技术不是很了解,此处暂时不作介绍,看官方文档的介绍和HBase差很少,这里只将参数列出,留待之后作补充。
用户能够经过修改配置文件conf/sqoop-site.xml来指定参数。参数能够像Hadoop配置文件中同样指定,例如:
<property> <name>property.name</name> <value>property.value</value> </property>
也能够在命令行中使用通用参数指定,例如:
sqoop import -D property.name = property.value ...
如下应用示例说明如何在各类状况下使用导入工具。
从数据库导入表名为EMPLOYEES的表的数据:
$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES
数据库链接验证:
$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \ --username SomeUser -P Enter password: (hidden)
选择导入的列:
$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \ --columns "employee_id,first_name,last_name,job_title"
控制并行导入(指定8个mappper):
$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \ -m 8
将数据存储在SequenceFiles中,并将生成的类名称设置为com.foocorp.Employee:
$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \ --class-name com.foocorp.Employee --as-sequencefile
指定分隔符:
$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \ --fields-terminated-by '\t' --lines-terminated-by '\n' \ --optionally-enclosed-by '\"'
导入数据到Hive中:
$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \ --hive-import
导入新增数据:
$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \ --where "start_date > '2010-01-01'"
指定分割列:
$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \ --split-by dept_id
验证是否导入成功:
$ hadoop fs -ls EMPLOYEES Found 5 items drwxr-xr-x - someuser somegrp 0 2010-04-27 16:40 /user/someuser/EMPLOYEES/_logs -rw-r--r-- 1 someuser somegrp 2913511 2010-04-27 16:40 /user/someuser/EMPLOYEES/part-m-00000 -rw-r--r-- 1 someuser somegrp 1683938 2010-04-27 16:40 /user/someuser/EMPLOYEES/part-m-00001 -rw-r--r-- 1 someuser somegrp 7245839 2010-04-27 16:40 /user/someuser/EMPLOYEES/part-m-00002 -rw-r--r-- 1 someuser somegrp 7842523 2010-04-27 16:40 /user/someuser/EMPLOYEES/part-m-00003 $ hadoop fs -cat EMPLOYEES/part-m-00000 | head -n 10 0,joe,smith,engineering 1,jane,doe,marketing ...
增量导入:
$ sqoop import --connect jdbc:mysql://db.foo.com/somedb --table sometable \ --where "id > 100000" --target-dir /incremental_dataset --append
使用validation对数据进行验证:
$ sqoop import --connect jdbc:mysql://db.foo.com/corp \ --table EMPLOYEES --validate
将关系型数据库导入数据到HDFS:
sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \ --username root --password 123 --table trade_detail \ --columns 'id, account, income, expenses'
指定输出路径、指定数据分隔符:
sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \ --username root --password 123 --table trade_detail \ --target-dir '/sqoop/td' --fields-terminated-by '\t'
指定Map数量 -m
sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \ --username root --password 123 --table trade_detail \ --target-dir '/sqoop/td1' --fields-terminated-by '\t' -m 2
增长where条件, 注意:条件必须用引号引发来
sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \ --username root --password 123 --table trade_detail \ --where 'id>3' --target-dir '/sqoop/td2'
增长query语句(使用 \ 将语句换行)
sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \ --username root --password 123 \ --query 'SELECT * FROM trade_detail where id > 2 AND $CONDITIONS' \ --split-by trade_detail.id --target-dir '/sqoop/td3'
注意:
若是使用--query这个命令的时候,须要注意的是where后面的参数,AND $CONDITIONS这个参数必须加上,并且存在单引号与双引号的区别,若是--query后面使用的是双引号,那么须要在$CONDITIONS前加上\即\$CONDITIONS。
若是设置map数量为1个时即-m 1,不用加上--split-by ${tablename.column},不然须要加上。
将关系型数据库导入数据到hive:
sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \ --username root --password 123 --table person \ --hive-import --hive-table hivetab1 -m 1
上一篇:Sqoop简介以及安装