2009-07-10 3 views
5

私はLAMPを使用してマルチテナントWebアプリケーションを開発しています。すべてのユーザセッションデータは、現在mysqlにテーブルタイプInnoDBとともに格納されています。MySQLセッションテーブルアプローチ

現在のセッションを保存し、セッションハンドラのガベージコレクタ機能を使用してInnoDB(通常のテーブル)と(の間でセッションを移動するために)HEAPテーブルタイプを使用する方法はありますか? )MEMORYテーブル?

また、この設定はクラスタリングが必要なときに影響します&マスター/スレーブ設定 後でですか?事前に

おかげで、custom session handlerを書く ocptimeは

答えて

6

驚くほど簡単ですが、私はMEMORYテーブルよりも、セッションデータを格納するために、おそらくより良い方法があると思います。

CREATE TABLE IF NOT EXISTS `session` (
    `id` char(32) NOT NULL, 
    `data` varchar(20000) NOT NULL, 
    `time_created` timestamp NOT NULL default '0000-00-00 00:00:00', 
    `time_updated` timestamp NOT NULL default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `time_created` (`time_created`), 
    KEY `time_updated` (`time_updated`) 
) ENGINE=MEMORY DEFAULT CHARSET=utf8; 

a previous questionからの変更で持ち上げる)のようなスキーマ何かこのtutorial上または内のリンクで概説として、あなたは、あなたのセッションハンドラ関数を定義するだけで必要があると思います。ガベージコレクション中にセッション情報を保存する場合は、INNODBエンジンを使用して上記のテーブルと同じテーブルを作成し、MEMORYからINNODBテーブルに行をコピーするgc()関数の最後にビットを追加する必要があります。

MEMORYテーブルにはかなりの制限があります。 BLOBまたはTEXTの列を使用することはできません。そのため、上記のような醜いvarchar(20000)があります。最大サイズは16 MBです。多くのユーザーがいる場合、状態をたくさん保つか、ガベージコレクションに問題がある場合は、その制限を超えてクラッシュする可能性があります。

遠い将来にセッション情報を保存する必要がない場合は、memcache session handlerを使用することをお勧めします。私は確かにmemcachedはどんなRDBMS(たとえMEMORYテーブルでも)より速く、それは設計によってうまくスケールされます。さらに、独自のセッションハンドラ関数を記述する必要もありません。

+1

[max_heap_table_size](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_max_heap_table_size)システム変数を調整することで、最大テーブルサイズを増やすことができます。 –

3
InnoDB: ~40 milliseconds Cons: (Slowest) 
MEMORY: ~22 milliseconds Cons: (16MB Max) 
MyISAM: ~25 milliseconds Cons: (Table-level locking) 

私は(GS)を使用していますので、私はmemcacheの操作を行うことはできませんが、それは最高だろう。

私は個人的にはMEMORYの使用を検討していましたが、性能上のメリットがサイズ制限などのコストを上回るかどうかはわかりませんでしたので、最適化するときには良いプログラマがすべきことをすべて行いました。

問題の私のPHPのページはユーザーがログインしているかどうかを確認するためのURLとSQLセッションのグラブに正規表現検索をSmartyのにキャッシュされ、ので、ここで起こっ操作のみであるされています。

とにかく、ここでは結果があります:InnoDBでは、リクエストを待ってから40ミリ秒も待っていました。 (私はこれを開発者ツールでクロムで測定しました)。テーブルをMEMORYに切り替えた後、1回のリクエストにつき〜20ミリ秒が得られました。うわー! 50%の改善!しかし、待って... MyISAMについてはどうですか?私はそれを試して、1回のリクエストにつき22〜23ミリ秒を得ました。ああ。

これは私がテストしたものであり、本格的なアプリケーションではありません。実際のアプリケーションでは、毎秒そのテーブルに何千人もの人が書き込まれ、MyISAMはテーブルレベルのロックを行います。これは悪い可能性があります(Which MySQL database engine is better for storing sessions and session data: MyISAM or InnoDB?)。

私は今、記憶に固執しています。それらのキャッシュされたページの広大な改善ですが、私はあなたのプロフィールをお勧めします!ウェブサイトがすべてのページを再構築している場合、10ミリ秒は重要ではないかもしれません。

+0

テーブルレベルのロックは、大規模アプリケーションのパフォーマンスにどのように影響しますか。誰かがログインのようにセッションに書き込もうとすると、効果的にブロックされますか? – Lightbulb1

+0

@ Lightbulb1、*すべての*ページビューは、データベースのセッションテーブルを更新して、最後にアクセスされた時間を更新する必要があります(セッションの有効期限とセッションがガベージコレクションされる時期を知るため)。 2人が同じ時刻にページを取得した場合、Mysqlは書き込みが完了するまでブロックされるため、他の人の書き込みが終了するまで待つ必要があります([LOW_PRIORITY](http://dev.mysql .com/doc/refman/5.0/ja/update.html)のアップデートで問題を解決できます)。 これは本当に早すぎる最適化です。あなたのサイトが忙しい場合は、memcachedを検討してください。 – andychase

+0

ありがとうございました。私はmemcacheを使用していませんでしたので、私はより多くの研究をする必要があります。これは、将来のための解決策になります。 – Lightbulb1

0

セッションには、InnoDBテーブルを使用してください。私はInnoDBが操作する必要のある特定の行だけをロックしている間に、挿入中のメモリテーブルはテーブル全体をロックすると聞いています。