持続的接続を理解するために(その2)

2009/12/02 | MySQL

マニュアルに記載のある、持続的接続を使用した際のメリットとデメリット、その他諸々を列挙してみる。

http://www.php.net/manual/ja/features.persistent-connections.php

機能としての違い

  • 機能の違いは持続するか否か、それだけ。

持続的接続を使用するメリット

  • 確立されたコネクション(apacheの子プロセスごとに管理)があると、それを使用するので、接続を確立する処理が減る。まず最初にapacheによってどの子プロセスに処理が渡されるか決められ、その子プロセスが当該接続を確立済みかどうか調べ、確立された接続があればそれを再利用する。だから処理が減る。つまりその分軽くなる。

持続的接続を使用した際のリスク

  • トランザクション使用時にコミットなりロールバックなりしないでスクリプトが終了(意図する・しないにかかわらず)したり、テーブルをロックしてロックを解除せずにスクリプトを終了すると、当該子プロセスのリンクコネクションは「トランザクション途中」や「ロック中」のままとなる。だから次にその子プロセスに処理が割り当てられると、トランザクション途中やロック中な状態のコネクションを使用する羽目になる(多分希望通りに動作してくれない)。
    結論として、register_shutdown_function()関数を使って、後始末をしてくれる関数を用意しておくか、トランザクションやロックを使用する場合は、そもそも持続的接続を使用しないほうが安全。

なんとなく、少しずつだけど理解できてきたような気がする。

持続的接続を理解するために(その1)

2009/12/02 | MySQL

とりあえず理解していることと理解していないことをメモ。

通常はブラウザからウェブサーバにアクセスがあった場合、アクセスごとに処理される。ページを連続して閲覧したとしても、それらは個々のアクセスとして処理される(連続した処理とみなすためには、別途処理を記述する必要がある)。これをふまえ、クライアントからのアクセスでオープンされたデータベースへのリンクコネクションは、通常そのスクリプト終了時に必ず(自動で)閉じられるが、持続的接続を使用すると、一連のスクリプトが終了しても、リンクコネクションは閉じられない(手動で閉じることは出来ない)。

持続的接続によるリンクコネクションが閉じられるタイミングについての記述が見つけられない。ふとマニュアルの設定項目に目を通したらいくつか関連しそうな記述を見つけた。

http://www.php.net/manual/ja/mysql.configuration.php

  • mysql.allow_persistent
    持続的接続を可能にするか否か 。
  • mysql.max_persistent
    プロセスごとの持続的MySQL接続の最大数 。
    そもそも持続的接続ならプロセスで必要な接続は一つでいいのではないのか。
    それともプロセスで複数の持続的接続(違うデータベースへの接続)をおこなうということなのか。
  • mysql.max_links
    プロセスごとの接続最大数。これは持続的接続に限った話ではない。
  • mysql.connect_timeout
    接続の有効時間。応答待ち時間と兼用。

調べれば調べるほどわからないことは増える。とりあえず接続時間(切断されるタイミング)という意味ではmysql.connect_timeoutという設定項目に関連性がありそうだけど、これってタイムアウト処理だから違うよね。

再度マニュアルに戻り「持続的データベース接続」の項を参照した。ここにapacheとの絡みの記述がある。

2番目は、最も一般的ですが、PHPをマルチプロセスWebサーバー(現在はApacheのみが含まれます)のモジュールとして実行する方法です。マルチプロセスサーバーは、通常、実際にWebページを送信する複数のプロセス(子)を管理するプロセス(親)を有しています。リクエストがクライアントから来ると、親プロセスは、他のクライアントにすでに送信を行っていないクライアントの一つに渡します。このため、同じクライアントが2番目のリクエストをサーバーに送信した際に最初のではなく他の子プロセスにより送信が行われる可能性があります。持続的接続がオープンされているとき、SQLサービスにリクエストを行うそれぞれのページはSQLサーバへの確立された接続を再利用することができます。

ブラウザからリクエストがあった場合、apacheのプロセス(親)は空いている子プロセスを使って応答する。だから連続したアクセスであっても、常に同じ子プロセスから応答がかえるわけではない、ということか。でもよくわからない。もう少し読み進むと・・・。

例えば、20の異なっ た子プロセスがSQLサーバーへの持続的接続を行うスクリプトを実行した場 合、各子プロセス毎にSQLサーバーへの20の異なった接続が行われます。

つまりapacheの子プロセスごとにデータベースへのリンクコネクションが張られるということか。これはapacheの子プロセスの最大数とmysql.max_persistentやmysql.max_linksの設定と密接に関係しそうだ(そういえば昔どこかでそういう記述を見た覚えがある)。

しかし、気をつけなければならないことが一つあります。それはデータベースへの接続数を制限して使用している場合に、持続的な子プロセスの接続数がその数を超えると問題が発生し得ることです。もしデータベースの同時接続数の制限が16だとして、サーバに多くのアクセスがあったため17個の子プロセスが接続しようとするとそのうちの一つは接続に失敗します。もしスクリプトにコネクションをシャットダウンしないようなバグ(例えば無限ループ)があると16程度の同時接続しか許容しないデータベースはすぐにダメになってしまいます。使用しているデータベースが、中断された、もしくは使用されていないコネクションをどのように扱うかを確認してみてください。

こういうことだ。今すぐにイメージできないけれど、図を描けばすぐに理解できそうだ。

このページで少し理解が進んだかもしれない。まずCGI版では動作しないということ。これは当たり前。CGI版では接続するたびにPHPのインスタンスが生成される(逆を言えば接続が終了するごとにインスタンスが破棄される)ので、持続のしようがない。マルチプロセスなウェブサーバ(apache)のモジュールや、マルチスレッドなウェブサーバ(IISなど)のプラグインとして動作する場合に限り、持続する。

