Хранение сессий PHP в XCache

()

Механизм сессий в PHP позволяет в течении некоторого времени хранить данные с привязкой к конкретному посетителю. Это удобный инструмент для решения достаточно большого спектра задач, в частности защиты от спама, сохранения настроек до конца сеанса и проч. По умолчанию сессионные данные сохраняются в файлах во временной директории что не является самым оптимальным вариантом и поэтому часто используют альтернативные хранилища.

XCache это модуль для PHP, ускоряющий работу скриптов за счёт кэширования их прекомпилированного байт-кода в памяти. Модуль может работать с PHP, запущенным как fastcgi-процесс или как модуль веб-сервера. Кроме того модуль можно ещё использовать как временное хранилище данных в памяти (по принципу "ключ - значение"). Это позволяет использовать XCache в качестве достаточно быстрого и эффективного хранилища сессионных данных.

Далее будет показано как именно можно сохранять сессионные данные в XCache. Описываемое решение автор использует на этом сайте.

Немного о начальных данных:

  • Сервер под управлением Debian Lenny;
  • Apache2 и php5 из репозитория;

Установим XCache:

apt-get install php5-xcache

После установки приведём файл "/etc/php5/conf.d/xcache.ini" примерно вот к такому виду (Уточните параметры под свои потребности. Детальное их описание есть в документации):

[xcache-common]
zend_extension = /usr/lib/php5/20060613+lfs/xcache.so

[xcache.admin]
xcache.admin.enable_auth = Off

[xcache]
xcache.shm_scheme =        "mmap"
xcache.size  =                96M
xcache.count =                 1
xcache.slots =                8K
xcache.ttl   =                 0
xcache.gc_interval =           0

xcache.var_size  =           16M
xcache.var_count =             1
xcache.var_slots =            8K
xcache.var_ttl   =          3600
xcache.var_maxttl   =     604800
xcache.var_gc_interval =    3600

xcache.test =                Off
xcache.readonly_protection = Off
xcache.mmap_path =    "/dev/zero"


xcache.coredump_directory =   "/tmp"

xcache.cacher =               On
xcache.stat   =               On
xcache.optimizer =            On

[xcache.coverager]
xcache.coverager =          Off

xcache.coveragedump_directory = "/tmp"

Закончив конфигурирование перезапустим веб-сервер:

invoke-rc.d apache2 reload

На этом XCache можно считать сконфигурированным. Теперь перейдём в директорию с нашим сайтом и создадим файл "sessions.php", следующего содержания:

<?php
//==============================================================================
// Функция открывает сессию. В нашем случае ничего делать не надо
function yl_session_open($save_path, $session_name) {
        return TRUE;
}
//==============================================================================

//==============================================================================
// Поскольку на самом деле мы ничего не открывали - закрывать тоже ничего не надо
function yl_session_close() {
        return TRUE;
}
//==============================================================================

//==============================================================================
// Чтение данных из сессии.
// На входе идентификатор сессии. На выходе - строка (сериализованный массив).
function yl_session_read($key) {
        // Препарируем ключ
        $key = 'yl_session_' . md5($key);
        // Извлекаем данные
        $rv = xcache_get($key);
        // Возвращаем результат
        return $rv !== FALSE ? $rv : '';
}
//==============================================================================

//==============================================================================
// Сохранение данных в сессии.
// На входе идентификатор сессии и строка данных для записи
function yl_session_write($key, $val) {
        // Препарируем ключ
        $key = 'yl_session_' . md5($key);
        // Сохраняем данные
        $rv = xcache_set($key, $val, ini_get('session.gc_maxlifetime'));
        // Возвращаем результат
        return $rv;
}
//==============================================================================

//==============================================================================
// Удаление записи о сессии.
// На входе - идентификатор сессии
function yl_session_destroy($key) {
        // Препарируем ключ
        $key = 'yl_session_' . md5($key);
        // Удаляем данные
        $rv = xcache_unset($key);
        return $rv;
}
//==============================================================================

//==============================================================================
// Сборщик мусора.
// Поскольку xcache сам удаляет устаревшие данные - ничего тут делать не надо
function yl_session_gc($maxlifetime) {
        return TRUE;
}
//==============================================================================

// Регистрируем наш обработчик сессий
ini_set('session.save_handler', 'user');
session_set_save_handler(
                'yl_session_open',
                'yl_session_close',
                'yl_session_read',
                'yl_session_write',
                'yl_session_destroy',
                'yl_session_gc'
        );

Теперь во все файлы, в которых необходимо использование сессий, необходимо подключить файл "sessions.php" ДО вызова функции "session_start()". Примерно вот так:

include_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'sessions.php';
session_start();

Так же стоит отметить наличие у XCache интерфейса администратора, позволяющего просматривать статистику работы модуля и в минимальных пределах управлять им, но его рассмотрение выходит за рамки этой статьи.

На этом всё. Приятной работы!

Ключевые слова: php, xcache, session, session storage.

Комментарии:

Anonymous 2011-02-08 23:50:38 (#)

А не рассматривали возможность использовать tmpfs ?
session.save_path = /path/to/mounted/tmpfs

// Sylvia

MooSE 2011-02-09 00:50:55 (#)

Цитата:

А не рассматривали возможность использовать tmpfs ?
session.save_path = /path/to/mounted/tmpfs

// Sylvia

Рассматривал. Но решил что там будет некоторое количество лишних действий. Всё-таки проверка существования файла и чтение/запись из него устроены чуть сложнее чем просто работа с простым массивом в памяти.

К тому же решение с tmpfs абсолютно не масштабируемо. От XCache в любой момент можно перейти к memcached с минимальными правками кода. После этого можно будет обрабатывать запросы не одним сервером, а несколькими бэкендами (такая конструкция проверена на достаточно большом проекте).

Вот как-то так:)

Killy 2011-07-29 22:50:27 (#)

Надеюсь ты сериализуешь сохраняемое значение?

А то xcache имеет багу с сохранением массивов - память начинает утекать.

MooSE 2011-07-30 04:03:02 (#)

Цитата:

Надеюсь ты сериализуешь сохраняемое значение?

А то xcache имеет багу с сохранением массивов - память начинает утекать.

Там уже сериализованные данные прилетают. Особенность механизма сессий в PHP.
Новый комментарий



© 2006-2016 Вадим Калинников aka MooSE