Upload
kazuki-ohta
View
2.049
Download
2
Embed Size (px)
Citation preview
今回のテーマ
• Javaで分散検索エンジンを楽をして作る
– Lucene (検索エンジン)
– Hadoop (MapReduceフレームワーク)
• 個人でも大規模な検索エンジンがさくっと作れる時代ということを示してみる
Agenda
• Luceneの説明
• Hadoopの説明
• Lucene + Hadoopで検索エンジンを構築
• まとめ
(Lucene)とは?
• Javaで書かれた検索エンジン– Yahoo ResearchのDougCutting氏が開発
– Javaのクラスライブラリとして提供され、他のソフトウェアから簡単に使用可能
– 文章サイズにもよるが、数百万件程度なら1台で検索可能
• 検索できるようになるまでの流れ– 文章を登録し、検索用インデックスを作成
– 検索用インデックスを読み込み、クエリーを発行
Luceneインデックス作成サンプル
//インデックスに登録するファイルのあるディレクトリFile directory = new File(args[0]);String[] filepath = directory.list();//インデックスの保存先String index = args[1];//インデクサの生成IndexWriter writer = new IndexWriter(index, new JapaneseAnalyzer(), true);//文書の解析for (int i = 0; i < filepath.length; i++) {
Document doc = new Document();//ファイルの登録doc.add(Field.UnIndexed("url", filepath[i]));Reader reader = new FileReader(filepath[i]);//文書内容の登録doc.add(Field.Text("contents",reader));writer.addDocument(doc);
} //インデクサのクローズwriter.optimize(); writer.close();
Luceneインデックス作成サンプル
//インデックスに登録するファイルのあるディレクトリFile directory = new File(args[0]);String[] filepath = directory.list();//インデックスの保存先String index = args[1];//インデクサの生成IndexWriter writer = new IndexWriter(index, new JapaneseAnalyzer(), true);//文書の解析for (int i = 0; i < filepath.length; i++) {
Document doc = new Document();//ファイルの登録doc.add(Field.UnIndexed("url", filepath[i]));Reader reader = new FileReader(filepath[i]);//文書内容の登録doc.add(Field.Text("contents",reader));writer.addDocument(doc);
} //インデクサのクローズwriter.optimize(); writer.close();
Luceneインデックス作成サンプル
//インデックスに登録するファイルのあるディレクトリFile directory = new File(args[0]);String[] filepath = directory.list();//インデックスの保存先String index = args[1];//インデクサの生成IndexWriter writer = new IndexWriter(index, new JapaneseAnalyzer(), true);//文書の解析for (int i = 0; i < filepath.length; i++) {
Document doc = new Document();//ファイルの登録doc.add(Field.UnIndexed("url", filepath[i]));Reader reader = new FileReader(filepath[i]);//文書内容の登録doc.add(Field.Text("contents",reader));writer.addDocument(doc);
} //インデクサのクローズwriter.optimize(); writer.close();
Luceneインデックス作成サンプル
//インデックスに登録するファイルのあるディレクトリFile directory = new File(args[0]);String[] filepath = directory.list();//インデックスの保存先String index = args[1];//インデクサの生成IndexWriter writer = new IndexWriter(index, new JapaneseAnalyzer(), true);//文書の解析for (int i = 0; i < filepath.length; i++) {
Document doc = new Document();//ファイルの登録doc.add(Field.UnIndexed("url", filepath[i]));Reader reader = new FileReader(filepath[i]);//文書内容の登録doc.add(Field.Text("contents",reader));writer.addDocument(doc);
} //インデクサのクローズwriter.optimize(); writer.close();
Lucene検索サンプル
// インデックス読み込みIndexSearcher is = new IndexSearcher("index");// クエリーパーサーの作成QueryParser qp = new QueryParser("content", new SimpleAnalyzer());// 検索クエリーの準備Query q = qp.parse(“SomeQuery");// 検索を実行Hits hs = is.search(q);// 検索結果を表示System.out.println(hs.length() + " hit(s)");for(int i=0; i<hs.length(); i++) {
System.out.println(hs.doc(i).toString()); }is.close();
Hadoopとは?
• Googleの基盤ソフトウェアのクローン
– Google File System
– MapReduce
• Yahoo Research の Doug Cutting氏が開発
– 元々はNutch Crawlerのサブプロジェクト
– Dougの子供の持っているぬいぐるみの名前
• Javaで記述
Hadoop参考文献
• Hadoop公式サイト
– http://hadoop.apache.org/core/
– Wiki: http://wiki.apache.org/hadoop/
• インストール方法・チュートリアル・プレゼン資料など
• Hadoop解析資料 (拙著)
• http://preferred.jp/pub/hadoop.html
• Hadoop, hBaseで構築する大規模データ処理システム on CodeZine (拙著)
– http://codezine.jp/a/article/aid/2448.aspx
MapReduceの実行フロー
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
Hadoopのスケーラビリティ
• Scaling 4000 nodes at Yahoo!
– http://developer.yahoo.net/blogs/hadoop/2008/09/scaling_hadoop_to_4000_nodes_a.html
• Hadoop wins Terabyte Sort Benchmark
– http://developer.yahoo.net/blogs/hadoop/2008/07/apache_hadoop_wins_terabyte_sort_benchmark.html
• Hadoopで書いとけば、4000ノードぐらいまではスケールするよ!
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
foo foo foobar bar buzz
入力文書: doc1
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
foo foo foobar bar buz
入力文書: doc1
doc1: foodoc1: foo
doc1: foodoc1: bar
doc1: bardoc1: buz
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
foo foo foobar bar buz
入力文書: doc1
doc1: foodoc1: bar
doc1: bardoc1: buz
doc1: foodoc1: foo
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
foo foo foobar bar buz
入力文書: doc1
doc1: foodoc1: bar
doc1: bardoc1: buz
doc1: foodoc1: foo
foo: 1foo: 1
bar: 1foo: 1
bar: 1buz: 1
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
foo foo foobar bar buz
入力文書: doc1
foo: 1foo: 1
bar: 1foo: 1
bar: 1buz: 1
bar: <1, 1>buz: <1>
foo: <1, 1, 1>
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
foo foo foobar bar buz
入力文書: doc1
bar: <1, 1>buz: <1>
foo: <1, 1, 1>
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
foo foo foobar bar buz
入力文書: doc1
foo: <1, 1, 1>
bar: <1, 1>buz: <1>
foo: 3
bar: 2buz: 1
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
foo foo foobar bar buz
入力文書: doc1
bar: 2buz: 1
foo: 3
作成する検索エンジンの仕組み
url1: <html>…url2: <html>…url3: <html>…url4: <html>…url5: <html>…url6: <html>…url7: <html>…
…
クロールしてきた文章 Lucene
インデックス1
Lucene
インデックス2
Lucene
インデックス3
Lucene
インデックス4
Lucene
インデックス5
Hadoopによる分散インデックス
作成
分散クエリー発行
検索用ノード
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffleurl3: <html>…url4: <html>…
url1: <html>…url2: <html>…
url5: <html>…url6: <html>…
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffleurl3: <html>…url4: <html>…
url1: <html>…url2: <html>…
url5: <html>…url6: <html>…
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffleurl3: <html>…url4: <html>…
url1: <html>…url2: <html>…
url5: <html>…url6: <html>…
url1: <html>…url4: <html>…url5: <html>…
url2: <html>…url3: <html>…url6: <html>…
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
url1: <html>…url4: <html>…url5: <html>…
url2: <html>…url3: <html>…url6: <html>…
Lucene
インデックス
Lucene
インデックス
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
Lucene
インデックス
Lucene
インデックス
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
Lucene
インデックス
Lucene
インデックス
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
Lucene
インデックス
Lucene
インデックス
分散インデックス作成(Mapフェーズ)
// 何もしないpublic void map(Text key, Text value,
OutputCollector<Text, Text> output,Reporter reporter) throws IOException {
Text url = key;Text str = value;output.collect(url, str);
}
分散インデックス作成(Reduceフェーズ)
public void reduce(Text key, Iterator<Text> values,OutputCollector<Text, Writable> output,Reporter reporter) throws IOException {
// URLText url = key;// 本文Text str = values.next();// ドキュメントを追加Document doc = new Document();doc.add(new Field("url", url.toString(), Field.Store.YES, Field.Index.NO));doc.add(new Field("content", str.toString(), Field.Store.YES, Field.Index.TOKENIZED));output.collect(url, new LuceneDocumentWrapper(doc));
}
分散インデックス作成(Reduce終了フェーズ)
public void close(final Reporter reporter) throws IOException {// 分散ファイルシステムに保存するための何かfinal Path perm = new Path(job.getOutputPath(), name);final Path temp = job.getLocalPath(
“index/_” + Integer.toString(new Random().nextInt()));// インデックス作成final IndexWriter writer = new IndexWriter(
fs.startLocalOutput(perm, temp).toString(),new JapaneseAnalyzer(), true);
try {writer.optimize();writer.close();fs.completeLocalOutput(perm, temp); // copy to dfs
} finally {closed = true;
} }
以上のコードを実行
• Hadoopのインストール
– 今回は24 (dual core)台のクラスタを使用
• ビルド
• 実行
– bin/hadoop jar indexer.ja net.kzk9.indexer in out
• 分散ファイルシステムのoutというディレクトリにLuceneインデックスが作成されている
– 30Gのドキュメントで約2-3時間?
作成する検索エンジンの仕組み
url1: <html>…url2: <html>…url3: <html>…url4: <html>…url5: <html>…url6: <html>…url7: <html>…
…
クロールしてきた文章 Lucene
インデックス1
Lucene
インデックス2
Lucene
インデックス3
Lucene
インデックス4
Lucene
インデックス5
Hadoopによる分散インデックス
作成
分散クエリー発行
検索用ノード
ここを作った
落ち穂拾い
• 時間的にここまで
• 残りのタスク
– クエリー受け付け用のサーバーを用意
– 作成されたインデックスをそいつらに転送
– クライアントから各サーバーにクエリーを発行
とはいえ
• 商用検索エンジンにするには絶対的に欠けている要素– ランキング
– クローラー
• OSSの分散検索エンジン– Nutch
• OSSの検索エンジン
• あんまり出来が良くない
– Senna• 分散バージョンマダー?
まとめ
• Luceneの使い方を説明
• Hadoopの使い方を説明
• 組み合わせて分散でインデックスを作成する方法を紹介
おわり
% wc -l indexer.java145 indexer.java