Nginx returns corrupted data from memcached

On my website, I did caching data with memcached. It stores fully generated html pages. The next step was to get this data from memcached from nginx and send it back to the user w \ o start apache. At first I tried to get data from the cache using php backend and it worked. But when I try to do this with nginx - I see barely corrupted data. smth like enter image description here

I ask for help with this problem.

ps here is part of nginx configuration if it can help

location / { #add_header Content-Type "text/html"; set $cachable 1; if ($request_method = POST){ set $cachable 0; break; } if ($http_cookie ~ "beauty_logged") { set $cachable 0; break; } if ($cachable = 1) { set $memcached_key 'nginx_$host$uri'; memcached_pass 127.0.0.1:11211; } default_type text/html; error_page 404 502 504 405 = @php; #proxy_pass http://front_cluster; } location @php { proxy_pass http://front_cluster; } 
+2
source share
5 answers

The problem was the specific behavior of memcached. even if you turn off data compression, memcached will do this if your data exceeds the 20k character limit. disinfection - (in my case) when caching the backend, for example, $this->_memcache->setCompressThreshold(20000, 1);

ps I am using Zend_Cache_Backend_Memcached as the parent class of my backend. so the line above should be in __contstruct()

0
source

Nginx does not process the content stored in Memcached, it just receives it and returns to the browser as it is.

The real reason is the Memcached client library used by your application. Most libraries compress large values ​​(usually when the size of the value exceeds a certain threshold), so you should not configure it for this or set memcached_gzip_flag ("unstable" 1.3.6 first appeared in Nginx) with gunzip module enabled.

+5
source

The answer you posted seems to be gzipped. My first assumption is that Apache returns a response with transfer-encoding=gzip , which is stored in memcached , but then when exposed and returns with nginx via memcached , the transfer-encoding header is omitted, so the browser gets the wrong answer. You can easily test if this happens with disabling gzip compression in Apache .

If so, you should look for a solution to save the transfer-encoding header ... perhaps to define different rules - for content without gzipped and gzipped and to always return the header in the latter case. But look at this: http://wiki.nginx.org/HttpSRCacheModule . He seems to cope with such cases.

+1
source

therefore the problem was in Memcached CompressTreshold. when data exceeds 20 thousand characters, memcached enables compression, even if conression = false.

+1
source

If you use the PHP Memcached library, keep in mind that it can only store compressed data using zlib . Nginx cannot extend zlib, even with memcached_gzip_flag , as Alexander says. Thus, in this situation, you probably should not compress the data in Memcached, if you are not comfortable compressing everything and transferring it directly to the browser using the add_header Content-Encoding deflate .

0
source

All Articles