Sqoop1.4.7编程,10分钟导入一亿数据

最近公司有个需求要让我使用sqoop往hdfs导入一亿的数据,要求5分钟完成,但是网上关于sqoop的资料比较少,因此就对此做一些补充。

要使用sqoop做一些嵌入式的编程,需要做如下准备。

  1. window本地需要有hadoop的环境,这里就不对hadoop的环境做阐述,可自行上网查找
  2. 下载sqoop的包,并配置sqoop的环境变量.
    sqoop的包
    配置好环境之后,我们就可以开始编程了。

maven没有sqoop的相关依赖

此时需要手动的将jar包添加到本地的maven仓库中,上图中,我们能看到sqoop-1.4.7.jar这个包,只要把这个包的添加到maven仓库中,我们的开发环境就准备好了。

 install:install-file -Dfile=<Jar包的地址> 
           -DgroupId=<Jar包的GroupId> 
           -DartifactId=<Jar包的引用名称> 
           -Dversion=<Jar包的版本> 
           -Dpackaging=<Jar的打包方式>

//例子           
mvn install:install-file 
 -Dfile=-Dfile=E:\U\spring-framework-4.2.4.RELEASE\libs\spring-context-4.2.4.RELEASE.jar
 -DgroupId=org.springframework
 -DartifactId=test
 -Dversion=4.2.4 
 -Dpackaging=jar

大家根据自己的路径去编译即可。

现在说说如何实现10分钟,导入一亿的数据量

核心思想 分批导入

  1. 将一亿的数据拆分,我这里是以一千万为单位,将一亿数据拆分成十份,利用线程池将任务发送,根但需要根据本地的硬件的性能做一些调整。
  2. 挖掘sqoop的参数的作用,努力提升服务的性能。

下面我将贴出部分代码,以供大家参考:

将任务拆分

    public boolean importFile(int threadCount, ImportModel sqlModel) throws Exception {
        int flag=0;
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        StringBuffer stringBuffer = new StringBuffer();
        //线程池为线程安全
        CustomThreadPoolExecutor pool = threadUtil.poolExecutor(threadCount);
        HashMap<String,Double> map=progressManager.getMap();
        for (int i = 1; i <= threadCount; i++) {
            int index = i;
            String[] args = ImportUtil.importFile(sqlModel, threadCount, i * splitPoint,i == 1 ? 0 : (i - 1) * splitPoint);
            pool.execute(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                      int result = sqoopUtil.submitSqoop(args, "import");
                    if (result == 1) {
                        stringBuffer.append("[" + (index == 1 ? 0 : (index - 1) * splitPoint) + "," + index * splitPoint + "]");
                    }else{
                        double current=index* 1.0 / threadCount;
                        lock.lock();
                        //进度存到Map中,“yanger”后面需要连上数据库 获取用户id
                        Double pre=map.get("yanger");
                        if (pre == null) {
                            map.put("yanger", current);
                        } else if (pre != null && current > pre) {
                            progressManager.getMap().put("yanger", current);
                        }
                        lock.unlock();
                    }
                    countDownLatch.countDown();
                }
            });
        }
        countDownLatch.await();
        if (stringBuffer.length() > 0) {
            throw new SqoopException(stringBuffer.toString() + "导入失败");
        }
        return flag==0?true:false;
    }

sqoop 相关配置

public static String[] importFile(ImportModel sqlModel,int threadCount, Long max, Long min) {
        Integer model=sqlModel.getImportModel();
        List<String> list = new ArrayList<String>();
        list.add("--connect");                //数据库url
        list.add(sqlModel.getUrl()+ "?serverTimezone=GMT%2B8&useUnicode=true&defaultFetchSize=10000&characterEncoding=utf-8");
        list.add("--driver");                 //数据库驱动
        list.add(sqlModel.getDriver());
        list.add("--username");               //数据库账号
        list.add(sqlModel.getUsername());
        list.add("--password");               //数据库密码
        list.add(sqlModel.getPassword());
        list.add("--table");                  //指定导入的表
        list.add(sqlModel.getTable());
        list.add("--bindir");                 //指定生成jar的路径
        list.add("lib");
        list.add("--fetch-size");             //批量读取
        list.add("10000");
        list.add("--target-dir");             //指定导入到那个HDFS文件中
        list.add("/TestMill");
        list.add("--outdir");                 //指定生成类的路径
        list.add("lib");
        list.add("--fields-terminated-by");   //分割符
        list.add(",");
        list.add("--skip-dist-cache");        //分布式缓存
        list.add("--direct");
        list.add("-m");
        list.add("10");
        if (model!=null && model == 2) {
            list.add("--incremental");           //增量导入
            list.add("lastmodified");
        }else {
            list.add("--incremental");            //增量导入
            list.add("append");
        }

        if (threadCount==1) {
            list.add("--where");
            list.add("id<" + sqlModel.getLine());
        }else{
            if(sqlModel.getLine()<max)
                max=sqlModel.getLine();
            list.add("--where");
            list.add("id<="+max+" and id >"+min);
        }
        if (sqlModel.getColmun() == null||sqlModel.getColmun() == "" ) {
            //如果没有指定列,默认自增指定id
            list.add("--check-column");
            list.add("id");
        }else {
            list.add("--check-column");       //导入时要检查的列
            list.add(sqlModel.getColmun());
            list.add("--split-by");
            list.add(sqlModel.getColmun());
        }
        return list.toArray(new String[list.size()]);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章