Re: Странное поведение кэша nginx

Maxim Dounin mdounin на mdounin.ru
Ср Июн 22 16:36:26 MSD 2011


Hello!

On Wed, Jun 22, 2011 at 02:21:44PM +0400, Alexander Pyhalov wrote:

> Здравствуйте.
> У меня возникла достаточно странная проблема.
> Когда закешированный статический файл изменяется, nginx возвращает
> его либо с большим таймаутом в конце передачи файла (около минуты)
> (в частности, если из текстового файла удалить строку), либо
> возвращает часть файла (обрезает его, в результате клиент получает
> какой-то мусор) (в частности, если в текстовый файл добавить
> строку). Проблема наблюдается только при изменении файла (при
> изменении mtime проблемы нет).
> При отключении кэша проблема исчезает (но, естественно, нагрузка на
> сервер возрастает). При этом аналогичные конфигурации nginx на
> других серверах работают нормально. Обновление nginx до 1.0.4 не
> помогает. На глюки с памятью сервера не похоже (затрагивает только
> nginx, остальные приложения работают нормально, пробовал запускать
> memtester на свободной области памяти, он говорит, что все в
> порядке).

[...]

>         open_file_cache max=2048 inactive=600s;
>         open_file_cache_valid 2000s;
>         open_file_cache_min_uses 1;
> ##      open_file_cache_errors on;

Вы сказали nginx'у кешировать открытые файловые дескрипторы и 
информацию о размере файлов в течение 2000 секунд.  Если при этом 
неатомарно изменить файл - то представление nginx'а о 
размере файла перестанет соответствовать реальности на указанные 
2000 секунд.  В результате Content-Length в ответе будет один, а 
реально имеющихся данных в ответе - меньше (или столько же, но не 
все данные из файла).  В первом случае с точки зрения браузера 
ответ будет "не завершён" пока nginx не закроет соединение по 
завершению keepalive_timeout.

Та же проблема будет наблюдаться и без open_file_cache, если 
обновлять файлы неатомарно, просто с open_file_cache вы 
увеличиваете масштаб проблемы с только тех запросов, которые 
отдавались в момент неатомарного изменения, до всех запросов за 
указанный период open_file_cache_valid.

Правильное (и единственное) решение - обновлять файлы атомарно.  
Т.е. писать новый (временный) изменённый файл, а потом атомарно 
(mv подойдёт) переименовывать его в файл с правильным именем.

Утверждение про "аналогичные конфигурации ... работают нормально" 
мне представляется сильно сомнительным.  Либо там файлы обновляют 
атомарно, либо вы просто чего-то не заметили.

Maxim Dounin



Подробная информация о списке рассылки nginx-ru