Публикации

Форумы

Про пути уменьшения нагрузки на базу данных в системе е107
 

Про пути уменьшения нагрузки на базу данных в системе е107

1 2 3 4 5 ... 12 13  
Модераторы: Патрик, net1313, Predator, Perfecthus, Kapman
Автор Добавил
Offline Fanat1k
02.09.08 - 22:25
Фанатик
Сообщений: 336
Все-таки решил написать этот небольшой обзор про пути решения существенной проблемы е107 - нагрузки на базу данных. Пусть это будет моим посильным вкладом в еще живую часть е107 сообщества

е107 пользуюсь с 2005 года, и все это время на различных сайтах переодически всплывают темы насколько этот движок неоптимизирован, как много у него делается ненужных запросов к базе и вообще при посещаемости больше тысячи человек в день он просто умирает.
На мой взгляд это не совсем так - работа с базой построена вполне нормально, и дальше я расскажу как можно существенно уменьшить нагрузку на базу, не прилагая сверхъестественных усилий.
Все что я пишу основывается на трехлетнем опыте владельца самого посещаемого сайта в России на движке е107 - в день стабильно 10-15 тыс пользователей, 200-400 тыс просмотров. По-крайней мере большие мне неизвестные - филка имхо не в счет, у них е107 служит только для новостей, основная часть посещает только форум IPB и основная нагрузка на базу идет именно с него.

Для все еще сомневающихся скриншотик из phpmyadmin - поверьте, без подобной оптимизации дела были бы значительно хуже
+ Показать

Ну и наверное подобная оптимизация важна при посещаемости от 500 человек в день и выше. Если у вас в день ходит 50 человек и смотрит 1000 страниц, то морочится с какой-то там оптимизацией не стоит.

Итак, я использую 4 метода отпимизации работы с е107:
1) Индексы на таблицы
2) Оптимизация запросов в class2.php
3) кэширование результатов работы плагинов
4) оптимизация наиболее медленных запросов

1) Индексы на таблицы
Это абсолютно понятная нормальная человеку вещь (вопрос конечно почему ее нет по-умолчанию в е107). Кому непонятно -
Все нагруженные таблицы, то есть как минимум #comments, #news, #private_msg, #rate, #user, #user_extended должны быть с индексами к соответствующим полям int (кое-где и к varchar)
Например, к таблице #comments у меня забито следующее:
+ Показать


В общем индексов много не бывает (ну кроме как к совсем часто изменяемым полям), поэтому phpmyadmin в руки и вперед

2) Оптимизация запросов в class2.php
Как некоторым здесь должно быть известно, class2.php инклюдится при обращении к любой странице движка e107 (ну кроме может быть rss, printnews и request), поэтому оптимизация запросов в нем сказывается сразу на всем сайте.
Суть самой оптимизации просто - уменьшение количества избыточно выполняемых запросов. К примеру, на мой взгляд совершенно излишне при генерации каждой страницы очищать временные таблицы, удалять забаненных пользователей и тд. Кроме лишней нагрузки на базу толку от этого - ноль. Поэтому нужно немного модифицировать код class2.php таким образом, чтобы подобные запросы выполнялись к примеру 1 раз на 100 (1000, 10000) генераций страниц.
Модификация кода простейшая - перед каждым запросом ставите if (rand(0, X) == 1) { код_запроса; } где X должен быть подобран эмпирически именно для вашего сайта.
Напишу то что изменил лично я, но имхо это с оглядкой на разницу в посещаемости не лишне будет сделать каждому.

+ Показать


Кстати, каждый из этих четырех запросов может вызывать блокировки таблиц, что является еще одним поводом вызывать их пореже

3) кэширование результатов работы плагинов
В е107 очень удобно добавлять различные статистические плагины в правую или левую часть сайта. Например, последние комменты, случайная картинка, последние закачки, кто онлайн и прочее.
Многие злоупотребляют этим делом, в результате при генерации каждой страницы бедный движок трудолюбиво и вхолостую проводит очень много вычислений. Например, для получения 5 последних комментов ему нужно:
1) считать в память всю таблицу комментов
2) если требуется только комменты к например новостям, то отфильтровать ее
3) отсортировать получившиеся данные по времени (а скажем 50 тыс комментов даже при наличии индекса будут отсортированы не так уж и быстро)
4) взять 5 первых комментов

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

