web-dev-qa-db-ja.com

セッション変数:どのくらいのデータが多すぎますか?

単一のユーザーIDのように、少量のデータを格納するために使用されるセッション変数の例を見たことがあるだけです。データベースへのクエリを回避するために、より頻繁にアクセスされるデータをセッション変数に保持する方が効率的ではないかと思います。

たとえば、構築時にそのユーザーに対して定期的に要求されるデータ(ユーザーID、ユーザー名、電子メール、パスワード、およびサイト固有のデータの配列)を収集するユーザークラスを作成し、このインスタンスをセッション変数として保持しています。ユーザーが最初にログインした後、データベースは既にメモリにあるため、ユーザーに関する情報を取得するためにデータベースを照会する必要はほとんどありません。

私は実際にはもっと効率的ですか、それともメモリ使用量でシステムを停止しているだけですか?

補足:クエリなどを最適化することを心配する必要がなく、セッションからデータを取得する方が実際には簡単だと思うので、私がばかでないことを本当に望みます。

32
user1537360

まず、PHPセッションはデフォルトではメモリに保存されません、ディスクに保存されるため、すべてのブロック/書き込むセッションは、メモリではなくディスク領域を使用します(PHPを使用してセッションデータを読み取るまで)。

はい、潜在的にはより効率的ですが、スケーリングしたい場合はそうではありません。その理由は次のとおりです。


セッションへのデータの保存

セッションにsomeデータを格納することは完全に許容されます。理論的には、制限はありません(これを壊したり、プッシュしたりすることは一度もありませんが、より効率的なソリューションに移動するだけです)。ただし、ディスク容量とPHP memory_limit() によって制限されます。

多くの場合、セッションに保存されるデータには次のようなものが含まれます。

  • ユーザー名
  • ハッシュ
  • 登録日
  • その他の変数(ユーザーグループID /キーなど)
  • フラッシュメッセージ
  • (パスワードではありません!)

ただし、トレードオフがあります。トラフィック(および使用量)が増加し、_$_SESSION_に大量のデータを格納している場合、ディスクとメモリの使用量の両方に関して、問題が発生する可能性が非常に高くなります。

私はあなたが提案していることに問題はないと思いますが、あなたがリストしたアイテムと上記の例が重複する場所を超えて、注意が必要です。

1つのサーバー上のディスクは同じセッションを保存しないため、(水平方向に)スケーリングしてディスクベースのセッションを保持する場合、オプション( スティッキーセッション またはストレージエリアネットワークはカップル)があります。別のサーバー上のディスク。


セッションデータの場所

PHPがセッションデータを保存する場所を見つけるには、次のように呼び出します。 session_save_path()

またはCLIで:

_php -r 'echo session_save_path(), "\n";'
_

OSについては言及していませんが、セッションファイルの一般的な場所(さまざまなOSタイプ間)は次のとおりです。

_/tmp 
/var/lib/php5/
/var/lib/php/session
c:/wamp/tmp
_

通常、ディスクに保存されたセッションのファイル名は、_ls -al_を使用して次のようになります。

_-rw-------  1 www www      0 2013-07-09 20:12 sess_bdsdjedmvtas5njhr5530b8rq6
_

特定の期間の後にデッドセッションをクリーンアップするガベージコレクションプロセスがよくあることに注意してください。 OSによって異なりますが、通常、さまざまなLAMPベースのインストールで存在します。


その他のセッションストレージオプション/アプローチ

データベース内
セッションデータは多くの場合、ローカルディスクではなくDBに保存されます。これは、適度なレベルのトラフィックを持つマイクロサイト、小規模サイト、および(実行方法に応じて)中規模サイトの両方に適しています。

他のソリューションと同様に、それは長所と短所があります(たとえば、_/tmp_からセッションファイルを削除するのではなく、クエリを実行することでユーザーを禁止/除外することができます)

メモリ内
大規模な(トラフィックの多い)サイトの場合、特に同時ユーザーの量が多い場合、DBに過度の負荷を追加する代わりに、非常に頻繁にアクセスされる変数またはデータのメモリへの読み書きが高速になります。これは、DBに書き込むことができますが、そうする必要があります( ライトスルーキャッシュ を参照)。また、効率的なアクセスのためにメモリに保持することもできます。

特にメリットのあるテクニックの1つは、メモリキャッシングです。 PHP互換のオープンソースソリューションとして広く使用されている例は Memcached で、1台のサーバーまたは多数の[分散]で使用できます。私はこれを小さな会社だけでなく大企業でも使用しているのを見てきましたが、誰がそれを使用/貢献しているかを見るだけで済みます...

32
nickhar

それはすべてサーバーのリソースと、ウェブサイト/アプリの同時ユーザーに依存します。

各ユーザーが必要とする平均セッションメモリを推定し、それを同時ビジターの平均数で乗算し、これをPHPサーバ。

この計算は、非常に大まかではあるが役立つ方法で、シナリオでどれだけ多すぎるかを推定するのに役立ちます。

編集:メモリとはRAMおよび/またはディスク容量、設定によって異なります).

5
Marcovecchio

他の回答のいくつかは、データをキャッシュするために PHPセッション を使用することを想定している。これは、あるリクエストから次のリクエストで利用できるようにする必要がある一時的なデータを保存するための優れたソリューションです。

しかし、 MySQLユーザー定義変数 を使用するつもりなのでしょうか。これらの変数に長いデータ文字列を格納でき、MySQLサーバー上のデータベーススレッドのスコープでRAMを占有します。しかし、これらのユーザー変数はを使用しますnotセッションが閉じた後もメモリ内に残ります。これらは、あるリクエストから次のリクエストへデータを格納するための良い方法ではありません。

ユーザー変数に大量のデータを格納する唯一の理由は、同じdbセッション中(つまり、同じPHPリクエスト中)に)を後続のSQLクエリで使用する必要があることです。その文字列をdbサーバーからアプリに転送しないようにしてください。そうでない場合は、結果をフェッチしてPHP変数に格納することもできます。

エフェメラルデータを格納する別のソリューションは、 memcached を使用することです。データを直接保存することも、 memcachedをPHPセッション のバッキングストアとして使用することもできます。

2
Bill Karwin

Webパラダイムはステートレスなメモリモデルを奨励することを覚えておいてください。つまり、ページのレンダリング、ページのレンダリング、リソースの解放に必要なものをロードします。

明らかにデータをキャッシュする時間はありますが、はい、セッション変数に情報を保存すると、アプリケーション全体のメモリ使用量が増加し、EACH SESSIONは保存しているNバイトを使用します。

パフォーマンスの問題がない場合は、キャッシュについて心配する必要はありません。一方、キャッシュする必要があり、それが少数のユーザーに対して1台のサーバー上にしか存在しない場合は、心配する必要はありません。 Webファーム全体でセッション変数を使用する場合の欠点に注意してください(使用する場合)。

1
Bahri Gungor