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()]);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章