Выход очень прост - надо проводить все эти вычисления только один раз, результат записывать в базу, а затем в течение определенного времени (ну например вы считаете, что список последних комментов следует обновлять только каждые 10 минут) просто выводить пользователю.
Можно подумать, что одно обращение к базе (к таблице комментов) просто заменяется обращением к таблице с хранимыми результатами. Это не так. В плагине может быть несколько сложных запросов (как показано выше - фильтрация, сортировка), в то время как вы меняете их на один простой (выборка).
Более того, никто не мещает вам (я например даже рекомендую ) сделать эту выборку отдельно не в каждом плагине, а только один раз при генерации страницы. Тогда получится, что запросы _всех_ подобных плагинов (10, 20, ...) в общем случае будут выполняться за один-единственный select.

Теперь о том как это сделать. Все очень просто:
1) Создаем в базе данных таблицу #mycache
+ Показать


mycache_id - идентификатор плагина
mycache_datetime - время последнего обновления данных данных
mycache_title - заголовок данных
mycache_description - сами закэшированные данные

2) В class2.php где-нибудь в середине добавляем:

+ Показать


3) В плагине который собрались отпимизировать надо "обернуть" весь исполняемый код вставками для анализа последнего обновления и для сохранения данных в базе.
На примере - вот код плагина, выводящего список последних новостей:
+ Показать


Теперь тоже самое, но уже с оберткой:
+ Показать


Кому надо должны понять идею

4) оптимизация наиболее медленных запросов
Это самый сложный путь, поэтому думаю именно вам он может уже и не понадобиться если вы проделали 1-2-3
Поэтому мне и лень уже его расписывать, кому надо, прочитайте про:
1) определение медленных запросов
2) их оптимизацию


В общем как-то вот так. Дураки я думаю до этого места уже не дочитают (если дочитали, не надо писать всякую дичь в комментах), а умные могут попробовать эти пути или описать своим методы

Автор статьи: Fanat1k


мой скромненький сайтик на e107...
Вернуться наверх
Сайт
Популярность сообщения: 4
Рекламный блок
VPS
Наверх

Offline Metaller
02.09.08 - 23:43
Metaller

Сообщений: 1059
Спасибо за статью, я прилепил тему, думаю многим будет инстерестно.

Тем не менее, насчет кеширования - почему игнорируется возможность использования собственной системы кеширования на диск?

Простой пример
+ Показать


Как видно, использовать кеширование действительно просто. Приведенный код используется для вывода меню "Последние версии локализации e107". Данные с сервера e107russian.sourceforge.net запрашиваются раз в 12 часов, при этом меню отображается на каждой странице сайта.
Вернуться наверх
Сайт
Популярность сообщения: 2
 
Offline Fanat1k
03.09.08 - 00:25
Фанатик
Сообщений: 336
Metaller:
1) class ecache работает через файлы, что плохо само по себе
2) я читаю из базы сразу все значения одним запросом, $e107cache->retrieve обращается к файлу при каждом обращение. Итог - если я кэширую к пример 15 разных кусков, то при генерации будет 15 обращений к 15 файлам.
Итог я думаю понятен


мой скромненький сайтик на e107...
Вернуться наверх
Сайт
Популярность сообщения: 3
 
Offline Fanat1k
03.09.08 - 00:32
Фанатик
Сообщений: 336
кстати и третья причина - оставлять каталог с правами 777, куда httpd может записывать (и по-умолчанию выполнять) *.php - спасибо, я как-то избегаю подобного


мой скромненький сайтик на e107...
Вернуться наверх
Сайт
Популярность сообщения: 2
 
Offline Igor&
03.09.08 - 03:05
Сообщений: 196
Большой сенк, логическое завершение спора в соседней ветке.
На e107.org как-то наткнулся на вопрос пользоавтеля создателям:
-Почему плагин "последние сообщения на форуме" сильно грузит базу данных на моем сайте, а на вашем этого не заметно? Вы используете другой плагин?
Ответ был загадочно прост :
-Нет, плагин тот же, но движок mysql нашего сайта был heavily оптимизирован.

Вернуться наверх
Популярность сообщения: 1
 
