Master-X
Форум | Новости | Статьи
Главная » Форум » Программинг, Скрипты, Софт, Сервисы » 
Тема: PHP спецам: по поводу работы с массивом и нагрузкой на хост
цитата
23/12/14 в 01:12
 S_Flash
Есть php файл - галлерея. Смысл php - проверяется полученный get параметр как ID галереи и если данный ID присуствует в ассоциативном массиве, то галерея отображается с нужным контентом и дескрипшеном, иначе 404. Чтобы эта галерея, реже обращалась к диску, я исключил возможные инклуды и включил массив "правелных" ID + Дескрипшенов прямо в файл галереи в конец файла. ПС, пришлось обернуть его в функцию, дабы вызов был в любом месте документа, а не после обьявления массива.

Тут появились следующие вопросы:
- Массив на 2500 записей (ID => Description) занимает где-то 130кб в файле.
- Каждый запуск данного файла это выполнение isset($array[$id]) для проверки вхождения ID галеры, как ключа в массиве.

Всё это мелочи, но, думаю, всему есть рациональное решение. Может стоит просто сгенерить 2500 галер как статику? Или не париться, вынести сериализированый массив в файл или дампом в файл и уже в этом виде инклудить этот файл в скрипт проверки в галерее? Сереилизированный массив, правда, уже весит поболее на диске.
Или подскажите, как протестить нагрузки открытия php файла под убунтой(имитировать нагрузку)? Чтоб попробовать и то и другое и третье для сравнения.
цитата
23/12/14 в 01:25
 Mika
S_Flash писал:
Или подскажите, как протестить нагрузки

Apachebench поставь и играйся с различными реализациями алгоритма.
цитата
23/12/14 в 04:21
 condom007
А зачем держать в php файле массив из 2500 элементов? У тебя ведь наверняка есть какие-то новые элементы со временем появляются и хочется ими как-то управлять... Запихни эти элементы (галереи) в какое-нибудь key-value хранилище (я бы порекоммендовал Redis). И получай одну единственную галерею каждый раз когда идет запрос.
цитата
23/12/14 в 08:11
 Pentarh
Какой нить компайлер типа eaccelerator может решить эту проблему, если это вообще проблема.

Но вообще лучше прибегнуть к какой нить простенькой БД. Sqlite там, Berkeley db или типа того.

Инклюд или его отсутствие вообще ничего не решают ибо дисковый кеш.
цитата
23/12/14 в 09:48
 Stek
S_Flash писал:
Чтобы эта галерея, реже обращалась к диску, я исключил возможные инклуды и включил массив "правелных" ID

Икнлуды быстрые, нет смысла экономить. Если их не десятки на страницу.


S_Flash писал:
Или подскажите, как протестить нагрузки открытия php файла под убунтой(имитировать нагрузку)? Чтоб попробовать и то и другое и третье для сравнения.


Любым бенчмарком, хоть стандартным апачевским.
ab -n 10000 http://вэб-адрес-страницы
цитата
23/12/14 в 10:56
 frec
Stek писал:
Икнлуды быстрые, нет смысла экономить. Если их не десятки на страницу.
Любым бенчмарком, хоть стандартным апачевским.
ab -n 10000 http://вэб-адрес-страницы


Согласен со Stek.
Но я не понимаю есть ли смысл в файл массив ложить. Не забывай, что поедание памяти на каждую загрузку будет 130кб - а это дохрена по меркам оперативки, хоть и быстро очищается оперативка. Почему не использовать базу данных?

Опять же какую проблему нужно устранить? Долго страница грузить? Много просмотров? Тут надо исходить от цели, какую проблему решаем?

Но я как то давно проверял все способы и вот к чему пришел, т.к. я использую VDS сервера где мало оперативки, есть ограничения на количество открытых файлов, лучший вариант - это MySQL.
цитата
23/12/14 в 14:30
 Nux
если у тебя не большой трафик то изобретать ничего не нужно if isset - само оптимально будет и работает оно очень быстро, насчет файла include тоже беспокойство не уместно т.к это кешируется. десятки или сотни "голых" запросов в секунду будут улетать легко... а диск будет грузить не serialize файл а контент галеры если он локальный...

но вот у тебя же там тайтл,+ еще что то захочешь итп ,если так, то на будущее база будет просто удобнее, если ничего не нужно то нах заморочки?
цитата
23/12/14 в 14:55
 Дартаньян
trollface.png если в падло бд то юзай уже memcached
цитата
23/12/14 в 14:59
 Ailk
+1 к дартаньяну, исходный массив храни в мемкеше, и меняй его тока когда удалишь или добавишь галеры.
цитата
28/12/14 в 20:43
 _s_[sov]


Чем плох Redis? Сервер перегрузили и в случае с мемкешем все тютю!
цитата
28/12/14 в 22:35
 PornRank
Офигеть вы тут кашу заварили! Поднимать редис ради 2.5к записей. Вы бы еще посоветовали в мускуль положить, а к нему 10 реплик серверов поднять, чтобы обращаться к нужной реплике по остатку деления ID галеры на 10 icon_lol.gif icon_lol.gif icon_lol.gif

5к записей в ассоциативном массиве и проверять через isset. Вполне терпимо для современных серверов.

