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

Igor Sysoev is at rambler-co.ru
Fri Apr 7 00:04:56 MSD 2006


On Fri, 7 Apr 2006, Andrei Nigmatulin wrote:

> 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 ?

На малых объёмах время поиска мало. Скорее всего, время начинает расти
после 10,000.


Игорь Сысоев
http://sysoev.ru





More information about the nginx-ru mailing list