ということでapacheの子プロセスの生存期間を調べてみるのがよさそう。

MySQL VIEW作成時の制限

2009/12/02 | MySQL

少し前に設計・開発期間が当初の予定より大幅に短くなってしまった案件があった。しかし諸事情で納期は絶対ということもあり、何とか形にしたけれど、当然バグがあるし、月日がたてばボロが出てくる。バグはその場で直していけばよいのだが、データ量が増えてウェブアクセスが重くなったりする部分はそもそも根本の問題なので簡単には直すことが出来ない(設計出来てないわけで・・・)。

現在その問題を解決するにあたり、SQL文を練りなおしている。当時は考える時間がまったくなかったし(とにかくプログラムを書き進めないと絶対間に合わないという状況だった)、データベースをデータ格納庫としか思っていなかったので、結果としてデータがたまってくると複雑な処理をしているところが遅くなってきているのだ。まぁ、こういう問題を経験したからこそ、複雑なシステムを組む際は速度面を考慮してデータを作成しているのだが・・・。

で、ちょっと複雑(専門家にとってみればまだまだ短いのだが)なSQL文を3時間ほどかけて作り、うまく動いて喜んでいたところ、「あ、ちょっとVIEWにしてみよ」っと思ったけどこれが出来ない。MySQLはバージョン5からVIEWが使えるようになったのだが、実はVIEWをほとんど使っていなかった・・・。PostgreSQLなんかは覚えたてのころ(バージョン6とか7だったかな)からVIEWが使えていたわけで、最初からそういう機能があったのでよく使っていたけど、MySQLみたいに途中から追加された機能って勢いがないと踏み込めなくって・・・と言い訳してみる。で、VIEWが作れなくて調べたらマニュアルに記述。

ビューのFROM句でサブクエリを使用することはできません。この制限はいずれ取り除かれる予定です。

「あらまー」。もしくは「ふーん」。一言で終わってしまった。前置き長すぎた。

MySQLのVIEWについて

2009/11/30 | MySQL

教えてもらったことをメモ。

とりあえず「単なるデータの格納庫」として、データベースを使っている。MySQLはバージョン5からVIEWが使えるようになった。作り方や使い方はわかっているが「実際のところVIEWって何」と根本的なことが気になった。MySQLのVIEWについて人に教えてもらった。

MySQLのVIEWは大きく2タイプに分かれる(作成時に指定でき、未指定の場合は自動選択される)。

  • MERGE
    SQLを記述する際にVIEWを呼び出すと、VIEWを定義したSQL文が、当該VIEWを記述した部分に割り当てられて実行される。つまりSQL文に仮の名前をつけておくような感じ。
  • TEMPTABLE
    TEMPTABLEを作成して、そこにVIEWで定義したSQL文の結果を展開し、それがテーブルとして扱われる。

TEMPTABLEもイメージとしてはわかっていたのだが、よく理解していなかったので調べてみた。当たり前だがマニュアルに書いてあった。

MySQL バージョン 3.23 以降では、テーブルの作成時に TEMPORARY キーワードを指定することができます。テンポラリテーブルは現在の接続の間のみ有効で、接続が閉じると自動で削除されます。そのため、異なる 2 つの接続が同じテンポラリテーブル名を使用できます。この場合、それぞれの接続のテンポラリテーブル間でコンフリクトが発生したり、同名の既存のテーブルとの間でコンフクリトが発生したりすることはありません(既存のテーブルはテンポラリテーブルが削除されるまで表示されません)。

現在の接続の間のみ有効ね。ということはpconnectすれば、結構な時間使えるということになるのかな。って・・・pconnectもイメージでしかわかっていない。これも調べておくか。

なにはともあれ、VIEWを使う1番のメリットはSQL文の可読性をあげることのようだ。またTEMPTABLEの場合は、場合によっては速くなることもあれば遅くなることもあるようだ。

PHPとSQLiteでブログを開発する

昨今レンタルサーバは安価になった。以前は「独自ドメインはオプション」みたいなのもあったけど、今は独自ドメインが当たり前。それどころか月額1000円そこそこでマルチドメイン無制限、サブドメイン無制限、メールアドレス無制限なんてレンタルサーバもよく見るようになった。今はXserverがそこそこ安定しているように思う。

エックスサーバー

マルチドメイン無制限なレンタルサーバは他にもたくさんあるみたいだが、データベース数無制限とかデータベース容量無制限なんてサービスは、有名どころのサービスでは見たことがない。「ドメインやサブドメインを複数作ったら、その数だけデータベースも使いたい」というのが人情だと思うのだが・。

そんなときにSQLiteがいい。SQLiteは単なるファイルを設置するだけだから、数に制限もない。データベースに格納する容量もウェブ容量を超えなければ問題ない。だから最近自分のサイトを作るときはSQLiteを最大限活用するようにしている。

しかし、ブログ、PHPで動くブログでSQLiteを採用しているものってほとんど見かけない。Googleで検索してもうまく見つけられない。海外では存在するようだが、日本での知名度はほとんどないに等しいようだ。がんばって使ってみようかとも思ったけど、どうせなら自分好みのブログを、ということで自分で開発してみることにした(車輪の再発明とは言われたくない)。

ということで現在開発中。初版は最低限の機能だけ実装して、超簡単お手軽ブログソフトとして公開する予定。今のところ簡易CMS的な用途で使えるようなレベルにはなっているので、これを充実させていきたい。とりあえず正月明けにリリースしたいと思っている。本当はゆっくり開発したい気もするが、重たい案件を抱えてしまっていて、その息抜きのために自分の開発をしたい、ということが根底にある。現実逃避の手段として、本業と同じことをするって・・・不健康極まりないな。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net