Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Нагрузка.... сервер не справляется. Подскажите....
 
 автор: Shorr Kan   (07.06.2006 в 04:35)   письмо автору
 
 

Сервер - специально под конкретный проект. Его мощность велика. Проект предполагает одномоментный заход на одну конкретную страничку 2000-5000 тысяч пользователей. Я знаю, что это уже реализовано, но должен сделать это же...

Итак, каковы проблемы:

1) mysql_max_connections . Сейчас установлено в 500 , но не хватает. Обращение в базу идет непрерывно... сперва выборка... потом запись в статистику (базу), потом вывод на экран. В error_log сразу же ошибки - too many connections.

2) Нагрузка на процессор, память... при 2к-5к одновременных заходов - ну очень велика.

Я вижу нарушение алгоритма... то есть, алгоритм работает хорошо - пока 10 человек одномоментно заходят... но как только цифра становится в три-четыре разряда - сразу рушится всё. Поэтому, исправление алгоритма должно выглядеть так: переодический запрос в базу, генерирование необходимых файлов, пользователи заходят, читают файлы,а не базу, записывают свои заходы во временную статистику. После этого, по крону (раз в 10 минут, например) - скрипт проходится по всей временной статистике, формирует ее нужным образом, закидывает в базу.

Это будет правильно? Или нужно как-то иначе?

   
 
 автор: targa   (07.06.2006 в 04:53)   письмо автору
 
   для: Shorr Kan   (07.06.2006 в 04:35)
 

по п.1

А как у вас реализован коннект к БД?
Если может у вас так?
коннект к бд
запрос
обработка
дисконнект


Т.е. каждый раз при вызове разных частей кода генерирующих страницу производится коннект к серверу БД.
Я делаю коннект в начале кода генерирующего страницу, ID его запоминаю в свойстве класса, формирую страницу и уже потом делаю дисконнект.

Можно еще попробовать денормализовать таблицы (если есть такая возможность). Но это уже переработка проекта.

   
 
 автор: Shorr Kan   (07.06.2006 в 05:04)   письмо автору
 
   для: targa   (07.06.2006 в 04:53)
 

У меня идет заход на страничку, потом запуск энного количества процессов в бэкграунде, sleep(7), чтение временных файлов и их вывод на экран.

Пока действует sleep(7) - работают фоновые процессы. Именно они коннектятся к базе, проверяют пару вещей и создают временные файлы (которые будут прочтены родителем). Один из фоновых процессов фиксирует заход на страничку, реферер, страну... время.

   
 
 автор: targa   (07.06.2006 в 05:53)   письмо автору
 
   для: Shorr Kan   (07.06.2006 в 05:04)
 

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

   
 
 автор: Shorr Kan   (07.06.2006 в 06:27)   письмо автору
 
   для: targa   (07.06.2006 в 05:53)
 

Мысль хороша, но разве можно создать глобальную переменную... Так, чтобы она была видна из другого процесса?
Ну и потом... это решит только долю проблемы. Хорошую, но долю. Перегруз останется. Дело в том, что я проверял это только на двух фоновых процессах.

То есть, неверен сам алгоритм.

Перефразирую своё предположение: нужно перевести максимум из базы - на файлы, дабы делать не многочисленные

<?$c=mysql_fetch_array(mysql_query("SELECT st FROM tbl WHERE rid='$rid' AND hid='$hid';"));
if(
$c[0]==""){...}?>

А, например,
<?if(!file_exists($file)){...}?>
Но этих if, file_exists и file_get_contents - будет действительно много. Файлы будут небольшими - играть я буду именами файлов, а не их содержимым.

Я прав? Нет?

   
 
 автор: Shorr Kan   (07.06.2006 в 11:06)   письмо автору
 
   для: Shorr Kan   (07.06.2006 в 06:27)
 

Не забывайте обо мне... я нуждаюсь в помощи.

   
 
 автор: cheops   (07.06.2006 в 12:12)   письмо автору
 
   для: Shorr Kan   (07.06.2006 в 06:27)
 

>Я прав? Нет?
Да неплохо, это может ускорить процесс значительно, учитывая что почти сразу файлы будут помещены в дисковый кэш, правда спрогнозировать точно нельзя, так как обращение к диску будет гораздо медленее, чем к оперативной памяти, в которой располагается кэш MySQL.

PS Вместо mysql_fetch_array() в этом случае лучше использовать mysql_result().
PPS А можно описать задачу подробнее - нельзя RAM диск или MEMORY-таблицы использовать? У вас пользователи читают информацию или также записывают?

   
 
 автор: cheops   (07.06.2006 в 12:06)   письмо автору
 
   для: Shorr Kan   (07.06.2006 в 04:35)
 

Хм... вот что не нравится, если у вас одновременно 2000-5000 пользователей, то почему mysql_max_connections 500, а не 2000-5000...

PS Вы уверены, что аналогичный проект обслуживает одни сервер, а как минимум не два (под Web-сервер и MySQL-сервер)?

   
 
 автор: Shorr Kan   (07.06.2006 в 12:35)   письмо автору
 
   для: cheops   (07.06.2006 в 12:06)
 

Я даже уверен, что аналогичный проект поддерживает несколько серверов. Но я не понимаю схемы. Вы ее можете представить и описать мне?

