You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Dalli调用GET无法读取旧版Memcached实例记录的问题排查

问题原因解析

Meta协议请求失败

Memcached 1.4.4不支持Meta协议——Meta协议是在Memcached 1.4.23版本才引入实验性支持的,你的旧版服务器完全无法识别Dalli发送的mg(Meta Get)命令,直接返回ERROR,触发Dalli的Dalli::DalliError。从日志也能看到,客户端协商Meta协议失败后回退到ASCII协议,但发送的mg命令依然不被支持。

二进制协议反序列化失败

二进制协议本身能和Memcached 1.4.4兼容,但数据序列化格式不匹配:

  • 你用Perl模块写入的数据,是PerlStorable模块的序列化格式,和Ruby的Marshal格式完全不同。
  • Dalli默认用RubyMarshal反序列化值,遇到Perl序列化的二进制数据时,就会因格式不兼容抛出Dalli::UnmarshalError(日志里的版本号提示是误判,本质是格式完全不同)。

修复方案

替换Meta协议为ASCII协议

改用Memcached 1.4.4支持的ASCII协议,修改Dalli初始化代码:

dc = Dalli::Client.new("<address>:11211", socket_timeout: 2.0, protocol: :ascii, namespace: 'ws')
dc.get('item_679')

注意:ASCII协议下Dalli依然会自动用Marshal反序列化,所以读取Perl写入的数据时,还要配合下面的步骤。

处理跨语言序列化兼容问题

  1. 获取原始二进制数据:添加raw: true选项,让Dalli跳过自动反序列化,返回原始数据:
    raw_data = dc.get('item_679', raw: true)
    
  2. 解析Perl Storable格式:安装ruby-storable gem(gem install ruby-storable),用它解析原始数据:
    require 'storable'
    parsed_data = Storable.load(raw_data)
    

额外建议

  • Memcached 1.4.4是2011年的老旧版本,存在安全漏洞和性能瓶颈,建议尽快升级到1.6.x及以上版本。
  • 如果需要Ruby和Perl共享Memcached数据,建议统一使用JSON这种跨语言的序列化格式,避免语言特定序列化带来的兼容问题。

内容的提问来源于stack exchange,提问作者ThorTL67

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:55:30