Rubyで並列に処理を実行する
Rubyでスクリプトを組んでバッチとして動かしているのですが、これがとても時間が掛かってしまっています。。。
CSVファイルを作成するバッチなのですが、それに必要なデータを取得するいくつかのSQLが重いのです。
そこで、複数あるSQLを並列処理させることで改善しました。
以下のコードになります。
# プロセスIDを格納する配列を用意 pids = [] # 子プロセスを生成その1 # forkにブロックを指定すると、生成したプロセスでブロックを処理する pids << fork do @data1 = exec_sql1 end # 子プロセスを生成その2 pids << fork do @data2 = exec_sql2 end ・・・ # すべての子プロセスが終了するのを待つ # 戻り値 => [子プロセスID, Process::Statusのオブジェクト] results = Process.waitall # 正常に終了しているかチェック results.each do |r| raise unless pids.include?(r[0]) && r[1].success? end
内容は簡単です。
処理毎にforkして子プロセスを生成し、それに処理させる訳です。
Process.waitallですべての子プロセスが終了するのを待ち、最後に正常終了のチェックをしています。
この場合、すべての子プロセスが終了するのを待つため、一番時間の掛かる処理まで待つことになります。
ただそれでも、一つ一つシングルで処理するよりは早くなるため、マシンスペックに余裕がある場合は試してみても良いかもしれません。
そもそもデータを取得するSQLの最適化を図るべきですが。。。
スレッドでの処理も検討しましたが、Ruby1.8はグリーンスレッドであるため、マルチ処理の恩恵を受けることはできません。
Ruby1.9はネイティブスレッドなので可能なようです。