膨大になったセッションファイルをどのように処理すればよいですか?


43

私は、Magentoサイトを保持するいくつかのサーバーのシステム管理者として活動しており、時々セッションファイルでいっぱいになります。

これらのファイルを管理することはMagento内でできることではないと言われており、一時的に使用することはオフにできないことを意味すると思いますが、Magentoにこれらの削除を処理する方法がないのは奇妙に思えますファイル?

私の解決策は、このようなことを実行する夜間のcrontabですがfind /path/to/magento/sessions/ -name "sess*" -type f -delete、控えめに言っても気の毒です。

これらを処理する最良の方法は何ですか?

回答:


37

他の人がfind述べたように、カスタム変更時間を使用してセッションファイルを削除する以外に、次のこともできます。

  • データベースにセッションを保存します。もちろん、これはデータベースに負荷をかけるため、最速の方法ではありませんが、その方法でより多くのセッションを処理でき、複数のフロントエンドサーバー間でセッションを共有できます。app/etc/local.xml切り替えることで設定を変更できます

    <session_save><![CDATA[files]]></session_save>

    <session_save><![CDATA[db]]></session_save>
  • セッションストレージとしてmemcachedを使用します。Magentoはデフォルトでこれもサポートしています。app/etc/local.xml.additional設定を見てください。本番環境では使用しませんでしたが、これは少し難しいかもしれないと聞いています。

  • Colin Mollenhoursの素晴らしい拡張機能Cm_RedisSessionを使用して、Redisでセッションを処理します。Redisのセットアップに時間がかかりすぎず、キャッシュにも使用でき(Cm_Cache_Backend_Redisを参照)、RAMキャッシュとディスク上の永続性(memcached、RAMディスクなどとは反対)を組み合わせます。クラッシュします。


1
データベースにセッションを保存することもより安全です。誰かがvarフォルダーを削除したために.htaccessファイルがない場合、外部からセッションファイルにアクセスできません。
エルファン

8
データベースにセッションを保存するのは悪い考えです。これはその目的のために設計されたものではなく、MySQLはセッションストレージ用の非常に貧弱なツールとして機能します。ロックは重要な問題です。もちろん、パージの組み込みサポートもありません。
ベン・レッサーニ-ソナシ

28

ファイルベースのセッションでは、PHPセッションクリーンアップcronによって自動的に整理されます。そのため、ファイルは作成後約7200秒以内に削除される可能性があります。したがって、忙しいサイト(1日あたり3万個)でも、通常は./var/sessionに約4,000のセッションファイルしかありません。これは、ローエンドのLinuxサーバーでもありません。

ただし、クリーンアップは実際にはcronの動作に依存しています。これは通常、Magentoの./var/sessionディレクトリを参照しません。したがって、新しいシステムcronをセットアップする必要があります

/usr/bin/find /home/myuser/public_html/var/session -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 -exec rm {} \; >/dev/null 2>&1

セッションのデフォルトのクリーンアップ期間は7200秒であり、これは十分すぎるはずですが、上記に合わせて変更できます。

Memcacheセッションでは、TCP / IPが唯一のオーバーヘッドです。単一サーバー展開の場合、ファイルベースよりも遅くなります。したがって、代わりにUNIXソケットを使用すると、オーバーヘッドがなくなり、セキュリティが向上します。しかし、それでも、割り当て可能なRAMの量に関して、顧客セッションは切り捨てられます。Magentoセッションの平均は4Kbです。したがって、割り当てるMBごとに256個のアクティブセッションをサポートできます。したがって、顧客がカート/セッションをランダムに失うことを避けるために、適切な制限を設定してください。また、Memcacheデーモンを再起動すると、既存のセッションがすべて消去されます(BAD!)。

Redis(ネイティブではないが、拡張機能を介して利用可能)を使用すると、Memcacheと同様のレベルのサポートが得られますが、永続性の利点が追加されます(使用する必要があります)。Cm_Redis拡張機能を使用すると、セッション圧縮を利用することもできます。この拡張機能は、CEとEEの両方の展開で非常にうまく機能することがわかりました。

DBの場合、デフォルトのプルーン有効期限設定は強力な1週間であるため、上記のストアサイズ(例:1日あたり3万ユニーク)を使用すると、core_cache_sessionのDBテーブルサイズが約7GBになります。ほぼすべてのセッションベースの操作に対して、ストアが完全に停止します。

大規模(1日あたり23万のユニークビジター)と小規模(1日あたり<1kのユニークビジター)の両方のストアをホストした経験から、私たちの推奨事項は次のとおりです。

単一サーバー展開-ファイル

マルチサーバー展開-Redis(Magentoのメインキャッシュとは別のデータベースを使用)

http://magebase.com/magento-tutorials/magento-session-storage-which-to-choose-and-why/comment-page-1/#comment-1980にいくつかの本当に徹底的な返信を書いた


