Относительно медленная работа proxy_cache в nginx ...

Eugene Batogov johnbat26 at gmail.com
Wed Jul 18 12:06:18 UTC 2012


Привет всем.
Я провожу оптимизацию работы нашей системы и пытаюсь переместить
кэширование некоторых
ресурсов с memcached на proxy_cache.
------------------
*Моё окружение:*
*ОС*: Gentoo x86-84 (Linux  kernel-3.3.8 #1 SMP PREEMPT  x86_64 Intel(R)
Core(TM) i5 CPU 750 @ 2.67GHz GenuineIntel GNU/Linux)
*NGINX:*
nginx version: nginx/1.2.2
TLS SNI support enabled
configure arguments: --prefix=/usr --conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error_log --pid-path=/var/run/nginx.pid
--lock-path=/var/lock/nginx.lock --with-cc-opt=-I/usr/include
--with-ld-opt=-L/usr/lib --http-log-path=/var/log/nginx/access_log
--http-client-body-temp-path=/var/tmp/nginx/client
--http-proxy-temp-path=/var/tmp/nginx/proxy
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi
--http-scgi-temp-path=/var/tmp/nginx/scgi
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --with-debug --with-ipv6
--with-pcre --with-http_addition_module --with-http_flv_module
--with-http_geoip_module --with-http_gzip_static_module
--with-http_image_filter_module --with-http_random_index_module
--with-http_stub_status_module --with-http_xslt_module
--with-http_realip_module
--add-module=/var/calculate/tmp/portage/www-servers/nginx-1.2.2/work/agentzh-headers-more-nginx-module-3580526
--add-module=/var/calculate/tmp/portage/www-servers/nginx-1.2.2/work/nginx-push-stream-module-0.3.4
--add-module=/var/calculate/tmp/portage/www-servers/nginx-1.2.2/work/echo-nginx-module-0.38rc2
--with-http_ssl_module --without-mail_imap_module
--without-mail_pop3_module --without-mail_smtp_module --user=nginx
--group=nginx
-------------------

Есть у меня одна картинка в формате png. Размером 400 Кб.
Сейчас она лежит в memcached. И nginx, на ненагруженной системе, выдает её
за* 2 мс*.
Если он берет её с Backend (JBoss/Java), то время получается: *25мс*.

В боевом окружении мы имеет периодические всплески запросов за этой
картинкой.
Когда они приходят в большом количестве (>200 в секунду), то трафик на
memcached возрастает до порядка *> 200 мб/c.*
memcached начинает слегка замедляться и просаживает всю систему.

Поэтому хотелось бы закэшировать эту картинку после получения ее с
backend-a на уровне proxy_module.
Для этого я сделал такую конфигурацию:

 ...
    proxy_cache_path  /var/cache/nginx/banners levels=1:2
keys_zone=banners-cache:20m max_size=100m inactive=120m;
...
    location /portal-facade-ng/v1/adv/imageMap/{
         proxy_pass   http://127.0.0.1:8080;
         proxy_cache banners-cache; # включаем proxy кэш в зону
banners-cache
         proxy_cache_key $scheme$proxy_host$uri; # ключ для кэша
         proxy_cache_valid  200 302  1h; # кэшируем 200 и 302 ответы на 1час
         proxy_cache_valid  404      10m; # 404 ответы кэшируем на 10 минут
         proxy_ignore_headers    X-Accel-Redirect; # некоторые заголовки
игнорируем
         proxy_ignore_headers    X-Accel-Expires Expires Cache-Control;
         proxy_ignore_headers Set-Cookie;
         expires       1h;  # проставляем заголовки для
браузера
         add_header  Content-Type   image/png;
         add_header  Cache-status: $upstream_cache_status;
         default_type  image/png;
         error_log        /var/log/nginx/adv.log  debug;
         error_page      404 = @404;
         error_page      502 = @502;
         error_page      504 = @504;
         index  index.html index.htm;
       }
...

Proxy кэш работает. Но одно но - *за 250 - 300 мс*.
*То есть в 100 раз медленней чем memcached и в 10 раз медленнеё чем backend.
Почему так может быть?

*Если я кладу ту же картинку статикой, тогда она отдается за 1 мс!

Я включил режим debug на nginx. логи приложил к письму.
Логи находятся тут:
лог через proxy модуль: https://gist.github.com/3135719
лог через статику: https://gist.github.com/3135728
Также вот сравнение запросов proxy_cache vs memcached_pass:
https://gist.github.com/3135124

Таким образом, я хочу добиться того, чтобы nginx proxy модуль быстрее
отдавал "динамическую статику" чем memcached.
Proxy-кэш работает, но медленно в сравнении с memcached.
Перенос каталога кэша с HDD на tmpfs на производительность не повлиял.
Хотелось бы узнать полный алгоритм работы proxy модуля в такой ситуации.

Я думал что он работает примерно так:

 1. Идет на backend
 2. Получает ответ от него.
 3. Если надо, кэширует его в файловой системе.
 4. При последующих запросах к этому ресурсу proxy модуль читает файл с HDD
и оставляет в памяти.
 5. И затем все остальные запросы молотит из памяти.

Где я ошибся?


И еще вопрос, можно ли еще сделать дополнительное кэширование после
memcached_pass ?
Иногда очень необходимо, для разгрузки memcached.

Можно ли выставлять время инвалидации кэша в абсолютных единицах, то есть,
например, ровно в 00:00 ?

Спасибо.





*
*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-ru/attachments/20120718/a12daf1b/attachment.html>


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