Очень долгий запуск на AMD64...

Andrei Nigmatulin anight at eyelinkmedia.com
Fri Apr 7 00:00:48 MSD 2006


On Thursday 06 April 2006 22:58, Igor Sysoev wrote:
> On Thu, 6 Apr 2006, Igor Sysoev wrote:
> > On Thu, 6 Apr 2006, Andrei Nigmatulin wrote:
> >> On Wednesday 05 April 2006 17:58, Igor Sysoev wrote:
> >>> On Fri, 31 Mar 2006, Andrei Nigmatulin wrote:
> >>>> On Friday 31 March 2006 16:08, Igor Sysoev wrote:
> >>>>> On Fri, 31 Mar 2006, Alexey N. Kovyrin wrote:
> >>>>>> Igor Sysoev пишет:
> >>>>>>>>> Нужно собрать nginx с профилированием.
> >>>>>>>>> Для gprof это делается примерно так:
> >>>>>>>>>
> >>>>>>>>> ./configure --with-cc-opt="-pg -g" --with-ld-opt="-pg" ...
> >>>>>>>>>
> >>>>>>>>> Потом запускается nginx, получаем файл nginx.gmon.
> >>>>>>>>> Потом запускаем gprof nginx, вывод присылаем мне.
> >>>>>>>
> >>>>>>> А если попробовать без профилирования
> >>>>>>> ./configure --with-cc-opt="-D NGX_ALIGNMENT=16" ...
> >>>>>>
> >>>>>> Эффект абсолютно нулевой... :-(
> >>>>>> Какие есть еще варианты кроме "выкинуть процессор"? :-)
> >>>>>
> >>>>> Кажется, я понял, в чём проблема.
> >>>>
> >>>> Если не секрет в чем же ? У меня аналогичные проблемы...
> >>>
> >>> Сколько времени занимает запуск ?
> >>> Что используется - map и куча виртуальных серверов ?
> >>
> >> Да, map используется, но кажется дело не в нем. Например, при
> >> server_names_hash_max_size 100000 и server_names_hash_max_size 384:
> >
> > Имеется в виду server_names_hash_bucket_size 384 ?
> >
> >> # time ../sbin/nginx -t
> >> 2006/04/06 19:36:31 [info] 28658#0: the configuration
> >> file /home/nginx/conf/nginx.conf syntax is ok
> >> 2006/04/06 19:36:31 [info] 28658#0: the configuration
> >> file /home/nginx/conf/nginx.conf was tested successfully
> >>
> >> real    0m47.037s
> >> user    0m46.841s
> >> sys     0m0.185s
> >>
> >> Увеличиванием server_names_hash_max_size до 512 проблема решается (время
> >
> > Имеется в виду server_names_hash_bucket_size 512 ?
> >
> >> становится 2 секунды) но поскольку кол-во server_names постоянно
> >> увеличивается - такую систему сложно поддерживать - было уже несколько
> >> раз когда nginx отказывался плавно перезагружаться из-за того что "could
> >> not build the server_names_hash, you should increase either
> >> server_names_hash_max_size or server_names_hash_bucket_size".
> >>
> >> Я так понимаю, что проблема в том, что в ngx_hash[_wildcard]_init()
> >> реализован
> >> алгоритм поиска minimal hashing. Это понятно, ведь nginx везде пытается
> >> использовать как можно меньше памяти. Однако если пользователь указал
> >> *_hash_max_size и *_hash_bucket_size то он (пользователь) уже дал
> >> согласие на
> >> то, что в худшем случае nginx найдет hash_size == hash_max_size и
> >> использует
> >> максимальное кол-во памяти.
> >>
> >> Следовательно, может быть, было бы оптимальнее начать искать hash_size с
> >> nelts / (ngx_cacheline_size / (2 * sizeof(void *)) - 1) в сторону
> >> увеличения,
> >> а с hash_max_size в сторону уменьшения ?
> >> (кстати, эвристику этой хитрой формулы я до сих пор не понял ;-)
> >
> > Эвристика такая - каждый ключ в корзине хэша занимает минимум
> > 2 * sizeof(void *): один void * - указатель на значение,
> > второй - длина имени ключа (один байт) плюс само имя ключа, выравненное
> > на void *. В линии кэша может поместится несколько ключей.
> > Для кэша с линией в 32 байта на 32-битной архитектуре в одной линии
> > может поместится максимум 2*4=8 ключей. После ключей есть ещё указатель
> > на NULL - это признак конца корзины, поэтому "- 1". Стало быть, ключей
> > уже 7. Ну а теперь делим общее количество элементов на максимальное число
> > ключей в одной линии кэша. Получаем значение, с которого нужно
> > стартовать. Меньше не имеет смысла (с). Но проблема в том, что основное
> > время тратится не на стартовых итерациях, а на последних, особенно, когда
> > массив, в котором считается размер корзин, уже не помещается в кэш
> > процессора.
> >
> >> Получившийся хэш был бы более perfect чем minimal, но вряд ли это будет
> >> критично для производительности. В теории, она даже может улучшиться ;-)
> >>
> >> Правда, пользователю может хотется "все равно построить хэш, даже
> >> вылезая за
> >> указанные hash_max_size / hash_bucket_size", в этом случае стратегию
> >> нужно пересмотреть.
> >
> > Наверное, в дополнение к server_names_hash_max_size имеет смысл сделать
> > директиву server_names_hash_size, задающую стартовый размер хэша.
> > И ещё можно выводить найденные размеры хэшней.
> > В этом случае есть только одна проблема - хэши создаются отдельно
> > для каждого слушающего сокета. И для одного сокета хэш может
> > быть маленький, а для - другого огромный.
>
> Я решил сделать несколько по-другому: если server_names_hash_max_size
> больше 50000 и server_names_hash_max_size / число элементов в хэше < 100,
> то начинать поиск размера с server_names_hash_max_size - 1000.

Мне понятен ход Ваших мыслей и этот алгоритм. Но не вызовет ли это вопроса у 
других, пытающихся настроить nginx ?

Я пытался смотреть какие алгоритмы построения hash есть в gperf, но не 
преуспел. Завтра попробую разобраться, может быть там есть более простые и 
эффективные алгоритмы.

> Патч прилагается. Интересно узнать результаты и кроме того, можно поиграть
> с числами.

Завтра обязательно проверю !!

-- 
Andrei Nigmatulin
GPG PUB KEY 6449830D

Now I lay me down to sleep(3)
Pray the OS my core to keep
If I die before I wake
Pray the Disk my core to take


More information about the nginx-ru mailing list