sqoop从mysql到hive导入时分隔符问题

核心参数

  • –check-column 
    用来指定一些列,这些列在增量导入时用来检查这些数据是否作为增量数据进行导入,和关系型数据库中的自增字段及时间戳类似. 
    注意:这些被指定的列的类型不能使任意字符类型,如char、varchar等类型都是不可以的,同时–check-column可以去指定多个列
  • –incremental 
    用来指定增量导入的模式,两种模式分别为Append和Lastmodified
  • –last-value 
    指定上一次导入中检查列指定字段最大值

Append模式实战增量导入

执行以下指令先将我们之前的数据导入

 
  1. sqoop import \

  2. --connect jdbc:mysql://master:3306/test \

  3. --username hive \

  4. --password 123456 \

  5. --table customer \

  6. -m 1

使用hdfs dfs -cat查看生成的数据文件,发现数据已经导入.然后我们在mysql的customer中插入2条数据

 
  1. insert into customer values(6,'james');

  2. insert into customer values(7,'luna');

执行如下的指令,实现增量的导入

 
  1. sqoop import \

  2. --connect jdbc:mysql://master:3306/test \

  3. --username hive \

  4. --password 123456 \

  5. --table customer \

  6. --check-column id \

  7. --incremental append \

  8. --last-value 5

在数据库的表字段中常常会设置一个自增的字段来作为数据表的主键,我们这里以id字段来作为判断数据行是否为增量数据的依据.last-value设置上次导入的id的最大值,因此sqoop就只会将id值在5~7之间的数据进行导入,实现了增量的导入 
注意:如果不指定last-value值,将会将表的所有数据进行导入,便发生了数据的冗余

Lastmodified导入实战

首先我们要创建一个customer表,指定一个时间戳字段

create table customertest(id int,name varchar(20),last_mod timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);

我们再次插入如下记录:

 
  1. insert into customertest(id,name) values(1,'neil');

  2. insert into customertest(id,name) values(2,'jack');

  3. insert into customertest(id,name) values(3,'martin');

  4. insert into customertest(id,name) values(4,'tony');

  5. insert into customertest(id,name) values(5,'eric');

此处的时间戳设置为在数据的产生和更新时都会发生改变. 
我们此时执行sqoop指令将数据导入hdfs,

 
  1. sqoop import \

  2. --connect jdbc:mysql://master:3306/test \

  3. --username hive \

  4. --password 123456 \

  5. --table customertest

  6. -m 1

我们再次插入一条数据进入customertest表

insert into customertest(id,name) values(6,'james')

我们使用incremental的方式进行增量的导入

 
  1. sqoop import \

  2. --connect jdbc:mysql://master:3306/test \

  3. --username hive \

  4. --password 123456 \

  5. --table customertest \

  6. --check-column last_mod \

  7. --incremental lastmodified \

  8. --last-value "2016-12-15 15:47:29" \

  9. -m 1 \

  10. --append

此处已经会导入我们最后插入的一条记录,但是我们却发现此处插入了2条数据,这是为什么呢? 
这是因为采用lastmodified模式去处理增量时,会将大于等于last-value值的数据当做增量插入. 
注意: 
使用lastmodified模式进行增量处理要指定增量数据是以append模式(附加)还是merge-key(合并)模式添加 
这里写图片描述
我们演示使用merge-by的模式进行增量更新,我们去update id为1的name字段

update customertest set name = 'Neil' where id = 1;

更新之后,这条数据的时间戳会更新为我们更新数据时的系统时间,我们执行如下指令,把id字段作为merge-key

 
  1. sqoop import \

  2. --connect jdbc:mysql://master:3306/test \

  3. --username hive \

  4. --password 123456 \

  5. --table customertest \

  6. --check-column last_mod \

  7. --incremental lastmodified \

  8. --last-value "2016-12-15 15:47:30" \

  9. -m 1 \

  10. --merge-key id

由于merge-key这种模式是进行了一次完整的maoreduce操作,因此最终我们在customertest文件夹下可以看到生成的为part-r-00000这样的文件,会发现id=1的name已经得到修改,同时新增了id=6的数据

Sqoop导入hive分隔符问题

Sqoop从Oracle导入数据到Hive,示例:

[plain] view plain copy

  1. sqoop import --connect jdbc:oracle:thin:@oracle-host:port:orcl --username name--password passwd --hive-import -table tablename  


如果不加其他参数,导入的数据默认的列分隔符是'\001',默认的行分隔符是'\n'。

这样问题就来了,如果导入的数据中有'\n',hive会认为一行已经结束,后面的数据被分割成下一行。这种情况下,导入之后hive中数据的行数就比原先数据库中的多,而且会出现数据不一致的情况。

Sqoop也指定了参数 --fields-terminated-by和 --lines-terminated-by来自定义行分隔符和列分隔符。

  1. sqoop import --connect jdbc:oracle:thin:@oracle-host:port:orcl --username name--password passwd --hive-import -table tablename  --fields-terminated-by '\n' --lines-terminated-by ',' 
  2. -split-by id  //按照id(int类型,例如共500个)的最大最小区间划分where id>=min(id) and id<=500/2 和 id>500/2 and max(id) 两个阶段导入,结合-m map job的个数来运用
  3. -m 2

猜你喜欢

转载自blog.csdn.net/xiaolong_4_2/article/details/82111189