[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Глубокофилософский вопрос о нагруженности серверов
sergeiss
Коллеги-форумчане!

Пришла мне тут в голову мысль поделиться с вами некоторыми знаниями, которые являются, с одной стороны, узкоспециализированными, а с другой стороны, желательно их знать и понимать.

(Далее много букоФФ, кому не интересно, могут не читать).

Я работаю в сотовой связи, а в связи для расчета нагрузок, создаваемых абонентами, используется так называемая "теория телетрафика". Она позволяет расчитать, какие ресурсы необходимы для пропуска создаваемой абонентами нагрузки (например, разговоров), чтобы вероятность отказа (по причине полной загрузки системы) не превышала некоторых предопределенных величин. Либо - можно расчитать, сколько пользователей смогут пользоваться сервером, исходя из средней величины загружаемых страниц и "толщины" канала до сервера. Это может быть иногда актуально, особенно для тех, кто хочет поставить сервер у себя дома и купить "широкий" канал до провайдера.

Какое это имеет отношение к ПХП? Да самое прямое smile.gif Теория телетрафика работает не только с телефонией, но и с передачей данных, и даже нагруженность дорог, создаваемую автомобилями, можно расчитать по этой теории (естественно, не "вес", а нагруженность временнУю - например, сколько авто может пропустить данная дорога при определенных скорости движения и интервалах между авто).

А теперь подойдем поближе к ПХП и серверам.
Зачем нам это может понадобится? Ну, например, встречаются "любители" хранить данные в файлах, а не в БД. При этом данные постоянно перезаписываются. При этом существует некоторая вероятность того, что произойдут одновременные обращения к файлу со стороны разных пользователей, что может привести к некорректной обработке данных.

Итак, берем следующие исходные данные.
Есть некий скрипт, который работает с файлом. Читает данные, что-то с ними делает, пишет обратно. Предположим, что общее время работы скрипта 0.01 с, и продожительность работы с файлом (пока он открыт) также будем считать равной этой величине. И нам надо быть уверенными, что пока один абонент работает с файлом, никто другой не будет работать с ним.

Далее. Для начала будем считать, что система расчитана на максимальную нагрузку 10000 обращений в час. То есть, это "всего лишь" 0.02777777 обращений за 0.01с, т.е. за время обслуживания. На первый взгляд "нет проблем", работаем с файлами и не "паримся".

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

Берем среднюю величину 0.02777777 обращений, и считаем:
Количество обращений; Вероятность поступления ровно стольки обращений за 0.01 с
0 ; 97.26%
1 ; 2.7%
2; 0.04%
3 ; очень мало, можно считать = 0

Что же означает величина 0.04%, много это или мало? Из 10000 обращений это 4. То есть, 4 раза за час у нас есть вероятность того, что файл будет испорчен при неправильной обработке.

Сразу же, наверняка smile.gif, появляется желание "поиграться" с цифрами. Сделать это можно, только надо учитывать, что зависимость далеко не линейная. Поэтому для каждых исходных данных надо считать результат по формуле.

Пусть для тех же 0.01 сек работы с файлом будет 100000 обращений в час. Это, на самом деле (с расчетной точки зрения), эквивалентно 10000 обращений, но при времени работы с файлом в течение 0.1с (сорри, тут была ошибка - сначала ошибочно написал величину, в 100 раз меньше; потом исправил).

Количество обращений ;Вероятность поступления ровно стольки обращений за 0.01 с (100 тыс обращений в час)
0 ; 75.75%
1 ; 21.04%
2 ; 2.92%
3 ; 0.27%
4 ; 0.02%
5 ; очень мало, можно считать = 0

Также вполне закономерным может быть вопрос о том, как этих проблем избегают разработчики БД? Очень просто. БД - это "система с очередью", т.е. поступающие запросу могут ждать в очереди, что приводит к некоторому увеличению продолжительности обработки, но позволяет корректно обработать все запросы.


Выводы какие? Да разные.
1. Просто полезно это понимать smile.gif.
2. Работая с файлами (модифицируя их), к которым обращаются все или многие пользователи, будьте осторожны! Подумайте о том, что затраты времени на изучение работы с БД окупятся очень быстро.



Спустя 51 минута, 59 секунд (22.07.2009 - 10:43) olgatcpip написал(а):
вау

Спустя 2 часа, 23 минуты (22.07.2009 - 13:06) stepan написал(а):
Это вот прям как для меня было написанно, потому что я пытаюсь себя отучить от везде сущего внедрения файла и приучить себя к более стабильной технологии.

Спустя 5 минут, 23 секунды (22.07.2009 - 13:11) sergeiss написал(а):
stepan - и для тебя тоже smile.gif Именно для того, чтобы не просто использовал "правильные" и стабильные технологии, но и понимал, почему они лучше. В чем состоит их правильность.

Спустя 11 минут, 28 секунд (22.07.2009 - 13:23) stepan написал(а):
Да после такой статьи есть над чем подумать.
Спасибо

Спустя 14 минут, 27 секунд (22.07.2009 - 13:37) twin написал(а):
А с какого перепуга должен наступить совместный доступ, если пользоваться безопасной (как обещают) функцией file_put_contents()? Она же вроде как их блокирует.
Вот ты посмотри, какя фишка. Конечно, БД удобная вещь, нет вопросов. Но если мне нужны данные, которые заведомо меняются раз в 10 минут, час, месяц? А посещаемость огромная. А таблица в базе весит 50 метров?
Сходил туда раз в час, взял данные и сунул в файл. 1-2 килобайта. Сравни ка нагрузку. Неет. Все хорошо на своих местах.
Справедливости ради - ты это отметил. Но не все могут это понять. smile.gif

Спустя 30 минут, 23 секунды (22.07.2009 - 14:08) sergeiss написал(а):
Насчет совместного доступа - я имел ввиду, что одновременно 2 пользователя откроют файл и начнут что-то дописывать в него. Тогда, в лучше случае, что-то просто не попадет в файл.

twin - я же четко сказал о том, что
Цитата (sergeiss @ 22.07.2009 - 10:51)
данные постоянно перезаписываются
. Не раз в 10 минут или реже, а практически при каждом обращении пользователей.

И ежели
Цитата (twin @ 22.07.2009 - 14:37)
не все могут это понять

то это их проблемы smile.gif Я писал для тех, кто понимает и хочет понять.

Но, опять же, пусть даже те, кто не поймет, сделают вывод, что лучше всегда использовать БД. Пусть уж лучше так, чем наоборот.

Спустя 23 минуты, 19 секунд (22.07.2009 - 14:31) HardWoman написал(а):
Е мое профессор - да и только - как в институте на лекции отсидела.
И стилистика путем. Умница

Спустя 26 минут, 58 секунд (22.07.2009 - 14:58) sergeiss написал(а):
HardWoman - приходиЦЦа тренироваЦЦа smile.gif Надо же на ком-то отрабатывать... Понятно хотя написано-то?

Я тут "подписался" обучать сотрудников нашей конторы. В августе начну. А пока вот тренируюсь. Правда, большей частью не по столь утонченным вопросам, да и вообще к программированию не имеет отношения. Только к GSM.


Спустя 3 часа, 48 минут, 26 секунд (22.07.2009 - 18:46) PandoraBox2007 написал(а):
Это типа кеширование с применением TTL (Time To Left) + математическое предугадывание наступление следующего обновления

Спустя 18 минут, 49 секунд (22.07.2009 - 19:05) Sylex написал(а):
да есть реализации с блокировками - проверяется файл заблокирован, или нет, если да - ждем, и опять проверяем, пока не разблокируется. Как разблокировался - пишем.

типа
PHP
while (!flock($f,LOCK_EX+LOCK_NB)) {
  sleep(1); // wait 1 sec
}
// write


хотя тут уже наверняка лучше решения есть

конечно, при такой нагрузке тупо писать в файл - неправильно

Спустя 1 час, 8 минут, 35 секунд (22.07.2009 - 20:14) kirik написал(а):
Цитата (twin @ 22.07.2009 - 05:37)
если пользоваться безопасной (как обещают) функцией file_put_contents()? Она же вроде как их блокирует.

Если с флагом LOCK_EX использовать, она ведь работает как fopen-fwrite-fclose, а при флаге в цепочку добавляется flock: fopen-flock[LOCK_EX]-fwrite-flock[LOCK_UN]-fclose

Цитата (Sylex @ 22.07.2009 - 11:05)
хотя тут уже наверняка лучше решения есть

Есть smile.gif Если файл залочен fopen будет ждать, пока его не разлочат. Можешь проверить скриптег:

PHP
$filename './file.txt';

$handle fopen($filename'r');
$contents fread($handlefilesize($filename));
fclose($handle);
echo 
$contents;

if(isset(
$_GET['ex']))
    exit;

$handle fopen($filename'w+');
flock($handleLOCK_EX);
fwrite($handle'Записали!');
sleep(2);
flock($handleLOCK_UN);
fclose($handle);


Запусти его одновременно в двух табах браузера, в первом случае просто скрипт, во втором с параметром ?ex в GET.

sergeiss
Спасибо за материал! Интересно было как нагрузка считается smile.gif

Спустя 1 час, 5 минут, 53 секунды (22.07.2009 - 21:20) sergeiss написал(а):
Цитата (kirik @ 22.07.2009 - 21:14)
sergeiss
Спасибо за материал! Интересно было как нагрузка считается

На самом деле, это даже и не нагрузка, а просто вероятность отказа, распределение Пуассона - база, на которой "зиждется" дальнейшая теория.
Дальше идет формула Эрланга для систем без очереди, и форумала Эрланга Це для систем с очередью smile.gif А передача данных через IP-сеть - типичный пример системы с очередью.

Но это уже тема для других тем, ежели есть желание узнать это.

PS. Весь нетематический флуд из темы будет удаляться. Кому хочется пофлудить - идите в соответствующий раздел.

Спустя 4 месяца, 26 дней, 13 часов, 21 минута, 12 секунд (19.12.2009 - 11:41) VolCh написал(а):
Кстати говоря, БД, особенно не поддерживающая транзакции, тоже не панацея. При таких частотах запросов на обновление связанных данных - в лучшем случае будем получать ошибку "Попытка нарушения целостности данных", в худшем - это самое нарушение с последствиями вплоть до краха всего приложения. А не дай бог обновляемые/добавляемые поля записей окажутся в индексах... wacko.gif

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

Спустя 20 дней, 8 часов, 4 минуты, 30 секунд (9.01.2010 - 19:45) Guest написал(а):
sergeiss а как с вами можно подробнее пообщаться на тему Теория телетрафика? Просто эта тема мне интересна.

Спустя 1 час, 31 минута, 23 секунды (9.01.2010 - 21:17) sergeiss написал(а):
Цитата (Guest @ 9.01.2010 - 20:45)
sergeiss а как с вами можно подробнее пообщаться на тему Теория телетрафика?

У меня в профиле есть ася. Заходи, только при запросе авторизации напиши, что по этому вопросу. Тогда я авторизую, и можно будет пообщаться.

Либо - сделай тут тему, задай вопрос. Мало ли, кому тоже будет интересно.

Спустя 6 часов, 1 минута, 37 секунд (10.01.2010 - 03:18) HardWoman написал(а):
А написать ему в личку

Спустя 1 год, 10 месяцев, 10 часов, 26 минут, 50 секунд (10.11.2011 - 12:45) LRCenter написал(а):
На самом деле все просто. Надо только подумать творчески. :D


function fCSV_lock($dbs, $wsec=NULL){
if(!is_array($dbs)){$dbs=explode(",",$dbs);}
if($wsec==""){$wsec=3;}
if($wsec > 8){$wsec=8;}
for($ick=0; $ick<=$wsec; $ick++){
$darr=array();
foreach($dbs as $msv){
$msv=trim($msv);
if(!file_exists($msv."~L")){file_put_contents($msv."~L",''); $darr[]=$msv;} else{$nan=1;}}
if($nan==1){
foreach($darr as $msc){unlink($msc."~L");}
unset($darr);
if($ick==$wsec){break; return FALSE;} else{sleep(1);}}
else{unset($darr); return TRUE;}}}


function fCSV_unlock($dbs){
if(!is_array($dbs)){$dbs=explode(",",$dbs);}
foreach($dbs as $msv){
$msv=trim($msv);
if(file_exists($msv."~L")){
if(unlink($msv."~L")){} else{$err=1;}}}
if($err==1){return FALSE;} else{return TRUE;}}


function fCSV_islock($dbs, $wsec=NULL){
if(!is_array($dbs)){$dbs=explode(",",$dbs);}
if($wsec==""){$wsec=1;}
if($wsec > 8){$wsec=8;}
for($ick=0; $ick<=$wsec; $ick++){
$err="";
foreach($dbs as $msv){
if(file_exists(trim($msv)."~L")){$err=1; break;}}
if($err!=1){break;}
else{if($ick!=$wsec){sleep(1);}}}
if($err==1){return TRUE;} else{return FALSE;}}



Первая блокирует файл(ы), вторая разблокирует, третья проверяет статус блокировки. И всякие flock-и нам не указ. (Они вообще не работают иногда).

Первый параметр массив или список путей к файлам через запятую. В данном случае CSV-таблицам, во втором, где есть, необязаетльном предельное время ожидиния в секундах, максимум 8, по умолчанию - 3

Пример использования:

if(fCSV_lock("test2.csv, test2ex.csv")){

#здесь запись

fCSV_unlock("test2.csv, test2ex.csv");}



Работает безотказно. Проверял эмпирически - 10 минут, непрерывная перезапись строк по запросу с 4-х клиентов в csv-таблице весом ~50мб.

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


_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.