Offline Metaller
03.09.08 - 14:53
Metaller

Сообщений: 1059
Fanat1k: выводы неверные. Можно 15 кусков сохранить одним и в один файл.

В любом случае - 15 кусков, это те же 15 обращений к базе. Не думаю что обращение к файлу для того чтобы узнать дату его изменения более ресурсоемкий процесс, чем обращение к БД. Опять таки, ничто не мешает сделать период кеширования достаточно малым (например 1 минуту), а $e107cache->retrieve делать через предложенный тобой rand, чтобы снизить количество обращений к файлам.

Раньше кешировать можно было в базу, потом разработчики наоборот убрали эту функцию. Права 777 на папку выставлять в любом случае, чтобы использовать кеширование функций ядра. Или ты отключаешь кешировани в движке совсем и полностью все переписываешь под себя? Я думаю большинство простых пользователей на это не пойдет.

Лежать в кеше могут в общем то и не PHP файлы, они лишь хранят информацию, исполняются скрипты не из папки кеша и это можно запретить через настройки сервера.
Вернуться наверх
Сайт
Популярность сообщения: 0
 
Offline sova
03.09.08 - 16:32
sova

Сообщений: 1148
Я вот что то никак догнать не могу
Сообщение от ... 
1) Индексы на таблицы
Это абсолютно понятная нормальная человеку вещь (вопрос конечно почему ее нет по-умолчанию в е107).
Смотрю базу и вижу что из 43 таблиц моей базы только 4 не имеют индекса.
Сообщение от ... 
В общем индексов много не бывает

А известно ли вам всем что при запросе из таблиц с множественными индексами существуют правило (так уж движок базы устроен ) , что индексный файл будет использоваться только в том случае если все без исключения выбираемые данные проиндексированы

Например:
Если таблица имеет множественный индекс (in1,in2), то соответствующие записи будут выбраны напрямую. Если существуют только одиночные индексы для in1 и in2, то оптимизатор сначала решит, при использовании какого индекса, количество возвращаемых записей будет меньше, а затем из этих записей будет произведена выборка по другому условию.

Если таблица имеет множественный индекс, то любой " префикс " этого индекса может использоваться для оптимизации запроса. Например, если есть индекс (in1, in2, in3), то можно считать, что существуют индексы (in1); (in1,in2); (in1,in2,in3).
Любая другая часть индекса не может быть использована для оптимизации.


так что перегибать палку с индексами не стоит.
И я считаю что с оптимизацией по индексу у e107 не в худшем виде дела обстоят !
Вернуться наверх
Сайт
Популярность сообщения: 1
 
Offline Fanat1k
03.09.08 - 20:40
Фанатик
Сообщений: 336
Metaller, я не собираюсь объяснять почему БД лучше чем куча файлов, не собираюсь рассказывать чем плохи каталоги 777.
Кстати просто ради "прикола" - твой плагин с кэшированием в файл позволяет раскрыть полный путь к папке с е107 (в твоем случае это " /home/***/domains/e107.org.ru/ public_html/", один каталог в пути закрыт звездочками и поэтому является неполным, так что может не стирать это после прочтения). Я думаю многие пользователи будут очень "рады" предоставить кулхацкерам подобную информацию

sova, ну я же просил не писать дичь...


мой скромненький сайтик на e107...
Вернуться наверх
Сайт
Популярность сообщения: 2
 
Offline Marianna
03.09.08 - 22:45
Скорпиоша
Marianna

Сообщений: 550
никто не сможет помочь? боюсь дров наломать и не так что-то сделать как сказанно в этой теме.
у меня под 500 чел в день и больше. и хостеры уже предлагают перрейти на др. тарифный план где степен пика нагрузки больше.

как оптимизоровать еще форум?
Вернуться наверх
Популярность сообщения: 0
 
Offline Metaller
03.09.08 - 23:58
Metaller

Сообщений: 1059
Fanat1k: Если уж на то пошло, серверный путь можно узнать у любого е107 сайта с включенным кешированием, если папка кеша незащищена.
Вернуться наверх
Сайт
Популярность сообщения: 0
 
1 2 3 4 5 ... 12 13  
Про пути уменьшения нагрузки на базу данных в системе е107

Перейти:  Вернуться наверх