| |
|
|
| | Сервер - специально под конкретный проект. Его мощность велика. Проект предполагает одномоментный заход на одну конкретную страничку 2000-5000 тысяч пользователей. Я знаю, что это уже реализовано, но должен сделать это же...
Итак, каковы проблемы:
1) mysql_max_connections . Сейчас установлено в 500 , но не хватает. Обращение в базу идет непрерывно... сперва выборка... потом запись в статистику (базу), потом вывод на экран. В error_log сразу же ошибки - too many connections.
2) Нагрузка на процессор, память... при 2к-5к одновременных заходов - ну очень велика.
Я вижу нарушение алгоритма... то есть, алгоритм работает хорошо - пока 10 человек одномоментно заходят... но как только цифра становится в три-четыре разряда - сразу рушится всё. Поэтому, исправление алгоритма должно выглядеть так: переодический запрос в базу, генерирование необходимых файлов, пользователи заходят, читают файлы,а не базу, записывают свои заходы во временную статистику. После этого, по крону (раз в 10 минут, например) - скрипт проходится по всей временной статистике, формирует ее нужным образом, закидывает в базу.
Это будет правильно? Или нужно как-то иначе? | |
| |
|
|
| |
|
|
| |
для: Shorr Kan
(07.06.2006 в 04:35)
| | | по п.1
А как у вас реализован коннект к БД?
Если может у вас так?
коннект к бд
запрос
обработка
дисконнект
Т.е. каждый раз при вызове разных частей кода генерирующих страницу производится коннект к серверу БД.
Я делаю коннект в начале кода генерирующего страницу, ID его запоминаю в свойстве класса, формирую страницу и уже потом делаю дисконнект.
Можно еще попробовать денормализовать таблицы (если есть такая возможность). Но это уже переработка проекта. | |
| |
|
|
| |
|
|
| |
для: targa
(07.06.2006 в 04:53)
| | | У меня идет заход на страничку, потом запуск энного количества процессов в бэкграунде, sleep(7), чтение временных файлов и их вывод на экран.
Пока действует sleep(7) - работают фоновые процессы. Именно они коннектятся к базе, проверяют пару вещей и создают временные файлы (которые будут прочтены родителем). Один из фоновых процессов фиксирует заход на страничку, реферер, страну... время. | |
| |
|
|
| |
|
|
| |
для: Shorr Kan
(07.06.2006 в 05:04)
| | | Может тогда перед запуском процессов в бэкграунде, сделаете коннект к БД, запомните его идентификатор в глобальную переменную или куда-нить еще (главное чтоб смогли из любого места достать). Делаете свои запросы, юзая этот коннекшн (один для всех запросов). А когда все запросы сделаны делаете дисконнект. | |
| |
|
|
| |
|
|
| |
для: 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 в 06:27)
| | | Не забывайте обо мне... я нуждаюсь в помощи. | |
| |
|
|
| |
|
|
| |
для: Shorr Kan
(07.06.2006 в 06:27)
| | | >Я прав? Нет?
Да неплохо, это может ускорить процесс значительно, учитывая что почти сразу файлы будут помещены в дисковый кэш, правда спрогнозировать точно нельзя, так как обращение к диску будет гораздо медленее, чем к оперативной памяти, в которой располагается кэш MySQL.
PS Вместо mysql_fetch_array() в этом случае лучше использовать mysql_result().
PPS А можно описать задачу подробнее - нельзя RAM диск или MEMORY-таблицы использовать? У вас пользователи читают информацию или также записывают? | |
| |
|
|
| |
|
|
| |
для: Shorr Kan
(07.06.2006 в 04:35)
| | | Хм... вот что не нравится, если у вас одновременно 2000-5000 пользователей, то почему mysql_max_connections 500, а не 2000-5000...
PS Вы уверены, что аналогичный проект обслуживает одни сервер, а как минимум не два (под Web-сервер и MySQL-сервер)? | |
| |
|
|
| |
|
|
| |
для: cheops
(07.06.2006 в 12:06)
| | | Я даже уверен, что аналогичный проект поддерживает несколько серверов. Но я не понимаю схемы. Вы ее можете представить и описать мне?
Что касается пятисот.. понимаете - поставлено пятьсот, а я тестировал - сотню одновременно (программка wapt)... сотня - уже убивала сервер. Сотня. Это же в ой-ой раз меньше.. | |
| |
|
|
| |
|
|
| |
для: Shorr Kan
(07.06.2006 в 12:35)
| | | Делают так, покупают несколько серверов и объединяют их в локальную сеть, ставят несколько Web-серверов (для начала можно один) с одинаковым содержимым и один MySQL-сервер к которому обращаются несколько Web-серверов (т.е. будет писаться не localhost, а адрес сервера в локальной сети). Так как под MySQL отведена вся память - он выдерживает значительные нагрузки. На вход всей этой конструкции ставят обратный кэширующий сервер, который по возможности кэширует статичные странцы, чтобы снизить нагрузки на сервера.
PS Начиная с MySQL 5.1 в бета-тестирование переходит кластерный вариант MySQL - т.е. теперь можно одну базу данных хранить на нескольких серверах. | |
| |
|
|
| |
|
|
| |
для: cheops
(07.06.2006 в 12:44)
| | | Значит, если я переведу на файлы всё - это не поможет? | |
| |
|
|
| |
|
|
| |
для: Shorr Kan
(07.06.2006 в 20:36)
| | | Если честно, то не уверен - скорее всего узнаете толко если попробуете... | |
| |
|
|
| |
|
|
| |
для: cheops
(07.06.2006 в 21:56)
| | | Пропустил это:
"А можно описать задачу подробнее - нельзя RAM диск или MEMORY-таблицы использовать? У вас пользователи читают информацию или также записывают?"
Использовать можно. Только - что это? Насколько я знаю - MEMORY-таблицы уничтожаются сразу, как только происходит отсоединение от Mysql... а оно происходит. И только потом - новое соединение и считывание. А что такое RAM-диск - лишь догадываюсь, что это объем оперативки, выделенный под сохранение данных... Но как это все выгляди и происходит - не понимаю. Что-то нужно настроить каким-то макаром, видимо...
Пользователи - записывают. А раз в пять минут по файлам проходит скрипт и перекидывает информацию в базу. | |
| |
|
|
| |
|
|
| |
для: Shorr Kan
(09.06.2006 в 11:03)
| | | Почему бі не сделать кеширование?
Скажем кеш не обновлять до тех пор, пока контент не поменяется, кешировать не всю страницу, а отдельное звено! Т.е. если это блок голосования то кешировать его, вывод главного контента то и его кешировать! При изменении главного контента кеш обновляется! Вы сократите свои запросы к БД к минимуму таким образом! ДА и время генерирования страниц! | |
| |
|
|
| |
|
|
| |
для: cernos
(09.06.2006 в 14:36)
| | | Нельзя. Нет там никакого контента. Это система статистики. Основная нагрузка происходит из-за записи сатистических данных. | |
| |
|
|
| |
|
|
| |
для: Shorr Kan
(10.06.2006 в 05:11)
| | | Может тогда пойти другим путем и сделать финт ушами?
Если у вас это специализированный проект и много пользователей (т.е. проект востребован), то может имеет смысл перенести его с ХТМЛ платформы?
Т.е. напишите на С++/Делфи/Фоксе специальную программу-клиент которая будет работать с сервером читать/писать данные. Тогда отпадет нужда в ХТТП сервере. Нужен будет только сервер баз данных MySQL или PgSQL, или другой.
Минус такого подхода - если изменятся выходные формы то придется переписывать программу клиент. Плюс - будете экономить на объеме траффика передаваемого по сети (передаете только данные, а не 5% данных и 95% ХТМЛ оформления). | |
| |
|
|
| |
|
|
| |
для: 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+")); ? Ведь должна же работать... | |
| |
|
|