Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fill memcached with compressed data, serve directly from nginx

In python I generate complex static pages. I then put them into memcached so the next time they're requested, they can be served directly from Nginx (without hitting python at all)

This worked great until I realized how inefficient it was to store uncompressed html in Nginx. So I tried to manually gzip data before storing it, and get Nginx to return that directly (just setting content-encoding:gzip), but although Nginx's documentation suggests it's possible, I haven't been able to get it to work.

In my test, I had python fill the cache with data I gzip in python via NPE's answer at How do I gzip compress a string in Python? . I also set the memcached flag for these to 1.

With no other changes, at this point, Nginx serves the raw data, which gets displayed as junk in the browser.

After that, I changed the Nginx settings for that location, setting the memcached_gzip_flag field to 1 so that Nginx would know that data was already gzipped, but nginx still served the raw data. I've experimented with every combination of nginx's settings: gzip on and memcached_gzip_flag 1 but in all cases the browser displays raw data (after the first direct python hit); in some cases firebug reports that content-encoding is gzip (but is still showing raw gzip data) and in others, content-encoding is not set.

Overall, my plan of attack is to trick nginx into serving already-compressed data with the right headers so that browsers will unzip it.

I'm in nginx 1.6 & memcached 1.4.13

Here's the related nginx config lines, which originally would work. First hit gets data from python which fills the cache, 2nd hit serves directly from memcached.

location ~* <matching stuff> 
{
    if ($request_method = POST){
        break;
    }
    memcached_gzip_flag 1;
    set $memcached_key $uri;
    memcached_pass 127.0.0.1:11211;
    error_page 404 405 502 = @redo;
    default_type text/html;
}

UPDATE: I experimented more (details in the comments), but still no result.

UPDATE POST BOUNTY: I have no good answer at all to this. Basically, I can't get the memcached_gzip_flag function to work at all. Note for future answerers: if you answer this I will make a bounty & award it to you. This is preferable to having half of the bounty automatically awarded to completely wrong answers.

like image 201
fastmultiplication Avatar asked Apr 24 '14 13:04

fastmultiplication


1 Answers

The documentation is a little sparse, but if I'm understanding it correctly: memcached_gzip_flag specifies which bits in the flag associated with the cached object indicate the content is already gzipped. You need to say something like: memcached_gzip_flag 1, then store the data with a flag having the matching bits set:

 memcache.set('key', 'gzipped-value', flags=1)
like image 126
Dark Falcon Avatar answered Oct 10 '22 06:10

Dark Falcon