S
S
Sergey Pugovkin2016-10-23 04:28:41
PHP
Sergey Pugovkin, 2016-10-23 04:28:41

Why is nginx throwing garbage from memcached?

Through php memcached I write data to memcached:

$this->memcached->setOptions([
    \Memcached::OPT_COMPRESSION => true,
    \Memcached::OPT_BINARY_PROTOCOL => true,
]);
$key = '...';
$value = '...';
$this->memcached->set($key, $value);

nginx takes the data and gives it to the user, something like this:
location ~ \.php$ {
        set $memcached_key "...";
        gunzip                  on;
        memcached_gzip_flag     2;
        memcached_pass          unix:/run/memcached/memcached.socket;
        error_page              404 405 = @php;
}

However, nginx stubbornly produces binary data instead of normal html code. I think the point here is that nginx thinks that uncompressed data is saved. Tried different variants of memcached_gzip_flag: 0, 1, 2, 3... nothing changes....
Of course, if you disable compression (Memcached::OPT_COMPRESSION => false) everything works fine. How about with it enabled?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey Pugovkin, 2016-10-24
@Driver86

In short, with grief in half solved the problem.
The problem turned out to be, as I thought, in the wrong compression : php-memcached compresses data as deflate, and nginx only recognizes gzip and, by the way, the last one is right - gzip, unlike deflate, roughly speaking, "more unambiguous" and even works with the most buggy browsers.
I wrote to the developers of php-memcached with a suggestion to add gzip compression, but they, apparently, are conservatives and do not want to change anything (as I felt a catch when I looked at the date of the latest version ). The funny thing is that adding support for gzip there is as easy as shelling pears - work for 20 minutes maximum , sources are simpleeven for me, far from C. At first I thought to propose changes to them myself, but oh well ... The extension was demolished. I did it through sockets, as it turned out, working with memcached directly is not so difficult .

$key = 'key';
$flags = 1;
$expire = 0;
$value = gzencode('value', 6, FORCE_GZIP);
$length = strlen($value);
if (!fwrite($memcached, "set {$key} {$flags} {$expire} {$length}\r\n{$value}\r\n")) {
        throw new Exception('Memcached write error.');
}

$flags - bit flags. I set this variable to 1 if $value is compressed, otherwise 0.
In the nginx config, respectively, set memcached_gzip_flag to 1. In
total, it works like this: $value compression saves space in the RAM. If nginx sees flag 1, then it returns the response "Content-Encoding: gzip" in the header, without re-compressing, thus saving CPU time. If the browser does not support gzip, then nginx will decode the $value and return it uncompressed.

B
bnytiki, 2016-10-23
@bnytiki

MIME укажите.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question