2
クリーンアップcronがセッションをクリアすると想定されている場合、なぜ失敗するのですか?
グース

12

少し前に関連する質問をしました:

https://stackoverflow.com/questions/7828975/php-garbage-collection-clarification

私が見つけられなかったのは(新しい仕事のためにその仕事を辞め、元の問題は他の人のものになりました)、Magentoのセッションがこれらの設定を尊重するか、Zend(およびおそらくzend.iniのいくつかの種類)を使用してセッション処理を実装するかどうかです設定ファイル)。

見るべきPHP設定:

session.gc_maxlifetime session.gc_probability session.gc_divisor

http://php.net/manual/en/session.configuration.php#ini.session.gc-probability


私はこれを自分で知りたいと思っています。私の経験から、Magentoはこれらの設定を尊重していないようです(GBのセッションファイルの価値があると考えているので、ある時点でGCがトリガーされると仮定しても安全です)。そのため、Benが推奨するスクリプトをcronジョブとして設定して安全にしています。
ハビエルビジャヌエバ

7

通常、cronジョブで十分ですが、次の点に注意してください。

1)セッションをsession.gc_maxlifetimephp -i | grep session.gc_maxlifetime)秒以内に設定します(これにより、有効期限が切れたセッションがphp.iniまたは.htaccessによるガベージコレクションの準備のために設定されます)

2)セッションをデータベースに保存することができます。これを行う方法の詳細については、こちらを参照してください(このオプションは、カスタムmagentoモジュールを使用して管理する方が簡単な場合があります)

3)考慮すべきもう1つのオプションは、Memcachedウィッチもサーバーを高速化できることです(ただし、質問に完全には接続されていませんが、知っておくと便利です)

詳細については、この質問を参照してください:https : //stackoverflow.com/questions/4353875/how-long-do-the-magento-session-files-need-to-be-kept


2
cronjobを使用してすべてのセッションファイルを単純に削除することは受け入れられません。cronが実行される10分前にユーザーがカートにアイテムを追加するとどうなりますか?彼らのカートはきれいに拭かれます!PHPのガベージコレクションが機能しない場合は、それを把握する必要があります。
-davidalger

+1 @davidalger良い点、私は
cronjob

1
@davidalger-PHP自身のガベージコレクションはcronを介して動作します。それは単にfind古いファイルをすべてsess.gc_maxlifetime削除し、削除します。cronを介したセッションの削除は、通常の安全で受け入れ可能な動作です。
ベン・レッサーニ-ソナシ

1
実際には、そうではありません。セッションガベージコレクションは、PHPスクリプトの実行中にセッションが開始されると実行されます。どのように頻繁にガベージコレクションが実行されることの値に依存session.gc_probabilityしてsession.gc_divisorsession.gc_maxlifetimeセッションストレージがグローバルであり、そのスクリプトの実行が他のスクリプトセッションオブジェクトをクリーンアップするので、異なるスクリプトが最小値のスクリプトに対して異なる値を持っている場合、スタッフが待機する時間を決定します。
-davidalger

5

すべてのセットアップで、ログとvarディレクトリのクリーニングを時々処理するmaintenance.phpファイルがあります。セッションはデータベースまたはファイルシステムに保存する必要があるため、このメンテナンスファイルは両方をクリーンアップします。(以下のコードを参照)。

次のコマンドをcronジョブとして実行して、ログをクリーンアップできます。

php maintenance.php clean=log

上記のコマンドは、次の出力を生成します。

catalogindex_aggregation has been truncated
catalogindex_aggregation_tag has been truncated
catalogindex_aggregation_to_tag has been truncated
catalog_compare_item has been truncated
dataflow_batch_export has been truncated
dataflow_batch_import has been truncated
log_customer has been truncated
log_quote has been truncated
log_summary has been truncated
log_summary_type has been truncated
log_url has been truncated
log_url_info has been truncated
log_visitor has been truncated
log_visitor_info has been truncated
log_visitor_online has been truncated
report_compared_product_index has been truncated
report_event has been truncated
report_viewed_product_index has been truncated

次のコマンドをcronジョブとして実行して、varフォルダーをクリーンアップできます。

php maintenance.php clean=var

上記のコマンドは、次の出力を生成します。

