Pull to refresh

Comments 70

На самом деле, как на меня, не очень удобный интерфейс. Я не вижу разделения по пользователям. Все данные, которые мы указываем — принаджлежат всем пользователям, а не кому-то одному. Лично мне кажется, что лучше было бы, если бы по set заносились значения в массив, а он потом, при деструкте объекта одним запросом заносился в поле, соответствующее текущей сессии. При контруировании же объекта — этот массив должен был бы одним запросом вытаскиваться. Таким образом подход был бы более близким к той сессии, что уже есть в пхп, но был бы на базе б.д.
сессии даны в начале статьи как пример.
код реализует хранилище ключ -> значение, а не хранение сессий в БД
А зачем для этого использовать MySQL?
По моему Memcached или, что лучше REDIS оптимальнее.
ну там же написано, что на дешёвом хостинге.
highload на дешевом хостинге?
на дешевом хостинге можно принять 3 запроса в секунду против 1 запроса в секунду. так не лучше?
мусье знает толк в извращениях )
при текущих ценах на VDS гораздо дороже выходит допиливание подобных решений чем полгода аренды

а в академических целях да, полезная статья
у меня свой сервак, я не извращаюсь_
На самом деле именно такого рода колдунства помогают натренироваться и потом рациональней использовать ресурсы «своего сервера» ;)

Науке известны случаи, когда саппорту удаленному платили просто за перезагрузку подвешенного сервера :)
недооециваете вы дешёвый хостинг. У нас когда-то проект с 300 тыс хитам в сутки висел на хостинге за 150 рублей в месяц. И держался будь здоров(при это не использовались HASH тейблы). Даже задержек особых при ответе небыло.
До поры до времени они все хорошо работают. Проблемы начинаются когда количество пользователй (хостинга в данном случае) переваливает число Х на 1 сервер. Лучшее в данном случае — хорошо закорефанится с админом чтобы он не «подсаживал» на ваш шаренный сервер еще народу. Но тут имхо легче вдс взять.
На дешевом хостинге использование MEMORY таблиц запретят в первую очередь. Так что решение неоднозначное.
Таблицы типа memory не такая уж экзотика. Многие коробочные скрипты используют для хранения сессий. vbulletin, например.
Скорее все будет хорошо.
В первой строчке написано:
Мы говорим о стиуации, когда недоступны memcached и другие специальные средства кэширования.
Похоже в статье не совсем понятно, что речь идет не о сессиях, сессии — это например. Сейчас подправлю.
Поскольку все значения сериализуются, можно делать

$storge->set(session_id(), $_SESSION);

и для автоматизации определить пользовательский session_save_handler.
ну на самом деле, я так знаю, сессии на базе файловой системы не очень эффективны.
то есть обычно делают так — пишут обертку для сессий, а в бэкграунде подключают нужный движок, например такой, как описан в топике.
Сессии на ФС неэффективны только тем, что нельзя сделать несколько фронтендов чтобы данные сессии можно было получить на любом из них.
По производительности они достаточно эффективны за счет файлового кеша ОС.
Несколько фронтендов и шаред-хостинг — оооооочень надуманная проблема.

В общем и целом — не вижу причин в описанной ситуации использовать субд — файловые нативные сессии будут быстрее.
Не понимаю, зачем нужно использовать для сессий субд или фс. Сессия в большинстве случаев помещается в cookie целиком, при этом производительность значительно вырастает за счет отстутствия обращений хоть к диску, хоть куда-либо еще, и можно не беспокоиться о нескольких фронтендах.

А если для сессии мало 4 Кб, то это возможно не совсем правильные сессии. Я в ограничение на большом и посещаем проекте (социальная сеть определенного рода) еще не упирался.
Ну это смотря что за приложение. дайте-ка парочку урл ваших сайтов?
Куки пользователь может отредактировать и напихать неправильных данных. Подставить чужое имя пользователя это ведь не нормально.
url дать не могу, есть личные причины. Но сайт мельком упоминался на хабре несколько раз, не в моих постингах.

