On 18.08.2015 14:38, Maxim Dounin wrote:

Наиболее неприятный из известных мне нюансов состоит в том, что
неразблокированные элементы кеша остаются, если какому-либо из
рабочих процессов сказать TERM.  Например, такое иногда практикуют
для принудительного завершения старых рабочих процессов, плавное
завершение которых занимает слишком много времени.
.....
В функции ngx_shmtx_lock блокировка делается через
ngx_atomic_cmp_set, при этом, вместо 0 записывается
ngx_pid, следовательно, если блокировка стоит -
всегда можно узнать, какой именно процесс
эту блокировку поставил.

Речь про блокировки отдельных элементов кеша, а не всей зоны
разделяемой памяти.  С зоны разделяемой памяти блокировку после
падения процессов мы снимать умеем, см. ngx_shmtx_force_unlock().

"блокировка отдельных элементов кеша" -
это когда в структуре ngx_http_cache_s
установлен бит lock ?

Если вместо unsigned lock:1; сделать ngx_tid_t lock;
- тогда можно будет снимать блокировки элементов кеша
после завершения рабочих процессов любым способом,
даже по SIGKILL - мастер скажет процессу cache manager
о том, какой pid завершил работу и cache manager тогда
сможет разблокировать все заблокированные этим процессом
элементы кеша, после чего мастер перезапустит упавший worker.
Или - мастер сам разблокирует все элементы кеша и перезапускает воркер.

И тогда завершение worker-процессов по сигналу TERM
будет "чистым", без оставления каких-либо блокировок.

На практике вполне неплохо работает вывод сообщений в логи и
перемещение заблокированных элементов в начало очереди,
реализованное для обработки удаления старых элементов по inactive.
Проблемы, судя по рассылке, наблюдаются у тех, кто очистку по
inactive фактически выключил - и, видимо, в сочетании с какой-то
ещё проблемой, какой - пока непонятно.

Если удалять заблокированные элементы - разве не будут segfault'ы?

Их никто не удаляет, их перемещают и ругаются в лог.
См. ngx_http_file_cache_expire().

Сначала перемещают, но потом всеравно удаляют:
"для обработки удаления старых элементов по inactive".

Тут не будет разве race condition, если живой worker очень
долго обновляет элемент кеша с бекенда, и в этот момент
происходит удаление элемента по inactive?

Например, если inactive стоит 10 секунд,
а proxy_cache_lock_age 20 секунд.

P.S. Кстати, документация по директиве proxy_cache_lock_age
в файле CHANGES более понятная, чем на http://nginx.org/en/docs/

--
Best regards,
 Gena

_______________________________________________
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Ответить