Подтвердить что ты не робот

Как декодировать/декомпрессировать значения из кэша Rails с поддержкой memcached (драгоценный камень Dalli) в Node.js

У меня есть приложение Rails, которое кэширует данные в memcached через драгоценный камень Dalli (https://github.com/mperham/dalli).

Я хотел бы прочитать содержимое этого кеша из Node.js. Я использую модуль mc для взаимодействия с memcached в Node.js.

Проблема, с которой я столкнулся, - это кодирование и сжатие. Dalli использует Zlib::Deflate.deflate(data) (https://github.com/mperham/dalli/blob/master/lib/dalli/compressor.rb). Когда я пытаюсь надуть от Node.js, я получаю сообщение об ошибке при попытке раздувания с помощью модуля zlib:

{ [Error: incorrect header check] errno: -3, code: 'Z_DATA_ERROR' }

Вот соответствующий код Ruby/Rails:

config.cache_store = :dalli_store, memcached_server, {compress: true}

И соответствующий Node.js код:

client = new Memcached.Client(MEMCACHED_HOSTNAME, Memcached.Adapter.raw);


client.get(key, function (err, response) {
  var data = response[key];

  zlib.inflate(data.buffer, function (err, buf) {
    console.log(err, buf);
  });
});

Буфер, возвращаемый из значения memcached string, выглядит следующим образом:

'\u0004\b[\u0015i\u0006i\u0007i\bi\ti\ni\u000bi\fi\ri\u000ei\u000fi\u0010i\u0011i\u0012i\u0014i\u0015i\u0016'

Значение, которое я ожидаю после раздувания, примерно такое: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17]

4b9b3361

Ответ 1

Обратите внимание, что Dalli будет только сжимать значения по 1K по умолчанию, поэтому, если ваши данные меньше 1K, вы сбрасываете обычный текст = > мусор.

Затем я предполагаю, что вы читаете правильный ключ, а не какое-то изображение или что-то, что хранится в memcached, так что теперь нужно попробовать без сжатия. Если он работает, то существует разница между реализацией Zlib в gem zlib и вашим JS-модулем, поэтому вы можете попробовать другой модуль.

Обратите внимание, что выход из memcached может потребоваться. Например, я:

    d = Rails.cache.fetch("xdtest", {:expires_in => 60.seconds}) do
        "OKGOFORCACHE"
    end

и с:

var Memcached = require('memcached');
var memcached = new Memcached('localhost:11211', {retries:10,retry:10000,remove:true,failOverServers:[ ]});


memcached.get('Frontend:xdtest', function (err, data) {
  console.log(data);
});

Я получаю

"OKGOFORCACHE:ET

Не уверен, что если это вещь протокола или что, так что просто .log ваш выход после прочтения ключа.

Ответ 2

Попробуйте с inflateRaw следующим образом:

client = new Memcached.Client(MEMCACHED_HOSTNAME, Memcached.Adapter.raw);

client.get(key, function (err, response) {
  var data = response[key];

  zlib.inflateRaw(data.buffer, function (err, buf) {
    console.log(err, buf);
  });
});