Чтобы в cookie пользователь не запихал отсебятину, они подписываются.
Неужели криптостойкие процессы подписи и её проверки менее ресурсоёмки, чем таблица в памяти или файл в кэше ФС? Да и пользователи небезлимитных или медленных тарифов, наверное, не будут рады передавать и принимать при каждом запросе лишний даже килобайт (с учётом кодирования)
Как все сложно. Почему вы сразу это не упомянули?
Большинство разработчиков не будут заморачиваться криптографией и ухудшать скорость аякса.
Выигрыш по сравнению с легкими хранилищами, наверное, не ахти какой большой.
И, кстати, если класть в качестве значения нужно не очень сложные структуры (массивы, строки, НЕ объекты) то есть смысл использовать jsqon_encode вместо serialize. Работает заметно быстрее и хорошо между языками переносится
как на счёт того, что русские символы он переводит в неприятные последовательности?
shock@localhost:~> php -"echo json_encode(array('тест'));"
["\u0442\u0435\u0441\u0442"]

Для меня это стало главной причиной отказа то json_encode
Русские символы кодируются в «неприятные последовательности» согласно формату json для безошибочной транспортировки закодированных объектов(воизбежание проблем с кодировками).
А какая вам разница, как это хранится в базе? Возможности дебага не ухудшаются. В коде ведь вы оперируете с объектом.
я знаю почему оно так кодируется и считаю такое поведение совершенно правильным. но увеличение кода, который содержит русские символы стремится к 6 разам! то есть в итоге один и тот же код на Джсоне и на Сериалайзе может отличаться по размерам приблизительно в 2-5 раз
Так напишите myjson_encode и myjson_decode, который будет кодировать русские символы как вам нужно. Например, вы же наверняка используете utf-8 в своих проектах? Так это же увеличивает размер русского текста в 2 раза!!!
Никаких уникальных индексов

MySQL HEAP таблицы вполне поддерживает UNIQUE индексы типа HASH.
А Вы пробовали создать таблицу запросом, приведённым в статье? Как ни крути, выходит
А Вы пробовали создать таблицу запросом, приведённым в статье? Как ни крути, выходит
ERROR 1163 (42000): The used table type doesn't support BLOB/TEXT columns

Видио из-за того, что для utf8 кодировки используется по 3 байта на символ, и VARCHAR(65536) — это совсем не 65536 байт.

А ещё, если не ошибаюсь, в MySQL есть лимит размера данных одной строки в 64кб (за исключением BLOB полей, но они как раз в MEMORY-таблицах и не поддерживаются).

