Nutch 1.3 學習筆記 8 LinkDb

來源:互聯網
上載者:User

Nutch 1.3 學習筆記 8 LinkDb
----------------------------
這裡主要是分析一下org.apache.nutch.crawl.LinkDb,它主要是用計算反向連結。

1. 運行命令 bin/nutch invertlinks

協助參數說明:

Usage: LinkDb <linkdb> (-dir <segmentsDir> | <seg1> <seg2> ...) [-force] [-noNormalize] [-noFilter]linkdboutput LinkDb to create or update-dir segmentsDirparent directory of several segments, ORseg1 seg2 ... list of segment directories-forceforce update even if LinkDb appears to be locked (CAUTION advised)-noNormalizedon't normalize link URLs-noFilterdon't apply URLFilters to link URLs

本地的運行結果為:

lemo@debian:~/Workspace/java/Apache/Nutch/nutch-1.3$ bin/nutch invertlinks db/linkdb/ db/segments/20110822105243/ LinkDb: starting at 2011-08-29 09:21:36LinkDb: linkdb: db/linkdbLinkDb: URL normalize: trueLinkDb: URL filter: trueLinkDb: adding segment: db/segments/20110822105243            // 加入新的segment庫LinkDb: merging with existing linkdb: db/linkdb  // 與原因的庫進行合并LinkDb: finished at 2011-08-29 09:21:40, elapsed: 00:00:03

2. LinkDb主要原始碼分析

在LinkDb主要是調用一個invert方法,這個方法做了兩件事,
+ 分析新輸入的segment目錄,產生新的反向連結庫
+ 把新產生的反向連結庫與原來的庫進行合并

2.1 分析新輸入的segment目錄,主要代碼如下:

// 建立立一個MP任務JobConf job = LinkDb.createJob(getConf(), linkDb, normalize, filter);// 添加目錄到輸入路徑,這裡可能有多個輸入路徑, parse_data    for (int i = 0; i < segments.length; i++) {      if (LOG.isInfoEnabled()) {        LOG.info("LinkDb: adding segment: " + segments[i]);      }      FileInputFormat.addInputPath(job, new Path(segments[i], ParseData.DIR_NAME));        }// 提交MP任務    try {      JobClient.runJob(job);    } catch (IOException e) {      LockUtil.removeLockFile(fs, lock);      throw e;    }

下面來看一下createJob都做了些什麼:

