Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 1106|回复: 0

sqlserver数据导入hdfs和hive的解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-6-17 23:03:06 | 显示全部楼层 |阅读模式

    方法一:

     

    环境:win7+sqlserver2008

    工具:bcp

    测试效率:

    新闻数据库,10 000 000行,25.8G

    导出时间:约2个小时

    每秒约1326

     

     

    方法二:

     

    用循环执行sql语句,分段写入文件。

     

     

     


     

     

     

    1 Bcp介绍

    bcp 实用工具可以在 Microsoft SQL Server 实例和用户指定格式的数据文件间大容量复制数据。 使用 bcp 实用工具可以将大量新行导入 SQL Server 表,或将表数据导出到数据文件。 除非与 queryout 选项一起使用,否则使用该实用工具不需要了解 Transact-SQL 知识。 若要将数据导入表中,必须使用为该表创建的格式文件,或者必须了解表的结构以及对于该表中的列有效的数据类型。 

    (1) 导入。

    这个动作使用in命令完成,后面跟需要导入的文件名。 

    (2) 导出。

    这个动作使用out命令完成,后面跟需要导出的文件名。 

    (3) 使用SQL语句导出。

    这个动作使用queryout命令完成,它跟out类似,只是数据源不是表或视图名,而是SQL语句。 

    (4) 导出格式文件。

    这个动作使用format命令完成,后而跟格式文件名。 

    下面介绍一些常用的选项: 

    -f format_file 

    format_file表示格式文件名。这个选项依赖于上述的动作,如果使用的是inoutformat_file表示已经存在的格式文件,如果使用的是format则表示是要生成的格式文件。 

    -x 

    这个选项要和-f format_file配合使用,以便生成xml格式的格式文件。

    -F first_row 

    指定从被导出表的哪一行导出,或从被导入文件的哪一行导入。 

    -L last_row 

    指定被导出表要导到哪一行结束,或从被导入文件导数据时,导到哪一行结束。 

    -c 

    使用char类型做为存储类型,没有前缀且以"\t"做为字段分割符,以"\n"做为行分割符。 

    -w 

    -c类似,只是当使用Unicode字符集拷贝数据时使用,且以nchar做为存储类型。 

    -t field_term 

    指定字符分割符,默认是"\t"。 

    -r row_term 

    指定行分割符,默认是"\n"。 

    -S server_name[ \instance_name] 

    指定要连接的SQL Server服务器的实例,如果未指定此选项,bcp连接本机的SQL Server默认实例。如果要连接某台机器上的默认实例,只需要指定机器名即可。 

    -U login_id 

    指定连接SQL Sever的用户名。 

    -P password 

    指定连接SQL Server的用户名密码。 

    -T 

    指定bcp使用信任连接登录SQL Server。如果未指定-T,必须指定-U-P。 

    -k 

    指定空列使用null值插入,而不是这列的默认值。 

    部署与流程

    详细设计

    3.1 Sqlserver数据导出到临时文本阶段

    Log

    BcpSqlserver

    JdbcStream

    SqlserverToTxt

    (代码见SVN-SqlserverToHive

    此阶段的是根据自定义每个导出文件中的数据行数进行分文件导出,一个导出成果如下:

    导出效率分析:

    测试一个文件1000,10000,100000条数据,比较完成时间:

    文件数据行数 = 1000 start:1359102390172 end:1359102452310 time use :62138ms

    文件数据行数 = 10000 start:1359102452310 end:1359102461626 time use :9316ms

    文件数据行数 = 100000 start:1359102461626 end:1359102462997 time use :1371ms

    文件数据行数 = 1000000 start:1359102577696 end:1359102578501 time use :805ms

    所以,用bcp导数据,文件越少效率越高,这是bcp内部的sql优化导致的。但是,考虑到实际需要,如果需对一个文件有控制,则可以自己设定文件大小。

     

    3.2 临时文本导入到hive/hdfs阶段

    3.2.1 导入hive

    创建符合行列规则的hive

    CREATE TABLE table1 (a STRING, b STRING)
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ESCAPED BY '\\'
    STORED AS TEXTFILE; 

     

    Jdbc连接hive,执行load语句

    LOAD DATA LOCAL INPATH '/home/admin/test/test.txt' OVERWRITE INTO TABLE test_1 

     

    或者直接创建外表指向hdfs中的数据文件

     

    create external table IF NOT EXISTS mytest (ID string,Symbol string) LOCATION '/tmp/sqltohdfs

     

     

     

    3.2.2 导入hdfs

    多线程每个线程处理一个文件导入到hdfs

    参考代码

    import java.io.IOException;

    import java.net.URI;

    import java.io.FileInputStream;   

      

    import org.apache.hadoop.conf.Configuration;  

    import org.apache.hadoop.fs.FileSystem;  

    import org.apache.hadoop.fs.FSDataOutputStream;  

    import org.apache.hadoop.fs.Path;  

    import org.apache.hadoop.io.IOUtils;

     

     

    public class LocalToHDFS {

    // s 为本地文件路径

    // d 为hdfs绝对路径

    public static void uploadLocalFile2HDFS(String s, String d)

    throws IOException {

    Configuration conf = new Configuration();

    FileSystem hdfs = FileSystem.get(URI.create(d), conf);

    FileInputStream in = null;

    FSDataOutputStream out = null;

    try {

    in = new FileInputStream(s);

    out = hdfs.create(new Path(d));

    IOUtils.copyBytes(in, out, 4096, false);

    finally {

    IOUtils.closeStream(in);

    IOUtils.closeStream(out);

    }

     

    }

    }

     


    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-19 22:17 , Processed in 0.071825 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表