downloader/.cache/* has been emptied
downloader/pearlib/cache/* has been emptied
downloader/pearlib/download/* has been emptied
var/cache/ has been emptied
var/locks/ has been emptied
var/log/ has been emptied
var/report/ has been emptied
var/session/ has been emptied
var/tmp/ has been emptied

実際のコード(local.xmlファイルへのパスを調整することを忘れないでください):

<?php
$xml = simplexml_load_file('./app/etc/local.xml', NULL, LIBXML_NOCDATA);

$db['host'] = $xml->global->resources->default_setup->connection->host;
$db['name'] = $xml->global->resources->default_setup->connection->dbname;
$db['user'] = $xml->global->resources->default_setup->connection->username;
$db['pass'] = $xml->global->resources->default_setup->connection->password;
$db['pref'] = $xml->global->resources->db->table_prefix;

if (!isset($argv[1]) || !stristr($argv[1], 'clean=')) {
    echo 'Please use one of the commands below:' . PHP_EOL;
    echo 'php maintenance.php clean=log' . PHP_EOL;
    echo 'php maintenance.php clean=var' . PHP_EOL;
    die;
}

$method = str_replace('clean=', '', $argv[1]);

switch ($method) {
case 'log':
    clean_log_tables();
    break;
case 'var':
    clean_var_directory();
    break;
default:
    echo 'Please use one of the commands below:' . PHP_EOL;
    echo 'php maintenance.php clean=log' . PHP_EOL;
    echo 'php maintenance.php clean=var' . PHP_EOL;
    break;
}

function clean_log_tables() {
    global $db;

    $tables = array(
        'catalogindex_aggregation',
        'catalogindex_aggregation_tag',
        'catalogindex_aggregation_to_tag',
        'catalog_compare_item',
        'dataflow_batch_export',
        'dataflow_batch_import',
        'log_customer',
        'log_quote',
        'log_summary',
        'log_summary_type',
        'log_url',
        'log_url_info',
        'log_visitor',
        'log_visitor_info',
        'log_visitor_online',
        'report_compared_product_index',
        'report_event',
        'report_viewed_product_index'
    );

    mysql_connect($db['host'], $db['user'], $db['pass']) or die(mysql_error());
    mysql_select_db($db['name']) or die(mysql_error());

    foreach($tables as $v => $k) {
        @mysql_query('TRUNCATE `'.$db['pref'].$k.'`');
        echo $db['pref'] . $k . ' has been truncated' . PHP_EOL;
    }
}

function clean_var_directory() {
    $dirs = array(
        'downloader/.cache/*',
        'downloader/pearlib/cache/*',
        'downloader/pearlib/download/*',
        'var/cache/',
        'var/locks/',
        'var/log/',
        'var/report/',
        'var/session/',
        'var/tmp/'
    );

    foreach($dirs as $v => $k) {
        exec('rm -rf '.$k);
        echo $k . ' has been emptied' . PHP_EOL;
    }
}

5

Magento CMSなど(古いセッションをクリーンアップしない)の場合、php.ini設定に基づいてcronジョブを使用します。

PHP5 / Ubuntu 14.04 / Debian

php5のシステムcron.dセットアップでは、Magentoの./var/session(またはデフォルトのセッションフォルダー(Ubuntuの場合は/ var / lib / php5、他のほとんどのLinuxの場合は/ var / lib / php5 / sessionsまたは/ tmp /)以外はクリーンアップされませんdists)。

ただし、デフォルトのphp5 / Debianシステムcronに従って、「sessionclean」と「maxlifetime」を引き続き使用できます。

コマンドラインから試すことができる例:

# sudo /usr/lib/php5/sessionclean /var/www/{yoursite}/var/session $(/usr/lib/php5/maxlifetime)

そのため、それをシステム/ルートcrontabまたはセッションファイルの読み取り/書き込み権限を持つユーザーのcrontabに組み込むだけです。

$ sudo crontab -e

これを追加すると、システムphp cronのようになります。

20,40 * * * * [ -x /usr/lib/php5/maxlifetime ] && [ -x /usr/lib/php5/sessionclean ] && [ -d /var/www/*/var/session ] && /usr/lib/php5/sessionclean /var/www/{yoursite}/var/session $(/usr/lib/php5/maxlifetime)

または-これらのファイル/ディレクトリが存在することがわかっているため:

20,40 * * * * /usr/lib/php5/sessionclean /var/www/*/var/session $(/usr/lib/php5/maxlifetime)

現在、管理可能な量のセッションがあり、php.ini(cli)設定を介してデフォルトのガベージコレクション/ライフタイムを介してクリーンに維持されています。

(上記のワイルドカードを残すか、サイト名に置き換えることができます。)

編集(PHP7 / Ubuntu 16.xx / Debian):

「sessionclean」スクリプトが変更され、maxlifetimeスクリプトが削除されました。system / php cronジョブの場合、1つのスクリプトになりました。ファイル呼び出しはスクリプトに対して静的であるため、これを実際に使用することはできません。

システムがクリーンアップしていない場合でも、古いphp5 sessioncleanスクリプトを使用できます。できることは、古いDebian php5パッケージを取得してsessioncleanそこから抽出することです。または、これをスクリプト領域にコピーするだけで済みます(適切な/ var / www /(site)permissions / ownershipを与えます):

#!/bin/sh

# first find all used files and touch them (hope it's not massive amount of files)
[ -x /usr/bin/lsof ] && /usr/bin/lsof -w -l +d "${1}" | awk -- '{ if (NR > 1) { print $9; } }' | xargs -i touch -c {}

# find all files older then maxlifetime
find "${1}" -depth -mindepth 1 -maxdepth 1 -ignore_readdir_race -type f -cmin "+${2}" -delete

また、名前を変更することをお勧めします。そのため、新しいphp 'sessionclean' cronjobと混同しないでください。次に、独自の「maxlifetime」番号を次のようにプラグインできます。

     20,40 * * * * /home/-username-/scripts/MySessionClean /var/www/*/var/session 61

