我有一个Rails应用程序,它通过Dalli gem(https://github.com/mperham/dalli)缓存memcached中的数据。
我想从Node.js读取此缓存的内容。我正在使用mc模块与Node.js中的memcached进行交互。
我遇到的问题是编码和压缩。 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的字符串值返回的缓冲区如下所示:
'\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]
答案 0 :(得分:0)
请注意,默认情况下,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
不确定它是协议还是什么,所以只需在读取密钥后记录输出。
答案 1 :(得分:0)
尝试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);
});
});
答案 2 :(得分:0)
上面没有提到的重要细节:dalli默认使用ruby native marshalling来序列化值。
如果您想使用多种语言的memcached值,请考虑使用其他serializer
,请参阅有关配置https://github.com/petergoldstein/dalli#configuration的文档