Что касается пятисот.. понимаете - поставлено пятьсот, а я тестировал - сотню одновременно (программка wapt)... сотня - уже убивала сервер. Сотня. Это же в ой-ой раз меньше..

   
 
 автор: cheops   (07.06.2006 в 12:44)   письмо автору
 
   для: Shorr Kan   (07.06.2006 в 12:35)
 

Делают так, покупают несколько серверов и объединяют их в локальную сеть, ставят несколько Web-серверов (для начала можно один) с одинаковым содержимым и один MySQL-сервер к которому обращаются несколько Web-серверов (т.е. будет писаться не localhost, а адрес сервера в локальной сети). Так как под MySQL отведена вся память - он выдерживает значительные нагрузки. На вход всей этой конструкции ставят обратный кэширующий сервер, который по возможности кэширует статичные странцы, чтобы снизить нагрузки на сервера.

PS Начиная с MySQL 5.1 в бета-тестирование переходит кластерный вариант MySQL - т.е. теперь можно одну базу данных хранить на нескольких серверах.

   
 
 автор: Shorr Kan   (07.06.2006 в 20:36)   письмо автору
 
   для: cheops   (07.06.2006 в 12:44)
 

Значит, если я переведу на файлы всё - это не поможет?

   
 
 автор: cheops   (07.06.2006 в 21:56)   письмо автору
 
   для: Shorr Kan   (07.06.2006 в 20:36)
 

Если честно, то не уверен - скорее всего узнаете толко если попробуете...

   
 
 автор: Shorr Kan   (09.06.2006 в 11:03)   письмо автору
 
   для: cheops   (07.06.2006 в 21:56)
 

Пропустил это:

"А можно описать задачу подробнее - нельзя RAM диск или MEMORY-таблицы использовать? У вас пользователи читают информацию или также записывают?"

Использовать можно. Только - что это? Насколько я знаю - MEMORY-таблицы уничтожаются сразу, как только происходит отсоединение от Mysql... а оно происходит. И только потом - новое соединение и считывание. А что такое RAM-диск - лишь догадываюсь, что это объем оперативки, выделенный под сохранение данных... Но как это все выгляди и происходит - не понимаю. Что-то нужно настроить каким-то макаром, видимо...

Пользователи - записывают. А раз в пять минут по файлам проходит скрипт и перекидывает информацию в базу.

   
 
 автор: cernos   (09.06.2006 в 14:36)   письмо автору
 
   для: Shorr Kan   (09.06.2006 в 11:03)
 

Почему бі не сделать кеширование?

Скажем кеш не обновлять до тех пор, пока контент не поменяется, кешировать не всю страницу, а отдельное звено! Т.е. если это блок голосования то кешировать его, вывод главного контента то и его кешировать! При изменении главного контента кеш обновляется! Вы сократите свои запросы к БД к минимуму таким образом! ДА и время генерирования страниц!

   
 
 автор: Shorr Kan   (10.06.2006 в 05:11)   письмо автору
 
   для: cernos   (09.06.2006 в 14:36)
 

Нельзя. Нет там никакого контента. Это система статистики. Основная нагрузка происходит из-за записи сатистических данных.

   
 
 автор: targa   (10.06.2006 в 05:42)   письмо автору
 
   для: Shorr Kan   (10.06.2006 в 05:11)
 

Может тогда пойти другим путем и сделать финт ушами?
Если у вас это специализированный проект и много пользователей (т.е. проект востребован), то может имеет смысл перенести его с ХТМЛ платформы?
Т.е. напишите на С++/Делфи/Фоксе специальную программу-клиент которая будет работать с сервером читать/писать данные. Тогда отпадет нужда в ХТТП сервере. Нужен будет только сервер баз данных MySQL или PgSQL, или другой.
Минус такого подхода - если изменятся выходные формы то придется переписывать программу клиент. Плюс - будете экономить на объеме траффика передаваемого по сети (передаете только данные, а не 5% данных и 95% ХТМЛ оформления).

   
 
 автор: Shorr Kan   (10.06.2006 в 08:33)   письмо автору
 
   для: targa   (10.06.2006 в 05:42)
 

Нет, не пройдет этот вариант - я наверное плоховато смог объяснить действие. Суть в том, что всё должно работать на сервере - клиентская программа не подходит, это во-первых. Во-вторых, в конечном счете - всё нужно писать в базу. Но сразу писать туда - нагружно. Поэтому - нужно писать в файлы. А это уже... что Си, что Php - тут просто количество процессов в sleep... при переносе этого всего на RAM-диск - Load уменьшился. Но при увеличении одновременных соединений в wapt (программка стресс-теста) более определенного числа - Load начинает расти. И вот это определенное число - грустно выглядит.

Проще говоря... вы зашли на страничку. Тут же происходит:

$fp=fopen($dir."/".$ip,"w+");fclose($fp);

и таких "происходит" - шесть-восемь штук. Если вы - не "вы", а "вы*N" - то начинаются проблемы.. если эта N больше, чем некий потолок. Но я не люблю низкие потолки...

p.s. Только что подумал... а насколько работоспособна запись fclose(fopen($dir."/".$ip,"w+")); ? Ведь должна же работать...

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования