Hadoop with Ruby
- 僕がPythonを選んだ理由
実際は
「Kawasaki.rbのきっかけとなった
“Rubyのハッシュが遅かった事例”の紹介」
- NKT77
<B,1>
<C,1>
<E,1>
MapReduce with Hadoop
• WordCountの例
mapper1
mapper2
mapperN
...
<単語,頻度>
<A,1>
<C,1>
<D,1>
<C,1>
<D,1>
<E...
<B,1>
<C,1>
<E,1>
MapReduce with Hadoop
• WordCountの例
mapper1
mapper2
mapperN
...
<単語,頻度>
<A,1>
<C,1>
<D,1>
<C,1>
<D,1>
<E...
Hadoop Streaming
Hadoop Streamingの仕組みを使うと、標準入出力に対応する
任意の言語でMap/Reduceを書くことができる
• WordCountの例
#!/usr/bin/env ruby
$stdin.ea...
Hadoop Streaming
Hadoop Streamingの仕組みを使うと、標準入出力に対応する
任意の言語でMap/Reduceを書くことができる
• WordCountの例
#!/usr/bin/env ruby
$stdin.ea...
当然こんなちょっとした処理も可能
• 大規模データのIDのマッピング
商品1 ID1
商品2 ID2
...
商品100万 ID100万
def load_idmap(idmapfile)
idmap = {}
puts idmapfile
o...
...???
• 大規模データのIDのマッピング
AWSのEMRで実際に実験
変換するID列: 8文字ID列~50億アイテム(LZO形式で26G)
マッピング:~100万組
前頁のMapperで変換を実行し、
念のためにPython実装でも実行...
Rubyの連想配列について
• Rubyは大きな連想配列を持たせると遅くなる(2013年1月)
配列の生成時間:
理想的には線形になるはず、、
50万行 100万行 300万行
秒
マッピングの連想配列サイズ
Rubyの連想配列について
• Rubyは大きな連想配列を持たせると遅くなる(2013年1月)
配列の参照時間:
理想的にはO(1)になるはず、、
秒
マッピングの連想配列サイズ
1万行 10万行 100万行 300万行
RubyのHashについての参考情報
・ハッシュの速度低下についての報告はいくつかある
Inserting hash value slows down as table gets larger
http://www.ruby-forum.com...
RubyのHashについての参考情報
・ハッシュの速度低下についての報告はいくつかある
Inserting hash value slows down as table gets larger
http://www.ruby-forum.com...
1億要素のインサートとルックアップの秒数
Google Hashの効果
○Intの10ケタ文字列をHashに入れるときにIntに変換
python Ruby Ruby
+GoogleHash
insertion 57.19 141.15 46....
EMRのコスト
• 大規模データのIDのマッピング
Ruby(1.9.3) Python(2.7.3)
実行時間 23.2時間 2.0時間
料金 11178円 972円
High Memory Extra Large Instance (m2....
EMRのお値段
• 大規模データのIDのマッピング
AWSのEMRで実際に実験
変換するID列: ~50億IDアイテム(LZO形式で26G)
マッピング:~100万組
前頁のMapperで変換を実行し、
念のためにPython実装でも実行
Ru...
まとめ
• 今回はRubyのハッシュの遅延の事例を紹介
• 大規模のクラウドコンピューティングだと普段
気にしていない速度差もコストに効いてくる
• 今回は1.9.3の実験結果、Rubyは常に進化し
ているので常にベンチマークが必要
ありがとうございました!
Upcoming SlideShare
Loading in …5
×

20130626 kawasaki.rb NKT77

1,549 views

Published on

2013年6月26日にKawasaki.rbで報告した内容です。
Rubyで大きなサイズの辞書を作成するとハッシュの挿入・参照の時間が極端に大きくなる事例についてご紹介しています。
http://kawasakirb.doorkeeper.jp/events/4115
当日は専門家の方の議論を聞くことができ勉強になりました。

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,549
On SlideShare
0
From Embeds
0
Number of Embeds
658
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

20130626 kawasaki.rb NKT77

  1. 1. Hadoop with Ruby - 僕がPythonを選んだ理由 実際は 「Kawasaki.rbのきっかけとなった “Rubyのハッシュが遅かった事例”の紹介」 - NKT77
  2. 2. <B,1> <C,1> <E,1> MapReduce with Hadoop • WordCountの例 mapper1 mapper2 mapperN ... <単語,頻度> <A,1> <C,1> <D,1> <C,1> <D,1> <E,1> <A,1> <B,1> <C,1> <C,1> <C,1> <D,1> <D,1> <E,1> <A,1> <B,1> <C,3> <D,2> <E,1> reducer Map Shuffle Reduce
  3. 3. <B,1> <C,1> <E,1> MapReduce with Hadoop • WordCountの例 mapper1 mapper2 mapperN ... <単語,頻度> <A,1> <C,1> <D,1> <C,1> <D,1> <E,1> <A,1> <B,1> <C,1> <C,1> <C,1> <D,1> <D,1> <E,1> <A,1> <B,1> <C,3> <D,2> <E,1> reducer Map Shuffle Reduce 超大規模なデータも HDFS上に展開すること でマシンを増やして スケールアウト 超大規模なデータも HDFS上に展開すること でマシンを増やして スケールアウト 超大規模なデータも HDFS上に展開すること でマシンを増やして スケールアウト 超大規模なデータも MapReduceで処理する ことでマシンを増やして スケールアウト
  4. 4. Hadoop Streaming Hadoop Streamingの仕組みを使うと、標準入出力に対応する 任意の言語でMap/Reduceを書くことができる • WordCountの例 #!/usr/bin/env ruby $stdin.each do |line| line.strip.split(" ").each do |w| puts "#{w}¥t1" end end line = $stdin.gets w, f = line.strip.split("¥t") w_prev = w f_sum = f.to_i $stdin.each do |line| w, f = line.strip.split("¥t") if w == w_prev f_sum += f.to_i else puts "#{w_prev} #{f_sum}" w_prev = w f_sum = f.to_i end end puts "#{w_prev} #{f_sum}" A B C D A C B E A E Mapper Reducer A 1 A 1 A 1 B 1 B 1 C 1 C 1 D 1 E 1 E 1 A 3 B 2 C 2 D 1 E 2
  5. 5. Hadoop Streaming Hadoop Streamingの仕組みを使うと、標準入出力に対応する 任意の言語でMap/Reduceを書くことができる • WordCountの例 #!/usr/bin/env ruby $stdin.each do |line| line.strip.split(" ").each do |w| puts "#{w}¥t1" end end line = $stdin.gets w, f = line.strip.split("¥t") w_prev = w f_sum = f.to_i $stdin.each do |line| w, f = line.strip.split("¥t") if w == w_prev f_sum += f.to_i else puts "#{w_prev} #{f_sum}" w_prev = w f_sum = f.to_i end end puts "#{w_prev} #{f_sum}" A B C D A C B E A E Mapper Reducer A 1 A 1 A 1 B 1 B 1 C 1 C 1 D 1 E 1 E 1 A 3 B 2 C 2 D 1 E 2 Amazon Web Serviceの ElasticMapReduceのサービスを利用して 簡単にHadoop Streamingが使える ! →Rubyで大規模データ処理!
  6. 6. 当然こんなちょっとした処理も可能 • 大規模データのIDのマッピング 商品1 ID1 商品2 ID2 ... 商品100万 ID100万 def load_idmap(idmapfile) idmap = {} puts idmapfile open(idmapfile).each do |line| rkey, rval = line.strip.split(" ") idmap[rkey] = rval end idmap end idmap = load_idmap("idmap.dat") $stdin.each do |line| line.strip.split(" ").each do |w| puts "#{idmap[w]}¥t1" end end Mapper A B C D A C B E A E 1 2 3 4 1 3 2 5 1 5
  7. 7. ...??? • 大規模データのIDのマッピング AWSのEMRで実際に実験 変換するID列: 8文字ID列~50億アイテム(LZO形式で26G) マッピング:~100万組 前頁のMapperで変換を実行し、 念のためにPython実装でも実行 Ruby(1.9.3) Python(2.7.3) 実行時間 23.2時間 2.0時間
  8. 8. Rubyの連想配列について • Rubyは大きな連想配列を持たせると遅くなる(2013年1月) 配列の生成時間: 理想的には線形になるはず、、 50万行 100万行 300万行 秒 マッピングの連想配列サイズ
  9. 9. Rubyの連想配列について • Rubyは大きな連想配列を持たせると遅くなる(2013年1月) 配列の参照時間: 理想的にはO(1)になるはず、、 秒 マッピングの連想配列サイズ 1万行 10万行 100万行 300万行
  10. 10. RubyのHashについての参考情報 ・ハッシュの速度低下についての報告はいくつかある Inserting hash value slows down as table gets larger http://www.ruby-forum.com/topic/1301386 遅いのはGabage Collectのせい? http://www.platanus.cz/blog/working-with-huge-hashes-in-ruby Google_hashを使うと速くなる? https://github.com/rdp/google_hash/blob/master/README ・ハッシュアルゴリズム解説の例 Ruby http://d.hatena.ne.jp/zariganitosh/20090716/1247709137 チェイン法 Python http://www.laurentluce.com/posts/python-dictionary-implementation/ Open Addressing法
  11. 11. RubyのHashについての参考情報 ・ハッシュの速度低下についての報告はいくつかある Inserting hash value slows down as table gets larger http://www.ruby-forum.com/topic/1301386 遅いのはGabage Collectのせい? http://www.platanus.cz/blog/working-with-huge-hashes-in-ruby Google_hashを使うと速くなる? https://github.com/rdp/google_hash/blob/master/README ・ハッシュアルゴリズム解説の例 Ruby http://d.hatena.ne.jp/zariganitosh/20090716/1247709137 チェイン法 Python http://www.laurentluce.com/posts/python-dictionary-implementation/ Open Addressing法 専門家に報告 とりあえず実験 保留
  12. 12. 1億要素のインサートとルックアップの秒数 Google Hashの効果 ○Intの10ケタ文字列をHashに入れるときにIntに変換 python Ruby Ruby +GoogleHash insertion 57.19 141.15 46.59 lookup 50.50 63.15 25.23 ○要素がIntのとき python Ruby Ruby +GoogleHash insertion 22.53 114.61 47.92 lookup 17.11 43.16 14.06 python Ruby Ruby +GoogleHash insertion 44.11 126.09 102.15 lookup 20.13 60.93 47.94 ○Intの10ケタの文字列 キーが文字列のときは効果が小さい
  13. 13. EMRのコスト • 大規模データのIDのマッピング Ruby(1.9.3) Python(2.7.3) 実行時間 23.2時間 2.0時間 料金 11178円 972円 High Memory Extra Large Instance (m2.xlarge)を使用 6.5 EC2 Compute Units, 10 instances (0.45$/h + 0.09$/h)*X h*10instances * 90円で計算 AWSのEMRで実際に実験 変換するID列: 8文字ID列~50億アイテム(LZO形式で26G) マッピング:~100万組 前頁のMapperで変換を実行し、 念のためにPython実装でも実行
  14. 14. EMRのお値段 • 大規模データのIDのマッピング AWSのEMRで実際に実験 変換するID列: ~50億IDアイテム(LZO形式で26G) マッピング:~100万組 前頁のMapperで変換を実行し、 念のためにPython実装でも実行 Ruby(1.9.3) Python(2.7.3) 実行時間 23.2時間 2.0時間 料金 11178円 972円 High Memory Extra Large Instance (m2.xlarge)を使用 6.5 EC2 Compute Units, 10 instances (0.45$/h + 0.09$/h)*X h*10instances * 90円で計算 クラウドコンピューティングでは、 速度がシビアに金額に効いてくるので怖い
  15. 15. まとめ • 今回はRubyのハッシュの遅延の事例を紹介 • 大規模のクラウドコンピューティングだと普段 気にしていない速度差もコストに効いてくる • 今回は1.9.3の実験結果、Rubyは常に進化し ているので常にベンチマークが必要
  16. 16. ありがとうございました!

×