使用压缩数据填充memcached,直接从nginx提供

时间:2014-04-24 13:18:50

标签: python nginx memcached gzip

在python中我生成复杂的静态页面。然后我将它们放入memcached中,以便下次他们请求时,可以直接从Nginx提供它们(完全没有点击python)

这很有效,直到我意识到在Nginx中存储未压缩的html是多么低效。所以我尝试在存储之前手动gzip数据,让Nginx直接返回(只设置content-encoding:gzip),但是尽管Nginx的文档表明它可能,但我还没有能够让它发挥作用。

在我的测试中,我通过NPE在How do I gzip compress a string in Python?的回答让python用python填充缓存中的数据。我还将这些的memcached标志设置为1。

此时没有其他更改,Nginx提供原始数据,在浏览器中显示为垃圾。

之后,我更改了该位置的Nginx设置,将memcached_gzip_flag字段设置为1,以便Nginx知道数据已经被gzip压缩,但nginx仍然提供原始数据。我已经尝试过nginx设置的每个组合:gzip onmemcached_gzip_flag 1但是在所有情况下浏览器都会显示原始数据(在第一次直接python命中之后);在某些情况下,firebug报告内容编码是gzip(但仍显示原始gzip数据),而在其他情况下,内容编码未设置。

总的来说,我的攻击计划是欺骗nginx使用正确的标头提供已经压缩的数据,以便浏览器将其解压缩。

我在nginx 1.6& memcached 1.4.13

这里是相关的nginx配置行,最初可以使用。第一次命中从python中获取数据,填充缓存,第二次命中直接来自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;
}

更新: 我试验了更多(评论中的细节),但仍然没有结果。

更新POST BOUNTY: 我对此没有任何好的答案。基本上,我无法使memcached_gzip_flag功能完全正常工作。未来回答者的注意事项:如果你回答这个问题,我会给你一个赏金和奖励。奖励给你。这比将一半的赏金自动判给完全错误的答案更好。

3 个答案:

答案 0 :(得分:2)

文档有点稀疏,但如果我理解正确:memcached_gzip_flag指定与缓存对象关联的flag中的哪些位表示内容已经被gzip压缩。您需要说出:memcached_gzip_flag 1之类的内容,然后使用设置了匹配位的标志存储数据:

 memcache.set('key', 'gzipped-value', flags=1)

答案 1 :(得分:0)

Memcached具有内置行为,如果您的数据超过20KB,则默认会压缩它。也许正在发生的情况是你的情况下有两级压缩,浏览器在渲染时只做一次数据解压缩(假设所有标题都很好)。查找Memcached的CompressionThreshold选项。

答案 2 :(得分:0)

Memcached服务器没有任何压缩。 memcached客户端必须压缩/解压缩。客户端通常具有CompressionThreshold逻辑

对我来说,使用nginx memcached和gunzip模块进行配置后工作:

//Load dump from assets folder
InputStream inputStream = application.getAssets().open("my_factory_data_db.realm");
// realm file default name is default.ream
File file = new File(context.getFilesDir(), "realmFileName.realm");
FileOutputStream outputStream = new FileOutputStream(file);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buf)) > 0) {
    outputStream.write(buf, 0, bytesRead);
}
ApiPreferenceHelper.setVersionApi(application, BuildConfig.BUILD_TIMESTAMP);
inputStream.close();
outputStream.close();

memcached_gzip_flag

  

在memcached服务器响应中启用标志存在的测试,如果设置了标志,则将“Content-Encoding”响应头字段设置为“gzip”。