А вот рецепт на over9000 галер:
1. Делаем baskets. Каждый basket пусть будет 5к галер.
2. Храним баскеты в виде CSV-файлов, читаем через fgetcsv
3. Пусть ID галеры от 1 и далее. Тогда basket_id = ceil(gallery_id / 5000);
4. Получили ID галеры, вычислили basket_id, прочитали basket до нужной галеры, PROFIT!!!

Для удобства редактирования храним все галеры в мускуле и выгружаем в baskets при изменениях.

PS: Специально фанатам мемкэша - файлы с baskets удобно кэшируются в память при прямых руках. Дисковый кэш на уровне ОС сам определит, какие баскеты чаще юзаются и сам будет держать их тепленькими в памяти.
цитата
29/12/14 в 01:06
 condom007
PornRank писал:


А с чего ты взял, что gallery_id у него цифровой? Может быть gallery_id это чисто текстовый alias без указания цифрового id. А если он не цифровой, то где-то нужно хранить соответствия, либо менять механизм дробления по файлам. Зачем изобретать велосипед, если гораздо грамотнее использовать persistent key > value хранилище а-ля Redis и не заниматься фигней?
цитата
29/12/14 в 01:51
 Stek
Имхо куда проще сделать галереи так, как себе удобнее. Хоть с базой, шаблонизатором и т.п. Просто кешировать результат и отдавать его уже из кеша.
цитата
29/12/14 в 02:28
 Nux
еще лучше разбить все по сервакам, 1 сервак 1 ид(онже ИП) = 1 уникальная галера, очень хороший баллансир получится icon_smile.gif

хех, топик на стеб похож чем то trollface.png

S_Flash: если у тебя трафа не лямы и ничего больше не нужно , то даже не парься а делай как уже делаешь и как тебе самому проще -иначе закопаешься в дебрях...
цитата
29/12/14 в 08:53
 Ailk
PornRank писал:
Офигеть вы тут кашу заварили! Поднимать редис ради 2.5к записей. Вы бы еще посоветовали в мускуль положить, а к нему 10 реплик серверов поднять, чтобы обращаться к нужной реплике по остатку деления ID галеры на 10 icon_lol.gif icon_lol.gif icon_lol.gif

5к записей в ассоциативном массиве и проверять через isset. Вполне терпимо для современных серверов.

А вот рецепт на over9000 галер:
1. Делаем baskets. Каждый basket пусть будет 5к галер.
2. Храним баскеты в виде CSV-файлов, читаем через fgetcsv
3. Пусть ID галеры от 1 и далее. Тогда basket_id = ceil(gallery_id / 5000);
4. Получили ID галеры, вычислили basket_id, прочитали basket до нужной галеры, PROFIT!!!

Для удобства редактирования храним все галеры в мускуле и выгружаем в baskets при изменениях.

PS: Специально фанатам мемкэша - файлы с baskets удобно кэшируются в память при прямых руках. Дисковый кэш на уровне ОС сам определит, какие баскеты чаще юзаются и сам будет держать их тепленькими в памяти.

Зачем это все? Если уж хранить в мускуле, то просто возвращать данные по галере, если результат вернулся фолс отдавать 404. Остальной гемор ваще не в тему. У человека как я понял задача стоит не использовать мускул. Или религия не позволяет, кто его знает.

Upd:
И еще иссет проверяет наличие переменной, т.е. просто существование. Она не перебирает массив (в отличие от аррай_серч) и следовательно хоть 5млн записей, оа будет работать также как и 5к записей...
цитата
29/12/14 в 10:24
 Nux
Цитата:
И еще иссет проверяет наличие переменной


да, самое тяжелое тут - unserialize и чем больше массив тем дольше работать будет функция, а isset можно в расчет времени даже не брать
цитата
29/12/14 в 14:37
 Дартаньян
кстати а не прощели сделать in_array?
цитата
29/12/14 в 14:55
 Nux
проще чем как ? слово isset короче же icon_smile.gif а работает быстрее in_array думаю раз в 100
цитата
29/12/14 в 15:32
 Stek
http://stackoverflow.com/questions/13483219/what-is-faster-in-array-or-isset
Вот тут уже спорили. isset порвал in_array как тузик грелку smail101.gif

Хотя в любом случае тут 2 операции. Сначала проверить , а потом достать при удаче.

Можно просто забить и сделать:
Код:

$res = @$array[$value];
if (!$res) { хреново_нам(); }
else { мужики_живем(); }


Не биллинг же пишем, а тупо галерку показать. Ну а для тех кто "это же говнокод", предлагаю подключить zend и замутить с его экзепшенами icon_lol.gif
цитата
29/12/14 в 16:33
 rx
+1, isset быстрее

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

все остальное - обычно от лукавого trollface.png
цитата
29/12/14 в 16:36
 DF™
В php есть разделяемая память, можете её использовать как кеш для данных вместо Redis и memcache
http://php.net/manual/ru/book.shmop.php
цитата
29/12/14 в 16:41
 Stek
да много чего есть, только смысл настолько усложнять себе задачу.
цитата
29/12/14 в 19:40
 S_Flash
Реально много интересных вещей узнал!
DF™: ваще шокировал меня! smail54.gif


Эта страница в полной версии