JRubyがCRubyに比べて遅すぎる件について
シングルプロセス・ローカル実行
課題は,ログのパースです.一ヶ月分のApache httpdのログをパースして,必要な情報のみを必要なフォーマットで出力するRubyのプログラムを,JRubyとCRubyで実行します.
[hadoop@hadoop_client]$ time cat access_log | ruby log_parser.rb | sort | md5sum - 241213aa784ff569b85a717b92ad27ee - real 54m13.262s user 52m39.431s sys 1m53.115s [hadoop@hadoop_client]$ time cat access_log | jruby log_parser.rb | sort | md5sum - 241213aa784ff569b85a717b92ad27ee - real 40m18.757s user 41m15.511s sys 1m44.323s
結果が同一であることをmd5で確認しています.
CRubyが54分でJRubyが40分なので,3割ほどJRubyの方が早いです.
Hadoop Streaming実行
特に最適化やオプションは付けずに,そのままHadoop Streamingで実行します.
[hadoop@hadoop_client]$ time hdfs dfs -put /var/log/access_log input/ real 2m29.479s user 0m42.045s sys 0m8.383s [hadoop@hadoop_client]$ time hadoop jar /usr/local/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.0.0-cdh4.4.0.jar -file log_parser.rb -mapper 'ruby log_parser.rb' -input input/access_log -output output 14/01/16 12:26:47 WARN streaming.StreamJob: -file option is deprecated, please use generic option -files instead. packageJobJar: [log_parser.rb, /home/hadoop/tmp/hadoop-hadoop/hadoop-unjar4342055864112442739/] [] /tmp/streamjob780153691860120701.jar tmpDir=null 14/01/16 12:33:10 INFO streaming.StreamJob: Output directory: output real 6m23.114s user 0m7.415s sys 0m0.241s [hadoop@hadoop_client]$ time hdfs dfs -cat output/part-00000 | sort | md5sum - 241213aa784ff569b85a717b92ad27ee - real 1m18.972s user 1m20.522s sys 0m1.504s [hadoop@hadoop_client]$ time hadoop jar /usr/local/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.0.0-cdh4.4.0.jar -file log_parser.rb -mapper '/usr/local/jruby/bin/jruby log_parser.rb' -input input/access_log -output output 14/01/16 13:42:28 WARN streaming.StreamJob: -file option is deprecated, please use generic option -files instead. 14/01/16 13:50:25 INFO streaming.StreamJob: Output directory: output real 7m57.466s user 0m7.428s sys 0m0.260s [hadoop@hadoop_client]$ time hdfs dfs -cat output/part-00000 | sort | md5sum - 241213aa784ff569b85a717b92ad27ee - real 1m18.988s user 1m20.450s sys 0m1.555s
実行時間だけ見ると,ここでCRubyは6分23秒,JRubyは7分57秒になります.
JRubyのオプション設定
デフォルトで今のJRubyはCRuby 1.9互換なので,2.0互換にしてみます.
[hadoop@hadoop_client]$ time hadoop jar /usr/local/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.0.0-cdh4.4.0.jar -file log_parser.rb -mapper '/usr/local/jruby/bin/jruby --2 .0 log_parser.rb' -input input/access_log -output output 14/01/16 18:17:44 INFO mapred.FileInputFormat: Total input paths to process : 1 14/01/16 18:17:44 INFO mapreduce.JobSubmitter: number of splits:133 real 8m5.647s user 0m7.524s sys 0m0.268s
返って遅くなりました.7分57秒から,8分5秒になってしまいました.
次に,デフォルトのclientモードからserverモードに変えてみます.
[hadoop@hadoop_client]$ time hadoop jar /usr/local/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.0.0-cdh4.4.0.jar -file log_parser.rb -mapper '/usr/local/jruby/bin/jruby --server log_parser.rb' -input input/access_log -output output 14/01/16 18:28:41 INFO mapred.FileInputFormat: Total input paths to process : 1 14/01/16 18:28:41 INFO mapreduce.JobSubmitter: number of splits:133 real 7m57.703s user 0m7.614s sys 0m0.238s
7分57秒.CRubyの6分台には行きません.
-J-Xmx1024mとかヒープメモリのサイズを変えてもダメ,-Xcompile.mode=FORCEでJITコンパイルから事前コンパイルに変えてもダメ.
(´・ω・`)