(61はサンプルの経過時間(分単位)で、「MySessionClean」は上記からダウンロードまたはコピーされた名前変更されたphp5スクリプトです)。

この方法では、php.ini / env呼び出しを完全に回避します。

(2016年12月13日編集:DEBIAN ARCHIVE REPO LINKを更新)


3

これらすべての古いセッションファイルからデータベースを定期的にクリアしました。Magento Optimizerをインストールするまで手作業はいらいらしていました。また、キャッシュは絶えず更新されますが、製品と静的ブロックを変更した後は手動で更新しません。ああ、はい、エラー報告と放棄されたカートも同様に掃除されます。


3

上記のすべてのコメントの中で、これは簡単な解決策であり、長いスクリプトやサードパーティの拡張機能をインストールして古いセッションファイルを管理し、新しいセッションファイルを保持するよりも優れていると思います。

  1. magentoフォルダーの下にファイル名「clean_session.sh」を作成します。
  2. これらの行を貼り付けます。

#!/bin/bash
# delete session files older than 14 days
find /home/DOMAIN/public_html/var/session -name 'sess_*' -type f -mtime +14 -exec rm {} \;

  1. その後、cronjobを毎週スケジュールして、クリーンアップを実行できます。

1 1 * * 6 /bin/sh /home/DOMAIN/public_html/clean_session.sh

  1. ファイルを次のように実行可能にすることを忘れないでください

chmod u+x clean_session.sh

  1. また、次のように実行することもできます

sh clean_session.sh


3

私の場合、magento/var/1週間以上前のセッションファイルを削除するためにディレクトリに配置された次のスクリプトを実行します(-mtime +7)。

#!/bin/sh
# Place this script in magento/var/ directory

for n in `seq 0 9`
  do
    for u in `seq 0 9`
    do
      for m in `seq 0 9`
        do
          name="sess_"$n$u$m*
          echo $name
          find session/ -name $name -type f -mtime +7 -delete
          echo $name ok
      done
      for m in {a..z}
        do
          name="sess_"$n$u$m*
          echo $name
          find session/ -name $name -type f -mtime +7 -delete
          echo $name ok
      done
    done
      for u in {a..z}
      do
        for m in `seq 0 9`
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
        for m in {a..z}
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
    done
done

for n in {a..z}
  do
    for u in `seq 0 9`
      do
        for m in `seq 0 9`
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
        for m in {a..z}
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
    done
    for u in {a..z}
      do
        for m in `seq 0 9`
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
        for m in {a..z}
          do
            name="sess_"$n$u$m*
            echo $name
            find session/ -name $name -type f -mtime +7 -delete
            echo $name ok
        done
    done
done

それは私の最初のbashスクリプト(リビジョン2)であり、いくつかの面で最適化できると思います。最適化の提案は受け付けています。

このスクリプトは、https//gist.github.com/Nolwennig/a75dc2f8628be2864bb2で取得できます


0

var / sessionディレクトリを空にするスクリプトを作成しました。これをcronジョブに追加して、1日に1回実行します。これは十分で、必要に応じて調整する必要があります。セッションディレクトリがいっぱいになると、cpanelまたはsshを介してファイルを削除することはできません。このスクリプトは、magentoのルートディレクトリに配置するだけでトリックを実行します。

<?php
function adjustSessionFiles($dir, $pattern = "*")
{
    $files = glob($dir . "/$pattern");
    foreach ($files as $file) {
        if (is_dir($file) and !in_array($file, array('..', '.')))  {
            adjustSessionFiles($file, $pattern);
        }else if(is_file($file) and ($file != __FILE__)) {
            unlink($file);
        }
    }
}
$dir = __DIR__ . DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'session';
adjustSessionFiles($dir);

このスクリプトの問題は、古いセッションだけでなく、すべてのセッションが削除されることです。したがって、誰も1日以上ログインできず(これを毎日実行する場合)、これが実行されると、すべてのカートは空になります(したがって、1日より長く保持できるカートはありません)。
simonthesorcerer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.