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