hadoop @ java ccc 2008 spring
TRANSCRIPT
![Page 3: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/3.jpg)
今回のテーマ
• Javaで分散検索エンジンを楽をして作る
– Lucene (検索エンジン)
– Hadoop (MapReduceフレームワーク)
• 個人でも大規模な検索エンジンがさくっと作れる時代ということを示してみる
![Page 4: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/4.jpg)
Agenda
• Luceneの説明
• Hadoopの説明
• Lucene + Hadoopで検索エンジンを構築
• まとめ
![Page 5: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/5.jpg)
(Lucene)とは?
• Javaで書かれた検索エンジン– Yahoo ResearchのDougCutting氏が開発
– Javaのクラスライブラリとして提供され、他のソフトウェアから簡単に使用可能
– 文章サイズにもよるが、数百万件程度なら1台で検索可能
• 検索できるようになるまでの流れ– 文章を登録し、検索用インデックスを作成
– 検索用インデックスを読み込み、クエリーを発行
![Page 6: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/6.jpg)
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();
![Page 7: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/7.jpg)
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();
![Page 8: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/8.jpg)
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();
![Page 9: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/9.jpg)
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();
![Page 10: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/10.jpg)
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();
![Page 11: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/11.jpg)
Hadoopとは?
• Googleの基盤ソフトウェアのクローン
– Google File System
– MapReduce
• Yahoo Research の Doug Cutting氏が開発
– 元々はNutch Crawlerのサブプロジェクト
– Dougの子供の持っているぬいぐるみの名前
• Javaで記述
![Page 12: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/12.jpg)
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
![Page 13: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/13.jpg)
MapReduceの実行フロー
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
![Page 14: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/14.jpg)
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ノードぐらいまではスケールするよ!
![Page 15: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/15.jpg)
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
foo foo foobar bar buzz
入力文書: doc1
![Page 16: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/16.jpg)
例: ワードカウント
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
![Page 17: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/17.jpg)
例: ワードカウント
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
![Page 18: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/18.jpg)
例: ワードカウント
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
![Page 19: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/19.jpg)
例: ワードカウント
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>
![Page 20: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/20.jpg)
例: ワードカウント
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>
![Page 21: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/21.jpg)
例: ワードカウント
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
![Page 22: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/22.jpg)
例: ワードカウント
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
foo foo foobar bar buz
入力文書: doc1
bar: 2buz: 1
foo: 3
![Page 23: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/23.jpg)
作成する検索エンジンの仕組み
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による分散インデックス
作成
分散クエリー発行
検索用ノード
![Page 24: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/24.jpg)
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffleurl3: <html>…url4: <html>…
url1: <html>…url2: <html>…
url5: <html>…url6: <html>…
![Page 25: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/25.jpg)
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffleurl3: <html>…url4: <html>…
url1: <html>…url2: <html>…
url5: <html>…url6: <html>…
![Page 26: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/26.jpg)
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>…
![Page 27: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/27.jpg)
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
インデックス
![Page 28: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/28.jpg)
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
Lucene
インデックス
Lucene
インデックス
![Page 29: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/29.jpg)
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
Lucene
インデックス
Lucene
インデックス
![Page 30: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/30.jpg)
Hadoopによる分散インデックス作成
Data Map
Data Map
Data Map
Reduce
Reduce
Data
Data
Shuffle
Lucene
インデックス
Lucene
インデックス
![Page 31: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/31.jpg)
分散インデックス作成(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);
}
![Page 32: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/32.jpg)
分散インデックス作成(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));
}
![Page 33: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/33.jpg)
分散インデックス作成(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;
} }
![Page 34: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/34.jpg)
以上のコードを実行
• Hadoopのインストール
– 今回は24 (dual core)台のクラスタを使用
• ビルド
• 実行
– bin/hadoop jar indexer.ja net.kzk9.indexer in out
• 分散ファイルシステムのoutというディレクトリにLuceneインデックスが作成されている
– 30Gのドキュメントで約2-3時間?
![Page 35: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/35.jpg)
作成する検索エンジンの仕組み
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による分散インデックス
作成
分散クエリー発行
検索用ノード
ここを作った
![Page 36: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/36.jpg)
落ち穂拾い
• 時間的にここまで
• 残りのタスク
– クエリー受け付け用のサーバーを用意
– 作成されたインデックスをそいつらに転送
– クライアントから各サーバーにクエリーを発行
![Page 37: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/37.jpg)
とはいえ
• 商用検索エンジンにするには絶対的に欠けている要素– ランキング
– クローラー
• OSSの分散検索エンジン– Nutch
• OSSの検索エンジン
• あんまり出来が良くない
– Senna• 分散バージョンマダー?
![Page 38: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/38.jpg)
まとめ
• Luceneの使い方を説明
• Hadoopの使い方を説明
• 組み合わせて分散でインデックスを作成する方法を紹介
![Page 39: Hadoop @ Java CCC 2008 Spring](https://reader034.vdocuments.pub/reader034/viewer/2022052602/55a2447a1a28abfc448b4837/html5/thumbnails/39.jpg)
おわり
% wc -l indexer.java145 indexer.java