Your SlideShare is downloading. ×
0
Hadoop Conference Scala on Hadoop はてな  田中 慎司 stanaka @ hatena.ne.jp http://d.hatena.ne.jp/stanaka/ http://twitter.com/stan...
アジェンダ <ul><li>自己紹介 </li></ul><ul><li>はてなでの Hadoop </li></ul><ul><ul><li>Scala までの道 </li></ul></ul><ul><li>Scala on Hadoop ...
自己紹介 <ul><li>( 株 ) はてな 執行役員 </li></ul><ul><li>担当領域 </li></ul><ul><ul><li>システムアーキテクチャ </li></ul></ul><ul><ul><ul><li>スケーラビリ...
はてなでの Hadoop #1 <ul><li>自作サーバ  10 台 </li></ul><ul><ul><li>CPU: Core2 Quad x 1 </li></ul></ul><ul><ul><li>Mem: 8GB </li></u...
はてなでの Hadoop #2 <ul><li>蓄積されるデータ ( 主にログ ) </li></ul><ul><ul><li>ダイアリー  7G/day </li></ul></ul><ul><ul><li>ブックマーク  5G/day </...
はてなでの Hadoop システム ( 現状 ) Hadoop MapReduce HDFS Reverse Proxy ジョブの 投入 Hatena Fotolife Hatena Graph ログを 時間毎に蓄積 /logs/$servic...
Hadoop <ul><li>2008/5 頃  調査 </li></ul><ul><ul><li>Hadoop Streaming </li></ul></ul><ul><li>2008/8 頃  稼働 </li></ul><ul><ul><...
Hadoop Streaming <ul><li>Java 以外の言語で MapReduce を可能に ! </li></ul><ul><ul><li>Map, Reduce の入出力を標準入力 / 標準出力として扱う ->  map.pl, ...
map.pl #!/usr/bin/env perl use strict; use warnings; while (<>) { chomp; my @segments = split /s+/; printf &quot;%s	%s
&qu...
reduce.pl #!/usr/bin/env perl use strict; use warnings; my %count; while (<>) { chomp; my ($key, $value) = split /	/; $cou...
実行 % hadoop jar $HADOOP_DIR/contrib/hadoop-*-streaming.jar  -input httpd_logs  -output analog_out  -mapper /home/user/work...
ジョブの定義 <ul><li>YAML で定義 </li></ul>- name: latency mapper: class: LogAnalyzer::Mapper options: filters: isbot: 0 conditions...
WebUI
Hadoop Streaming の限界 <ul><li>遅い ←  Perl の問題も .. </li></ul><ul><li>ジョブを KILL しても、プロセスが残ることがある </li></ul><ul><li>HDFS 操作が遅い ...
Scala <ul><li>2003 年登場 </li></ul><ul><li>関数型の特徴を備えた言語 </li></ul><ul><li>普通のオブジェクト指向っぽくも書ける </li></ul><ul><li>JavaVM 上で動作する...
Scala による Quick sort def qsort[T <% Ordered[T]](list: List[T]): List[T] =  list match { case Nil => Nil case pivot::tail =...
WordCount by Java public class WordCount { public static class Map extends MapReduceBase  implements Mapper<LongWritable, ...
WordCount by Scala object WordCount { class MyMap extends Mapper[LongWritable, Text, Text, IntWritable] { val one = 1 over...
Java vs Scala <ul><li>Java </li></ul><ul><li>Scala </li></ul>public void map(LongWritable key, Text value, OutputCollector...
Scala on Hadoop <ul><li>Java と Scala を接続するライブラリが必要 </li></ul><ul><li>SHadoop </li></ul><ul><ul><li>http://code.google.com/...
mapper class MyMap extends Mapper[LongWritable, Text, Text, IntWritable] { val one = 1 override def map(ky: LongWritable, ...
reducer class MyReduce extends Reducer[Text, IntWritable, Text, IntWritable] { override def reduce(key: Text, values: java...
main def main(args: Array[String]) = { val conf = new Configuration() val otherArgs = new GenericOptionsParser(conf, args)...
HDFS 操作 import java.net.URI import org.apache.hadoop.fs._ import org.apache.hadoop.hdfs._ import org.apache.hadoop.conf.Co...
ビルド手法 <ul><li>Maven </li></ul><ul><ul><li>http://maven.apache.org/ </li></ul></ul><ul><ul><li>Java 系のプロジェクト管理ツール </li></ul...
依存関係の記述 <ul><li>Hadoop 関連 jar の登録 </li></ul><ul><li>依存関係の記述 </li></ul><dependency> <groupId>commons-logging</groupId> <art...
ビルド・パッケージ作成と実行 <ul><li>ビルド・パッケージ作成 </li></ul><ul><li>実行 </li></ul>$HADOOP_HOME/bin/hadoop jar  ../maven/hadoop/target/hado...
レスポンス時間の計測  #1 <ul><li>計測方法 </li></ul><ul><ul><li>特定の URL を叩いて、その時間を計測 </li></ul></ul><ul><ul><li>生アクセスログから収集 </li></ul></...
レスポンス時間の計測  #2 Mapper URL などの条件でフィルタ レスポンス時間を記録 Reducer レスポンス時間の分布を計算 後処理 グラフ化 (gnuplot) Fotolife にアップロード (AtomAPI)
レスポンス時間の分布グラフ
良好なレスポンスの例
キャッシュによる影響
まとめ <ul><li>はてなでの Hadoop </li></ul><ul><li>Scala on Hadoop </li></ul><ul><li>色々、触って楽しみましょう ! </li></ul>
<ul><li>Q & A </li></ul><ul><li>[email_address] </li></ul>
Upcoming SlideShare
Loading in...5
×

Scala on Hadoop

7,093

Published on

Published in: Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,093
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
111
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide

Transcript of "Scala on Hadoop"

  1. 1. Hadoop Conference Scala on Hadoop はてな 田中 慎司 stanaka @ hatena.ne.jp http://d.hatena.ne.jp/stanaka/ http://twitter.com/stanaka/
  2. 2. アジェンダ <ul><li>自己紹介 </li></ul><ul><li>はてなでの Hadoop </li></ul><ul><ul><li>Scala までの道 </li></ul></ul><ul><li>Scala on Hadoop </li></ul><ul><li>Scala on Hadoop の応用 </li></ul>
  3. 3. 自己紹介 <ul><li>( 株 ) はてな 執行役員 </li></ul><ul><li>担当領域 </li></ul><ul><ul><li>システムアーキテクチャ </li></ul></ul><ul><ul><ul><li>スケーラビリティ </li></ul></ul></ul><ul><ul><li>サーバ・ネットワーク </li></ul></ul><ul><ul><li>サポート </li></ul></ul>
  4. 4. はてなでの Hadoop #1 <ul><li>自作サーバ 10 台 </li></ul><ul><ul><li>CPU: Core2 Quad x 1 </li></ul></ul><ul><ul><li>Mem: 8GB </li></ul></ul><ul><ul><li>HDD: 3TB </li></ul></ul><ul><li>DC ではなくオフィスに置いて、電源代節約 </li></ul>
  5. 5. はてなでの Hadoop #2 <ul><li>蓄積されるデータ ( 主にログ ) </li></ul><ul><ul><li>ダイアリー 7G/day </li></ul></ul><ul><ul><li>ブックマーク 5G/day </li></ul></ul><ul><ul><li>うごメモ 3G/day </li></ul></ul><ul><li>ジョブ </li></ul><ul><ul><li>300 jobs/day </li></ul></ul>
  6. 6. はてなでの Hadoop システム ( 現状 ) Hadoop MapReduce HDFS Reverse Proxy ジョブの 投入 Hatena Fotolife Hatena Graph ログを 時間毎に蓄積 /logs/$service/$year/$month/$date/$host_access-$hour.log
  7. 7. Hadoop <ul><li>2008/5 頃 調査 </li></ul><ul><ul><li>Hadoop Streaming </li></ul></ul><ul><li>2008/8 頃 稼働 </li></ul><ul><ul><li>Perl による Mapper, Reducer </li></ul></ul><ul><ul><li>YAML でジョブを定義 </li></ul></ul><ul><li>2009/4 WebUI を作成 </li></ul><ul><li>2009/11 Scala 化 ← イマココ </li></ul>
  8. 8. Hadoop Streaming <ul><li>Java 以外の言語で MapReduce を可能に ! </li></ul><ul><ul><li>Map, Reduce の入出力を標準入力 / 標準出力として扱う -> map.pl, reduce.pl を用意するだけ </li></ul></ul><ul><li>通常は入力出力共に HDFS 上に置かれる </li></ul>
  9. 9. map.pl #!/usr/bin/env perl use strict; use warnings; while (<>) { chomp; my @segments = split /s+/; printf &quot;%s %s &quot;, $segments[8], 1; }
  10. 10. reduce.pl #!/usr/bin/env perl use strict; use warnings; my %count; while (<>) { chomp; my ($key, $value) = split / /; $count{$key}++; } while (my ($key, $value) = each %count) { printf &quot;%s %s &quot;, $key, $value; }
  11. 11. 実行 % hadoop jar $HADOOP_DIR/contrib/hadoop-*-streaming.jar -input httpd_logs -output analog_out -mapper /home/user/work/analog/map.pl -reducer /home/user/work/analog/reduce.pl
  12. 12. ジョブの定義 <ul><li>YAML で定義 </li></ul>- name: latency mapper: class: LogAnalyzer::Mapper options: filters: isbot: 0 conditions: - key: Top filters: uri: '^/$' value: $response reducer: class: Reducer::Distribution input: class: LogAnalyzer::Input options: service: ugomemo period: 1 output: class: Output::Gnuplot options: title: &quot;Ugomemo Latency $date&quot; xlabel: &quot;Response time (msec)&quot; ylabel: &quot;Rates of requests (%)&quot; fotolife_folder: ugomemo
  13. 13. WebUI
  14. 14. Hadoop Streaming の限界 <ul><li>遅い ← Perl の問題も .. </li></ul><ul><li>ジョブを KILL しても、プロセスが残ることがある </li></ul><ul><li>HDFS 操作が遅い </li></ul><ul><li>Combiner が定義できない </li></ul>
  15. 15. Scala <ul><li>2003 年登場 </li></ul><ul><li>関数型の特徴を備えた言語 </li></ul><ul><li>普通のオブジェクト指向っぽくも書ける </li></ul><ul><li>JavaVM 上で動作する </li></ul>object HelloWorld { def main(args: Array[String]) { println(&quot;Hello, world!&quot;) } }
  16. 16. Scala による Quick sort def qsort[T <% Ordered[T]](list: List[T]): List[T] = list match { case Nil => Nil case pivot::tail => qsort(tail.filter(_ < pivot)) ::: pivot :: qsort(tail.filter(_ >= pivot)) } scala> qsort(List(2,1,3)) res1: List[Int] = List(1, 2, 3)
  17. 17. WordCount by Java public class WordCount { public static class Map extends MapReduceBase implements Mapper<LongWritable, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException { String line = value.toString(); StringTokenizer tokenizer = new StringTokenizer(line); while (tokenizer.hasMoreTokens()) { word.set(tokenizer.nextToken()); output.collect(word, one); } } } public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable> { …
  18. 18. WordCount by Scala object WordCount { class MyMap extends Mapper[LongWritable, Text, Text, IntWritable] { val one = 1 override def map(ky: LongWritable, value: Text, output: Mapper[LongWritable, Text, Text, IntWritable]#Context) = { (value split &quot; &quot;) foreach (output write (_, one)) } } class MyReduce extends Reducer[Text, IntWritable, Text, IntWritable] { override def reduce(key: Text, values: java.lang.Iterable[IntWritable], output: Reducer[Text, IntWritable, Text, IntWritable]#Context) = { val iter: Iterator[IntWritable] = values.iterator() val sum = iter reduceLeft ((a: Int, b: Int) => a + b) output write (key, sum) } } def main(args: Array[String]) = { …
  19. 19. Java vs Scala <ul><li>Java </li></ul><ul><li>Scala </li></ul>public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException { String line = value.toString(); StringTokenizer tokenizer = new StringTokenizer(line); while (tokenizer.hasMoreTokens()) { word.set(tokenizer.nextToken()); output.collect(word, one); } } override def map(ky: LongWritable, value: Text, output: Mapper[LongWritable, Text, Text, IntWritable]#Context) = { (value split &quot; &quot;) foreach (output write (_, one)) }
  20. 20. Scala on Hadoop <ul><li>Java と Scala を接続するライブラリが必要 </li></ul><ul><li>SHadoop </li></ul><ul><ul><li>http://code.google.com/p/jweslley/source/browse/#svn/trunk/scala/shadoop </li></ul></ul><ul><ul><li>型変換を行うシンプルなライブラリ </li></ul></ul>
  21. 21. mapper class MyMap extends Mapper[LongWritable, Text, Text, IntWritable] { val one = 1 override def map(ky: LongWritable, value: Text, output: Mapper[LongWritable, Text, Text, IntWritable]#Context) = { (value split &quot; &quot;) foreach (output write (_, one)) } }
  22. 22. reducer class MyReduce extends Reducer[Text, IntWritable, Text, IntWritable] { override def reduce(key: Text, values: java.lang.Iterable[IntWritable], output: Reducer[Text, IntWritable, Text, IntWritable]#Context) = { val iter: Iterator[IntWritable] = values.iterator() val sum = iter reduceLeft ((a: Int, b: Int) => a + b) output write (key, sum) } }
  23. 23. main def main(args: Array[String]) = { val conf = new Configuration() val otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs() val job = new Job(conf, &quot;word count&quot;) job setJarByClass(WordCount getClass()) job setMapperClass(classOf[WordCount.MyMap]) job setCombinerClass(classOf[WordCount.MyReduce]) job setReducerClass(classOf[WordCount.MyReduce]) job setMapOutputKeyClass(classOf[Text]) job setMapOutputValueClass(classOf[IntWritable]) job setOutputKeyClass(classOf[Text]) job setOutputValueClass(classOf[IntWritable]) FileInputFormat addInputPath(job, new Path(otherArgs(0))) FileOutputFormat setOutputPath(job, new Path(otherArgs(1))) System exit(job waitForCompletion(true) match { case true => 0 case false => 1}) }
  24. 24. HDFS 操作 import java.net.URI import org.apache.hadoop.fs._ import org.apache.hadoop.hdfs._ import org.apache.hadoop.conf.Configuration object Hdfs { def main(args: Array[String]) = { val conf = new Configuration() val uri = new URI(&quot;hdfs://hadoop01:9000/&quot;) val fs = new DistributedFileSystem fs.initialize(uri, conf) var status = fs.getFileStatus(new Path(args(0))) println(status.getModificationTime) } }
  25. 25. ビルド手法 <ul><li>Maven </li></ul><ul><ul><li>http://maven.apache.org/ </li></ul></ul><ul><ul><li>Java 系のプロジェクト管理ツール </li></ul></ul><ul><li>プロジェクト作成 </li></ul>mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-4:create -DarchetypeGroupId=org.scala-tools.archetypes -DarchetypeArtifactId=scala-archetype-simple -DarchetypeVersion=1.2 -DremoteRepositories=http://scala-tools.org/repo-releases -DgroupId=com.hatena.hadoop -DartifactId=hadoop
  26. 26. 依存関係の記述 <ul><li>Hadoop 関連 jar の登録 </li></ul><ul><li>依存関係の記述 </li></ul><dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.0.4</version> <scope>provided</scope> </dependency> <dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> mvn install:install-file -DgroupId=org.apache.hadoop -DartifactId=hadoop-core -Dversion=0.20.1 -Dpackaging=jar -Dfile=/opt/hadoop/hadoop-0.20.1-core.jar
  27. 27. ビルド・パッケージ作成と実行 <ul><li>ビルド・パッケージ作成 </li></ul><ul><li>実行 </li></ul>$HADOOP_HOME/bin/hadoop jar ../maven/hadoop/target/hadoop-1.0-SNAPSHOT.jar com.hatena.hadoop.Hadoop -D mapred.job.tracker=local -D fs.default.name=file:/// input output mvn scala:compile mvn package mvn clean
  28. 28. レスポンス時間の計測 #1 <ul><li>計測方法 </li></ul><ul><ul><li>特定の URL を叩いて、その時間を計測 </li></ul></ul><ul><ul><li>生アクセスログから収集 </li></ul></ul><ul><li>生アクセスログを分析 </li></ul><ul><ul><li>Hadoop クラスタ </li></ul></ul><ul><ul><ul><li>Core2Quad サーバ 10 台 </li></ul></ul></ul><ul><ul><ul><li>はてなダイアリーのログ 7GB -> 10 分程度で処理 </li></ul></ul></ul><ul><ul><li>分布をグラフ化 </li></ul></ul>
  29. 29. レスポンス時間の計測 #2 Mapper URL などの条件でフィルタ レスポンス時間を記録 Reducer レスポンス時間の分布を計算 後処理 グラフ化 (gnuplot) Fotolife にアップロード (AtomAPI)
  30. 30. レスポンス時間の分布グラフ
  31. 31. 良好なレスポンスの例
  32. 32. キャッシュによる影響
  33. 33. まとめ <ul><li>はてなでの Hadoop </li></ul><ul><li>Scala on Hadoop </li></ul><ul><li>色々、触って楽しみましょう ! </li></ul>
  34. 34. <ul><li>Q & A </li></ul><ul><li>[email_address] </li></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×