Sunday, January 25, 2009

Yaws и потребление памяти

Уважаемые телерадиослушатели, мегаблог не совсем умер :)

В комментариях к записи про Yaws жжюзер [info]alekciy поинтересовался, сколько yaws будет хавать памяти на одно HTTP соединение. Понятно, что немного, но конкретные циферки всегда красноречивее слов. Не вопрос — на коленке собрался небольшой test suite. По хорошему тут надо было бы взять нормальный стенд — сервер и пяток клиентов (давняя мечта, повторить тот самый тест самому, так как его справедливо критикуют за отсутствие подробного описания условий тестирования), но под рукой только рабочий нотебук с убунтой 8.04 (Celeron 1.7, 2G памяти).

Итак, берем yaws 1.79, в качестве генератора траффика программка на C, за основу взял пример работы с epoll какого-то японца.

Тупо создаем соединения к серверу, запрашиваем файл и мееедленно (по байту) читаем ответ.

$ uname –a 
Linux lrrr-laptop 2.6.24-23-generic #1 SMP Thu Nov 27 18:44:42 UTC 2008 i686 GNU/Linux 

Исходники клиента.

График:

 yaws-mem

По оси X — количество одновременных соединений, по Y resident size процесса в килобайтах. Понятно, тут хватило б и двух точек, но мало ли что, вдруг, например, gc стал бы захлебываться с какого-то момента, надо было удостовериться.

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

Итого, если поделить — отжирается 14 кб памяти на коннект. Неплохо. Yaws (ожидаемо) не кушал CPU (показатель болтался около 1-2%), но, почему-то, довольно медленно принимал соединения — удавалось создать порядка 10 коннектов в секунду.

Попытка поставить в те же условия nginx пока не увенчалась успехом, соединения создаются раз в десять быстрее, но в районе 700 коннектов nginx сначала отдает 500 ошибку, потом молча закрывает соединения, а потом начинает приходить ECONNRESET. Думаю, он это делает из лучших побуждений, но я пока не нашел как на это повлиять.

15 comments:

Anonymous said...

Спасибо за тест. Любопытные цифры.

Насчет ограничения коннектов. Директив к Yaws-у которые бы регулировали скорость создания коннектов я лично не нашел, может они вшиты внутрь. Если конечно таковые есть вообще. В Apache что-то было, т.к. он с разной скоростью создает дочерние процессы.

В nginx может стоит поиграться с limit_conn и limit_req.

lrrr said...

Насчет коннектов, оказалось, это у меня косяк был %)

Anonymous said...

Насчёт Nginx: помимо указанных лимитов, увеличьте также лимит на количество открытых файликов. Параметр worker_rlimit_nofile.

John Lepikhin

Anonymous said...

коннекты также может ядро резать, есть лимит.
у меня так было когда случайно сделал udp thread/fork bomb

Anonymous said...

Понятно, что ОСь ограничивает ресурсы процесса, но как мне видиться в тот же лимит открытых файлов уперся бы не только nginx, но и VM с Yaws-ом.

Alex Ott said...

попробуй обсудить nginx с catap (http://catap.ru/blog/) -- он знатный в нем специалист :-)

lrrr said...

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

RumataEstor said...

А mochiweb не хочешь попробовать?

lrrr said...

Я все хочу, только времени маловато :)

Но вообще про mochiweb есть вроде подробный туториал, про сервер с миллионом соединений -- так что там точно должно быть все в порядке с памятью.

Anonymous said...

Кстати, все забываю. Почему 14кБ на коннект? К примеру на графике я вижу для 4000 порядка 340 000 кБ ОЗУ. Получаем 340 000/4 000 = 85 кБ/коннект.

lrrr said...

Ну там же еще какая-то константа есть, которая независимо от количества соединений отжирается, так что надо две точки брать, (y2-y1) / (x2-x1).

Anonymous said...

Ааа ну тогда понятно. А я думал это график уже непосредственно по коннектам, а не системы в целом.

Maksym Shevchenko said...

В *nix-ах по стандарту ограничение 1024 сокета на процесс.
Ковырять в сторону sysctl, ulimit, setrlimit (в FreeBSD первое, в Линуксе втрое).
14Кб на коннект станное число. By default буфер системы в котором хранятся не подтвержденные TCP/IP пакеты 36Кб.
10 коннектов в секунду получается потому что использунтся блокируемый accept.

Матчасть:http://www.kegel.com/c10k.html

Gisinoqih said...

график ужасает

Сервисник said...

График уже вообще не отображается? Поправьте по возможности