А ещё «MEMORY tables use a fixed-length row-storage format. Variable-length types such as VARCHAR are stored using a fixed length» (http://dev.mysql.com/doc/refman/5.5/en/memory-storage-engine.html),
т.е. даже если Ваши данные всего несколько символов — в таблице они всё равно откудают место под 65536-символов = 196кб
А почему для UTF-8 используется 3 байта на символ? Вообще-то должно от 1 до 3 в зависимости от самого символа.
Потому, что при создании таблицы мы заранее не знаем, какие данные в ней будут. И если сказано «будем хранить 10 символов», надо понимать «может понадобиться до 30 байт». При DYNAMIC-формате строк (для InnoDB, MyISAM и др.) всё нормально, лишнего не скушается, ограничивается только максимальная длина строки.

А MEMORY-таблицы всегда имеют FIXED-формат строк. Потому под любую строку будет выделяться <макс-длина-строки> * 3 байт места.

И да, я ошибся, 65536 * 3 = 192кб, а не 196. Сорри.
Действительно, это важное замечание — длина строки в таблице MEMORY не может превышать 65536 байт.
А длина VARCHAR указывается в символах. 32 символа отводятся под key — 96 байт. Далее, 65535 / 3 — 96 = 21749, именно столько символов может поместиться в value.
Корректный запрос:

CREATE TABLE `hashtable` (
`key` VARCHAR(32),
`value` VARCHAR(21749),
PRIMARY KEY (`key`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8 COLLATE utf8_bin;
Даже в этом случае
INSERT INTO `hashtable`(`key`, `value`) VALUES ('A', 'B');

скушает 64кб памяти, хотя сохранили мы всего 2 символа.
С чего вдруг? Не путайте CHAR и VARCHAR.
Извиняюсь, был не прав. Действительно «MEMORY tables use a fixed-length row-storage format. Variable-length types such as VARCHAR are stored using a fixed length.»
А Вы сходили по ссылке на MySQL Manual, которую я давал чуть выше?

А там сказано:
MEMORY tables use a fixed-length row-storage format. Variable-length types such as VARCHAR are stored using a fixed length.


Так что я не перепутал VARCHAR и CHAR в данном конкретном случае (использование MEMORY-таблиц).
Уже выше признал свою неправоту :)
Не подумайте, что я придираюсь. Ваша статья полезная и интересная. Я лишь указываю на места, которые требуют доработки :)
Всё круто, но почему ничего не сказали про сброс таблицы на диск? Что будет при аварийном завершении сервера?
Ничего не будет. тут как раз всё логично, при аварийном завершении завершатся и все сессии.
нельзя в таблицах типа MEMRORY хранить жизненно важные данные.
php5 + mysql драйвер (не mysqli или pdo) это противоестественная deprecated связка.
Аргументриуйте.
ЕМНИП, Deprecated только одна функция — mysql_escape_string.
ну и табличка там в самом низу страницы
mysqli_stmt_result_metadata, как говориться — драсте.
без этой функции( и mysqli_stmt_store_result ) далеко на mysqli не уедете
Да? В таком случае, pdo_mysql тоже deprecated?
Рекомендация одного расширения не означает возражения (deprecate) против использования другого.

Тем более, что «deprecated» — термин из мануала с вполне определенным значением.
Да это они пошутили. То regex запретят, то mysql.
Тем не менее новый драйвер mysqlnd реализует функции и mysql и mysqli.
правильно сказали.
mysqlnd — драйвер, не интерфейс
Да? В таком случае, pdo_mysql тоже deprecated?
Рекомендация одного расширения не означает возражения (deprecate) против использования другого.

Тем более, что «deprecated» — термин из мануала с вполне определенным значением.
Не в тот топик похоже написал…
после рестарта сервера memory-таблицу нужно создавать заново? или она уже будет существовать, просто будет пустой?
Будет существовать, просто будет пустой. Определения таких таблиц храняться в отдельных файликах.
хочется еще замеров скорости работы с сессиями fs vs mysql (myisam) vs mysql (memory) vs tmpfs в условиях сферического
Кстати, MEMORY таблицы лочатся per-table. Это так, замечание на случай если у вас реально дешевый хостинг и хочется замутить чтото update-heavy.
Еще memory-таблицы имеют большие проблемы с репликацией. Это конечно не в случае дешевого хостинга, но чтоб другие знали.
Честно, Шпильчин — ты молодец.
Такого велосипеда еще не встречал. Дешевле было бы конечно купить VDS, но ты решился попробовать нечто.
И вроде все слышали об этом, но ни кто не решался на такое исследование.
Теперь я наконец знаю, как использовать тип таблиц MEMORY. Никак.
Все, кто установил vbulletin его используют сами того не подозревая.
Так что читайте и расширяйте кругозор.
Да я сам много нового узнал!)
а где результаты тестов? чутьё подсказывает мне, что с хайлоадом этот способ имеет очень мало общего… какое-то адское memcached-подобное хранилище over mysql, за которое даже с недешёвого shared-хостинга попросят исчезнуть при паре-тройке тысяч уникальных посетителей в сутки…

for ($i=0; $i<10000; $i++) {
     $storage->set($i, $i);
     $storage->check($i);
     $storage->delete($i);
}

С Memory-таблицей — почти 5 секунд, с MyISAM — 7, и может я что-то сделал неправильно, но на InnoDB скрипт работал дольше 30 сек.
я думаю, всем и так ясно, что таблицы memory быстрее, чем myisam и innodb.
интересно сравнить memory vs files vs memcachedb.
UFO just landed and posted this here
Маленькое дополнение, мне говрили что если таблица в памяти заполнена, то MYSQL ее конвертит в дисковую таблицу. КАЖЕТСЯ, кажется данные при этом не теряются.
Нет, просто тогда данные перемещаются в своп-файл на диске. После перезагрузки сервера данные оттуда в таблицу не востанавливаются.
При перезапуске mysql сервера данные сессий потеряются, все залогиненые пользователи разлогинятся.
Уж лучше myisam.
Sign up to leave a comment.

Articles

Change theme settings