sqlserver数据导入hdfs和hive的解决方案
方法一:?环境: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表示格式文件名。这个选项依赖于上述的动作,如果使用的是in或out,format_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值插入,而不是这列的默认值。? 2?部署与流程3?详细设计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) ? 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); } ? } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |