MapReduce trong Nutch:

Một phần của tài liệu XỬ lý dữ LIỆU PHÂN tán với MAPREDUCE và xây DỰNG ỨNG DỤNG MINH họa (Trang 58 - 63)

5 Mã nguồn mở Lucene, Solr và Nutch

5.4MapReduce trong Nutch:

Cấu trúc dữ liệu chính trong Nutch 5.4.1

CrawlDatum: Cấu trúc dữ liệu dùng trong CrawlDB dùng để lƣu trữ thông tin của một URL, gồm có trạng thái, thời gian, số lần thử lại để thu thập dữ liệu, điểm số, giá trị băm, metadata và thời gian cập nhật của URL,… Các thuộc tính trong lớp này gồm:

private byte status;

private long fetchTime;

private byte retries;

private int fetchInterval;

private float score = 1.0f;

private byte[] signature = null;

private long modifiedTime;

private org.apache.hadoop.io.MapWritable metaData;

SelectorEntry: Cấu trúc dữ liệu sử dụng trong Generator, gồm có URL, CrawlDatum và Segnum (để chứa tên của segment).

58

Content: Cấu trúc dữ liệu sử dụng để chứa dữ liệu thu thập đƣợc, gồm các trƣờng:

private final static int VERSION = -1;

private int version;

private String url;

private String base;

private byte[] content;

private String contentType;

private Metadata metadata;

private MimeUtil mimeTypes;

ParseText: Chứa text trích xuất đƣợc từ dữ liệu thu thập đƣợc

ParseData: Chứa title, trạng thái, các liên kết ra ngoài, metadata,… của URL, gồm các trƣờng chính:

private String title;

private Outlink[] outlinks;

private Metadata contentMeta;

private Metadata parseMeta;

private ParseStatus status;

private byte version;

Inlink: Dùng trong LinkDB, chứa các liên kết đầu vào của một URL (adsbygoogle = window.adsbygoogle || []).push({});

Các thuật toán MapReduce trong Nutch 5.4.2

5.4.2.1 Thuật toán: Inject

Mục đích: Chuyển các urls khởi tạo từ file text vào trong CrawlDB.

MapReduce1: Chuyển các urls trong các file text vào trong CrawlDB tạm: Input là các file text chứa danh sách urls khởi tạo, hàm Map chuyển đổi các dòng trong file text thành dạng <url, CrawlDatum>, hàm Reduce không cần cài đặt, Output là thƣ mục CrawlDB tạm gồm các file chứa danh sách <url, CrawlDatum>.

MapReduce2: Hợp thƣ mục CrawlDB vừa tạo với CrawlDB đang tồn tại: Input là đầu ra của bƣớc 1 và thƣ mục CrawlDB đang tồn tại, hàm Map không làm gì, hàm Reduce hợp các CrawlDB thành một thƣ mục duy nhất, Output là phiên bản mới của CrawlDB.

5.4.2.2 Thuật toán: Generate

59

MapReduce1: Chọn các URL để fetch (tải về). Input là CrawlDB, hàm Map kiểm tra ngày của CrawlDatum và đƣa ra cặp key-value có dạng <CrawlDatum, url>. Hàm Reduce sắp xếp giảm theo CrawlDatum.LinkCount để lấy ra N mục có số lƣợng link nhiều nhất.

MapReduce2: Tạo các file <url, CrawlDatum> để fetch song song. Hàm Map đảo ngƣợc lại đầu ra thành <url, CrawlDatum>, hàm Partition phân mảnh theo host, hàm Reduce không làm gì.

5.4.2.3 Thuật toán: Fetch

Mục đích: Thu thập dữ liệu từ các URL trong segment.

MapReduce: Fetch một tập các URL. Input là các files <url, CrawlDatum> đƣợc phân vùng theo host. Hàm Map sử dụng nhiều tiến trình để tải dữ liệu và đƣa ra <url, FetcherOutput>. FetcherOutput gồm hai lớp là CrawlDatum và Content (chứa nội dung đƣợc tải về), hàm Reduce không làm gì, Output là hai files <url, CrawlDatum>, <url, Content>

5.4.2.4 Thuật toán: Parse

Mục đích: Phân tích nội dung thu thập đƣợc của các segment.

MapReduce: Input là tập tin chứa <url, Content>, hàm Map sử dụng plugin của Nutch để phân tích dữ liệu và đƣa ra cặp key-value <url, Parse>. Parse gồm có ParseText và ParseData. Đầu ra là 3 files chứa: <url, ParseText>, <url, ParseData> và <url, CrawlDatum> để lƣu chứa các outlink.

5.4.2.5 Thuật toán: Update CrawlDB

Mục đích: Sử dụng các URL mới đƣợc thu thập thêm để cập nhật lại CrawlDB

MapReduce: Chuyển các <url, CrawlDatum> từ giai đoạn Fetch và Parse vào trong CrawlDB. Input là CrawlDB đang tồn tại và các files <url, CrawlDatum> từ giai đoạn Fetch và Parse. Hàm Map không làm gì, Hàm Reduce hợp các mục thành một một mới. Output là phiên bản CrawlDB mới.

5.4.2.6 Thuật toán: Invert Links

Mục đích: Đếm số lƣợng liên kết đầu vào của một URL.

MapReduce: Tính toán Inlinks cho tất cả các urls. Input là <url, ParseData> chứa Outlinks của trang web. Hàm Map duyệt qua các Outlinks trong ParseData và đảo ngƣợc lại để đếm Inlinks: <url, ParseData> → <outlink, url>. Hàm Reduce đếm số lƣợng Inlink cho mỗi url. Output là <url, Inlinks>

60

5.4.2.7 Thuật toán: Index

Mục đích: Tạo Lucene/Solr index.

MapReduce: Input gồm nhiều files, giá trị đƣợc gói trong <Class, Object> gồm có: <url, ParseData>, <url, ParseText> đƣợc lấy từ giai đoạn parse, chứa title, metadata, text… <url, Inlinks> có đƣợc sau khi Invert Links để sử dụng tính toán giá trị boost khi đánh chỉ mục. Hàm Map không làm gì chỉ làm nhiệm vụ chuyển tiếp dữ liệu, hàm Reduce sử dụng các plugin đánh chỉ mục trong Nutch để tạo ra một Nutch Document.

Đoạn mã chính để tạo Index trong Nutch:

public void map(Text key, Writable value,

OutputCollector<Text, NutchWritable output, Reporter reporter)

throws IOException {

output.collect(key, new NutchWritable(value)); } (adsbygoogle = window.adsbygoogle || []).push({});

public void reduce(Text key, Iterator<NutchWritable> values,

OutputCollector<Text, NutchDocument> output, Reporter reporter)

throws IOException {

Inlinks inlinks = null; CrawlDatum dbDatum = null; CrawlDatum fetchDatum = null; ParseData parseData = null; ParseText parseText = null; while (values.hasNext()) {

final Writable value = values.next().get(); // lấy dữ liệu ra if (value instanceof Inlinks) {

inlinks = (Inlinks)value;

} else if (value instanceof CrawlDatum) { final CrawlDatum datum = (CrawlDatum)value; if (CrawlDatum.hasDbStatus(datum))

dbDatum = datum;

else if (CrawlDatum.hasFetchStatus(datum)) {

// không đánh chỉ mục các trang trống hoặc không có gì thay đổi if (datum.getStatus() != CrawlDatum.STATUS_FETCH_NOTMODIFIED) fetchDatum = datum;

} else if (CrawlDatum.STATUS_LINKED == datum.getStatus() || CrawlDatum.STATUS_SIGNATURE == datum.getStatus() || CrawlDatum.STATUS_PARSE_META == datum.getStatus()) { continue;

} else {

throw new RuntimeException("Error Status: "+datum.getStatus()); }

61

} else if (value instanceof ParseData) { parseData = (ParseData)value;

} else if (value instanceof ParseText) { parseText = (ParseText)value;

} }

NutchDocument doc = new NutchDocument();

final Metadata metadata = parseData.getContentMeta();

// add segment vào document , được dùng để ánh xạ index được hợp trở lại các files segment

doc.add("segment", metadata.get(Nutch.SEGMENT_NAME_KEY)); // add digest sử dụng để dedup (loại bỏ các trang trùng nhau) doc.add("digest", metadata.get(Nutch.SIGNATURE_KEY));

final Parse parse = new ParseImpl(parseText, parseData); try {

final Text url = (Text)

dbDatum.getMetaData().get(Nutch.WRITABLE_REPR_URL_KEY); if (url != null) {

fetchDatum.getMetaData().put(Nutch.WRITABLE_REPR_URL_KEY, url); }

// chạy indexing filters

doc = this.filters.filter(doc, parse, key, fetchDatum, inlinks); } catch (final IndexingException e) {

return; }

// skip documents discarded by indexing filters if (doc == null) return;

float boost = 1.0f; (adsbygoogle = window.adsbygoogle || []).push({});

// sử dụng scoring filters để tính điểm try {

boost = this.scfilters.indexerScore(key, doc, dbDatum, fetchDatum, parse, inlinks, boost);

} catch (final ScoringFilterException e) { if (LOG.isWarnEnabled()) {

LOG.warn("Error calculating score " + key + ": " + e); }

return; }

// áp dụng boost cho tất cả các trường được đánh chỉ mục. doc.setWeight(boost);

// lưu lại boost để sử dụng trong chức năng explain and dedup doc.add("boost", Float.toString(boost));

62

output.collect(key, doc); }

Chƣơng 6: GIỚI THIỆU ỨNG DỤNG TÌM KIẾM TRUYỆN TRANH

6 Giới thiệu ứng dụng tìm kiếm truyện tranh

Một phần của tài liệu XỬ lý dữ LIỆU PHÂN tán với MAPREDUCE và xây DỰNG ỨNG DỤNG MINH họa (Trang 58 - 63)