Perlゼミ

  1. Perl
  2. Mojolicious

ノンブロッキングIOはどの部分がノンブロッキングなのかを理解する / Mojolicious

Mojoliciousが持っているWebサーバーはノンブロッキングIOに対応しています。でもノンブロッキングといったときには、人それぞれにいろんなイメージを抱いていると思いますし、誤解がたくさんある気がするので簡単に解説します。

ノンブロッキングなのは、HTTPリクエストを読み取る部分と書き込む部分

Mojoliciousがノンブロッキングなのは、HTTPリクエストを読み取る部分と書き込む部分です。ですので、たとえば複数の10Mバイトのファイルをレスポンスとして返す場合は、並列で処理することができます。またアップロードで複数の10Mバイトのファイルをリクエストとして受け取るときは、並列に処理することができます。

データベースアクセスはノンブロッキングではない

一般的にデータベースアクセスはノンブロッキングではありません。MySQLやSQLiteへのアクセスはブロッキングな処理になります。

ですから、Mojoliciousを使っているからといって、単純に全部がノンブロッキングになってくれるわけではなくって、データベースへアクセスする部分はブロッキングします。

たとえば処理に30秒かかる処理が、あるとすれば、その部分で30秒ブロッキングします。後続の処理はこれを待っている間は処理を行うことができません。

もしそういう処理がある場合は、ノンブロッキングIOのWebサーバーとしてではなくって、純粋なプリフォークサーバーとして運用するのがおそらくよいでしょう(まだ試していません)。並列処理のクライアント(clients)の数を減らして、プリフォークする数(workers)を増やします。

hypnotoad => {
  clients => 1,
  workers => 10
}

Mojoliciousを使うときは、処理の中に長くブロックする処理があると、デフォルトの設定では、後続の処理がとまってしまうということを覚えておきましょう。

データベースアクセスをノンブロッキングにするにはどうすればよいか

これは難しい問題で、一般的な方法では簡単に解決することができません。アーキテクチャー的には、フレームワークが内部で利用しているひとつのIOループの中に、処理を組み込むしかないのですが、これは非常に困難ですし、各データベースモジュールが対応している必要があります。

一番簡単なのはMojoliciousの作者が提供しているMangoというMongoDBへアクセスするためのモジュールを使うことです(まだ実験的な段階)。Mojolicious + MongoDBという組み合わせであれば、すべての処理をノンブロッキングで行うことが比較的簡単です。

ファイルを読み込む処理はノンブロッキングではない

通常Perlでファイルを読み込む処理を書く場合は、ノンブロッキングな処理ではなくてブロックする処理になります。ですから、大量に処理が必要となるコンテンツ配信サーバーを書きたい場合は、普通のファイル入出力の処理を書いてはいません。

AEをインストールして、AnyEventを使って、ファイルを読み込む部分を、ノンブロッキングで書く必要があります。こうしないと、HTTPリクエストとレスポンスの処理が並列化できても、内部がブロックしてしまうことになるからです。

Perlの書籍
  • 初めてのPerl 第7版

    Perl入門 定番の一冊
  • 業務に役立つPerl

    ログ解析など日本語を含むテキスト処理の実践!
  • 詳説 正規表現

    正規表現の詳細な解説
  • Perlの書籍販売 14冊 »
自己紹介
木本裕紀(きもとゆうき)

Twitter

フォロー、いいね、リツート、コメント歓迎

Youtube

チャンネル登録、いいね、コメント歓迎
Perlの求人広告募集中