`

大数据导入导出-dump和fetch的测试

 
阅读更多

1.当需要从数据库大量导出数据时,同时又需要对对数据逐行进行过滤处理,如果是mysql这样的数据库,选择分页查询到内存再处理导出的话,当数据量超过千万时速度会直线下降,到达几千万条时会下降到难以接受的速度(以上经过多次测试验证),oracle另说...

有没有办法很好的解决这个问题,当然有哈哈

这里简单介绍2种方法:

一是使用远程dump的方式,对权限高要求,因为你可以随时把人家的表乃至库整个都拉下来,速度快,一般的linux系统直接支持mysql dump命令,具体操作如果不会,网上一搜很多说的,不详细说明了。

二是使用fetch游标的方式,速度也很快,可能比dump略慢,但是好处是可以逐条处理数据,并导出

参考代码

 

1.fetch方式

package com.jd.gp.lzotest;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStreamReader;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.Statement;

 

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import au.com.bytecode.opencsv.CSVReader;

 

 

public class DumpAndFetch {

 

private static final Logger logger = LoggerFactory.getLogger(DumpAndFetch.class);

 

public static void main(String[] args) {

printMemory();

startDump();

startFetch();

printMemory();

}

 

private static void startFetch() {

Connection conn = null;

Statement ps = null;

ResultSet rs = null;

try {

long start = System.currentTimeMillis();

conn = DBUtil.createConnection("ip", port, "dbname", "username", "password");

ps = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);

//这个地方必须这么写,mysql不止fetchSize

ps.setFetchSize(Integer.MIN_VALUE);

logger.error("fetch start.... setFecthSize=" + ps.getFetchSize());

rs = ps.executeQuery("select * from orderdetail");

int count = 0;

while (rs.next()) {

//count++;

/*if(count % 200000 ==0){

logger.info("剩余内存 = " + Runtime.getRuntime().freeMemory()/1024 + "KB");

}*/

}

logger.info("fecch total time = " + (System.currentTimeMillis() - start) / 1000 + "Second");

logger.info("fetch end....count=" + count);

Thread.sleep(5000L);

System.out.println("剩余内存 = " + Runtime.getRuntime().freeMemory()/1024 + "KB");

} catch (Exception e) {

e.printStackTrace();

}

DBUtil.close(conn, ps, rs);

}

 

2.dump方式

private static void startDump() {

try {

long start = System.currentTimeMillis();

logger.info("dump start.... " );

//路径不能含有空格--替换空格?

Runtime rt = Runtime.getRuntime();

//空格不能乱加,参数不能乱加,否则异常也很难知道

//linux下一般支持mysqldump,所以可以直接这么写,但是在win下面需要指定命令的路径,或者在path环境变量中指定mysqldump命令 "cmd /c  C:/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump -uroot.."

Process proc = rt.exec("mysqldump -h192.168.229.69 -umq -pmq test orderdetail --result-file=/root/gp/orderdetail.sql ");

int exitValue = proc.waitFor();//等待执行结束

logger.info("dump total time = " + (System.currentTimeMillis()-start)/1000 + "Second");

logger.info("返回值:" + exitValue);

//readF();

} catch (Exception e) {

e.printStackTrace();

}

 

public static void printMemory(){

// 可使用内存  

        long totalMemory = Runtime.getRuntime().totalMemory()/1024 ;// kb;  

        // 剩余内存  

        long freeMemory = Runtime.getRuntime().freeMemory()/1024 ;// kb;  

        // 最大可使用内存  

        long maxMemory = Runtime.getRuntime().maxMemory()/1024 ;// kb;

        logger.info("可使用内存 = " + totalMemory + "KB");

        logger.info("剩余内存 = " + freeMemory + "KB");

        logger.info("最大可使用内存 = " + maxMemory + "KB");

}

 

public static void readF() throws Exception {

File f = new File("/root/gaopeng/orderdetail.sql");

CSVReader reader = new CSVReader(new InputStreamReader(new FileInputStream(f), "UTF-8"));

String[] items = null;

int line = 0;

while((items = reader.readNext()) != null){

line++;

if(line % 400000 == 0) {

for(String s : items)

System.out.print(s);

System.out.println();

}

}

reader.close();

}

}

 以下是转来的:参考学习

  • 等待命令执行结束用waitFor(),其返回值就是命令的返回值。
  • 如果出现程序执行被挂起,没有任何反应的情况,是由于没有读取命令子进程的正常输出流或错误输出流导致缓冲区被占满,进程被锁住。这个时候需要把输出流中的内容给读出来。最好的做法是使用两个线程,分别同时读取正常输出流和错误输出流。
  • 执行Windows平台上的命令时使用cmd.exe /C,如cmd.exe /C dir。
  • 记得关闭命令子进程的输出流,通过Process.getOutputStream().close(),这样不会导致命令子进程被锁住。



仿照上面文章中,写了一个简单的例子。

Java代码
 
package cmd;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
class StreamDrainer implements Runnable {
 private InputStream ins;
 public StreamDrainer(InputStream ins) {
  this.ins = ins;
 }
 public void run() {
  try {
   BufferedReader reader = new BufferedReader(
     new InputStreamReader(ins));
   String line = null;
   while ((line = reader.readLine()) != null) {
    System.out.println(line);
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
public class TestRunCmd {
 public static void main(String[] args) {
  String[] cmd = new String[] { "cmd.exe", "/C", "wmic process get name" };
  try {
   Process process = Runtime.getRuntime().exec(cmd);
   
   new Thread(new StreamDrainer(process.getInputStream())).start();
   new Thread(new StreamDrainer(process.getErrorStream())).start();
   
   process.getOutputStream().close();
   int exitValue = process.waitFor();
   System.out.println("返回值:" + exitValue);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
 
***************************************************************
细节:

一 exec()方法有很多重载版本,常用的方式是将所有命令以一个String对象传递给exec() ; 另一种方式是将cmd命令的各个部分包装成String [] ,然后将此数组传递给exec() !

二 在windows上,文件名或者文件夹命中有空格时,可以采用将该名称放入双引号内的办法来避免出错!
PS:windows中的程序很少会被使用cmd来启动,大家已经很习惯于双击了,所以常用程序不一定有统计的命名,这一点不同于linux上的vi等! 因此,请大家一定要熟悉windows cmd下的一个特殊命令“start”;另外,cmd在windows的很多版本里,其实就是 cmd.exe !


1 调用记事本(或系统默认的文本程序)打开简单文本文件:

Runtime.getRuntime().exec("cmd.exe /c start filename.txt ");
2 调用ms word打开文本文件:
Runtime.getRuntime().exec("cmd.exe /c start winword.exe filename.doc ");
3 打开一个windows目录:
Runtime.getRuntime().exec("cmd.exe /c start dirname ");
4 打开一个url :
Runtime.getRuntime().exec("cmd.exe /c start http://www.google.com ");
5 打开默认的邮件程序并给xxx发送邮件;
Runtime.getRuntime().exec("cmd.exe /c start mailto:xxx@xxx.com ");

6 执行程序并捕获其标准输出:
Process p = Runtime.getRuntime().exec("start .\\xxx.exe"); p.waitfor();

注:此法亦可用来解决调用程序后其CMD黑色窗口不自动关闭的问题! 同时,如果被调用程序的执行需要消耗一段时间,则应该在exec()之后调用其返回的Process 对象的waitfor()方法来等待该程序的执行。例如:
Process p = Runtime.getRuntime().exec("start .\\xxx.exe"); p.waitfor();

再强调一点:

start 后面的命令如果包含空格,请一定使用双引号,并且必须紧跟在 start 后多添加一个以双引号引起来的参数作为start的title ; 因为start命令会把其后的第一个使用双引号的参数作为新cmd窗口的title !!!
分享到:
评论

相关推荐

    class-dump-z全平台版本(linux、iPhone、Windows)

    在使用`class-dump-z` 时,我们需要确保遵循所有相关的法律和道德规范,只在合法和授权的范围内进行逆向工程操作。例如,在进行应用的安全审计、性能优化或者寻找兼容性问题时,可以使用该工具。同时,`class-dump-z...

    redis中使用redis-dump导出、导入、还原数据实例

    在Redis中,虽然没有内置的`redis-dump`工具,但我们可以使用第三方工具来实现数据的导出、导入和还原。以下将详细介绍如何使用`redis-dump`工具来完成这些操作。 首先,要安装`redis-dump`,你需要确保系统已经...

    class-dump, class-dump-z.exe,class-dump-z win版本

    class-dump, class-dump-z.exe,class-dump-z win版本

    Redis-dump安装.rar

    Redis-dump是一个用于导出和导入Redis数据库内容的工具,主要功能是将Redis的数据备份到磁盘上,以便在需要时恢复数据。本教程将详细介绍如何在Windows环境下使用msys2和ruby进行Redis-dump的安装。 首先,我们需要...

    elasticsearch-dump-6.78.0.tar.gz

    "elasticsearch-dump-6.78.0.tar.gz" 文件是一个包含 Elasticsearch-dump 工具的归档包,版本号为 6.78.0,通过解压可以获得该工具的执行文件和其他相关资源。 Elasticsearch 是一个基于 Lucene 的分布式、RESTful ...

    class-dump-3.5

    本文将详细介绍class-dump-3.5,这是一个开源工具,用于从 Mach-O 文件(如可执行文件、动态库)中导出Objective-C类、协议、分类等元数据信息。 首先,我们来理解一下什么是Mach-O文件。在苹果的生态系统中,Mach-...

    elasticsearch-dump-6.79.0.tar.gz

    Elasticsearch-dump 是一款强大的工具,专门设计用于在 Elasticsearch 集群之间进行数据的导入和导出,同时也适用于数据的备份与迁移。这款工具的版本为 6.79.0,它提供了灵活且高效的方式来管理和操作 Elastic...

    class-dump-z

    class-dump-z是一款强大的工具,专门用于导出iOS应用的头文件,为逆向工程师提供了便利。 首先,我们要了解什么是class-dump。class-dump是一款开源工具,由Steve Troughton-Smith开发,主要用于从Mach-O二进制文件...

    class-dump-z_0.2-0

    本文将深入探讨class-dump-z的核心特性、适用场景以及使用方法,帮助读者更好地理解和运用这一工具。 class-dump-z是针对iOS应用的二进制文件进行分析,提取出其中Objective-C类的头文件信息的利器。它的出现,使得...

    class-dump ios9

    解决ios sdk9 无法class-dump导出framework头文件 也可以自己重新编译一份https://github.com/nygard/class-dump

    class-dump-z.zip

    这个名为"class-dump-z.zip"的压缩包包含了适用于Windows、Linux、Mac以及iPhone等多种平台的版本,使得开发者和研究者能够在不同的操作系统环境下进行类信息的提取工作。 class-dump-z,正如其名,是一个开源的...

    parallel-fastq-dump:并行fastq-dump包装器

    并行fastq转储并行fastq-dump包装器为什么和如何即使您已经拥有更快的资源(网络,IO,CPU),即使您已经下载了sra文件,NCBI fastq-dump有时也会非常慢。 该工具通过将工作划分为多个线程来加快过程。 这是可能的,...

    elasticsearch-dump-6.76.0.tar.gz

    在解压 "elasticsearch-dump-6.76.0.tar.gz" 文件后,你通常会得到一个包含 `bin` 和 `lib` 目录的结构。`bin` 目录下的可执行文件 `elasticsearch-dump` 是你需要运行的脚本。`lib` 目录则包含必要的库文件,确保...

    redis-dump-master.zip

    "redis-dump-master.zip" 是一个专门针对Redis数据库的备份工具,它能够帮助用户将Redis中的数据导出为JSON格式的文件,便于数据迁移、备份或者恢复。 在IT行业中,数据安全性和可恢复性是至关重要的。Redis-dump...

    Objective-C头文件导出工具class-dump

    Objective-C头文件导出工具class-dump 。 Current version: 3.4 (64 bit Intel) Requires Mac OS X 10.7 or later. class-dump 3.4 (64 bit) Usage: class-dump [options] <mach-o-file> where options are: -a ...

    redis-check-dump.exe

    redis-check-dump.exe-

    ORACLE数据导入导出-操作手册.docx

    ### Oracle 数据库数据导入导出操作手册解析 #### 手册概述 该操作手册由中科软科技股份有限公司于2019年5月发布,旨在指导数据处理人员如何正确地使用Oracle数据库进行数据导入与导出操作。手册不仅包含了具体的...

    gcov-dump-1.0.tar.gz

    希望能对通过gcc覆盖率测试工具GCOV进行覆盖率测试相关工作的同行有些许的帮助。 gcov-dump是一个dump程序,输入是一个gcov的文件,或者.gcda,即gcov的data文件;或者.gcno,即gcov的note文件。

    class-dump for ios9

    对于iOS9之前,class-dump工作良好,但在iOS9之后,由于新的安全机制,直接使用class-dump可能无法成功导出framework的头文件。为了解决这一问题,社区对class-dump进行了更新,使其能够适应iOS9的环境。 首先,...

    前端开源库-adana-dump

    在实际应用中,adana-dump可以与其他前端工具如webpack、babel、eslint等配合使用,形成一套完整的开发、测试和调试流程。例如,可以结合持续集成/持续部署(CI/CD)系统,自动运行测试并收集adana-dump生成的日志,以...

Global site tag (gtag.js) - Google Analytics