private static JobConf createJob(Configuration config, Path linkDb, boolean normalize, boolean filter) {// 新成一個臨時的目錄    Path newLinkDb =      new Path("linkdb-" +               Integer.toString(new Random().nextInt(Integer.MAX_VALUE)));    JobConf job = new NutchJob(config);    job.setJobName("linkdb " + linkDb);// 設定輸出格式    job.setInputFormat(SequenceFileInputFormat.class);// 配置Map,Combiner,Reducer方法    job.setMapperClass(LinkDb.class);    job.setCombinerClass(LinkDbMerger.class);// 如果配置了過濾或者規格化,並且沒有找到老的linkdb目錄,好就以filter和normalize進行配置    // if we don't run the mergeJob, perform normalization/filtering now    if (normalize || filter) {      try {        FileSystem fs = FileSystem.get(config);        if (!fs.exists(linkDb)) {          job.setBoolean(LinkDbFilter.URL_FILTERING, filter);          job.setBoolean(LinkDbFilter.URL_NORMALIZING, normalize);        }      } catch (Exception e) {        LOG.warn("LinkDb createJob: " + e);      }    }    job.setReducerClass(LinkDbMerger.class);// 配置MP輸出路徑    FileOutputFormat.setOutputPath(job, newLinkDb);// 配置輸出格式    job.setOutputFormat(MapFileOutputFormat.class);// 對map輸出使用壓縮,以減少Reducer的輸入壓力    job.setBoolean("mapred.output.compress", true);// 配置<key,value>的輸出類型    job.setOutputKeyClass(Text.class);    job.setOutputValueClass(Inlinks.class);    return job;  }

  下面來看一下LinkDb中的map做了些什麼,這個方法主要是從toUrl=>fromUrl建立一個對應關係,這個有點像倒排索引中的TermId=>DocId
  而LinkDbMerger這個類實現了reducer介面,主要是收集指定個數的同一個toUrl的fromUrl,這個指定的個數可能通過設定db.max.inlinks來設定。 

  2.2 把新產生的反向連結庫與老的庫進行合并,主要代碼如下:

   if (fs.exists(currentLinkDb)) {   // 如果存在老的反向連結庫,就進行合并      if (LOG.isInfoEnabled()) {        LOG.info("LinkDb: merging with existing linkdb: " + linkDb);      }      // try to merge  //       Path newLinkDb = FileOutputFormat.getOutputPath(job);      job = LinkDbMerger.createMergeJob(getConf(), linkDb, normalize, filter);  // 加入輸入路徑      FileInputFormat.addInputPath(job, currentLinkDb);      FileInputFormat.addInputPath(job, newLinkDb);      try {        JobClient.runJob(job);      } catch (IOException e) {        LockUtil.removeLockFile(fs, lock);        fs.delete(newLinkDb, true);        throw e;      }      fs.delete(newLinkDb, true);    }    LinkDb.install(job, linkDb); // 安裝新產生的反向連結庫

我們再看一下createMergeJob做了些什麼:

 public static JobConf createMergeJob(Configuration config, Path linkDb, boolean normalize, boolean filter) { // 產生一個臨時目錄    Path newLinkDb =      new Path("linkdb-merge-" +                Integer.toString(new Random().nextInt(Integer.MAX_VALUE)));    JobConf job = new NutchJob(config);    job.setJobName("linkdb merge " + linkDb);// 配置個輸出格式    job.setInputFormat(SequenceFileInputFormat.class);// 配置Map與Reducer方法,這裡的Reducer方法與上面的一樣,用於對相同key(toUrl)的values進行彙總// 然後輸出指定個數的value,而這裡的LinkDbFilter應該是對key與value所對應的url進行過濾與正規化    job.setMapperClass(LinkDbFilter.class);    job.setBoolean(LinkDbFilter.URL_NORMALIZING, normalize);    job.setBoolean(LinkDbFilter.URL_FILTERING, filter);    job.setReducerClass(LinkDbMerger.class);// 配置輸出路徑    FileOutputFormat.setOutputPath(job, newLinkDb);    job.setOutputFormat(MapFileOutputFormat.class);    job.setBoolean("mapred.output.compress", true);    job.setOutputKeyClass(Text.class);    job.setOutputValueClass(Inlinks.class);    return job;  }

  3. bin/nutch readlinkdb 分析

主要是用於下載linkdb的內容到指定的目錄,協助如下:

     

Usage: LinkDbReader <linkdb> {-dump <out_dir> | -url <url>)-dump <out_dir>dump whole link db to a text file in <out_dir>-url <url>print information about <url> to System.out

下面是本機啟動並執行結果:

lemo@debian:~/Workspace/java/Apache/Nutch/nutch-1.3$ bin/nutch readlinkdb db/linkdb/ -dump output2LinkDb dump: starting at 2011-08-29 09:54:08LinkDb dump: db: db/linkdb/LinkDb dump: finished at 2011-08-29 09:54:09, elapsed: 00:00:01

下面是輸出output2目錄中檔案的部分內容,可以看到,這裡一個<key,value>對,key是toUrl,value是fromUrl

lemo@debian:~/Workspace/java/Apache/Nutch/nutch-1.3$ head output2/part-00000 http://baike.baidu.com/Inlinks: fromUrl: http://www.baidu.com/ anchor: 百科http://hi.baidu.com/Inlinks: fromUrl: http://www.baidu.com/ anchor: 空間http://hi.baidu.com/baidu/Inlinks: fromUrl: http://www.baidu.com/ anchor: http://home.baidu.com/Inlinks:

這個readlinkdb也是用了一個MP任務,輸入格式為SequenceFileInputFormat,輸出格式為TextOutput,Map-Reducer都是用的預設的。

   4. bin/nutch mergelinkdb 分析

主要是用來合并個不同的linkdb資料庫的

   Usage: LinkDbMerger <output_linkdb> <linkdb1> [<linkdb2> <linkdb3> ...] [-normalize] [-filter]output_linkdboutput LinkDblinkdb1 ...input LinkDb-s (single input LinkDb is ok)-normalizeuse URLNormalizer on both fromUrls and toUrls in linkdb(s) (usually not needed)-filteruse URLFilters on both fromUrls and toUrls in linkdb(s)

其實這裡的合并就是調用上面分析的LinkDbMerger中的createMergeJob方法

   5. 總結
這裡主要是對於parse_data目錄中分析出來的外連結進行反向連結的計算,在下面計算連結分數的時候會用到這些反向連結。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.