用berkelyDB持久化memcached时bug解决过程记录——第一次读取报MEMCACHED_UNKOWN_READ_FAILURE错误

【问题背景】
       我们的程序是一个基于tuxedo交易中间件发布的服务,以.so方式更新程序,起停serveice。
由于memcached在程序重启之后,已有缓存数据会全部失效,在访问量大且数据变化较小的情况下,会造成顺时延时长。所以用嵌入式轻量级数据库berkeleyDB(以下简称bdb)对其进行改造:
       1)存memcached同时,存入bdb;
       2)读取memcached时,如果查不到数据,再查一次bdb,bdb存在则存入memcached。
      memcaced是用一个daemon service(tuxedo平台下)调用一个起停脚本管理的,打印不出调试信息。遂停止daemon,手动起停,发现只会第一次不命中,而之前是一直不命中。
【版本】
        memcached1.4.4
         libmemcached4.0.0
         berkely db4.7.25
        g++4.1.2
【问题描述】
       改造完成后,停止daemon,手动起停,程序在第一次读取改造后的memcached(以下称之为bdb_memcached)总是未命中且提示MEMCACHED_UNKOWN_READ_FAILURE,第一次之后完全正常。
【解决历史】
      0.memcaced是用一个daemon程序起停的,手动起试试。发现只会第一次不命中,而之前是一直不命中。
1.怀疑是第一次读取时,bdb因为延时还没启动。修改在memcaced启动bdb时,加sleep(20),问题依然存在。
2.bdb数据文件权限。修改为所有人可读,不行。
3.查看libmemcached接口mget和memcached_fetch_result()源码,看MEMCACHED_UNKOWN_READ_FAILURE错误是那个地方报的。由于没深入看,没发现问题。
4.用libmemcached写了一个本地可执行的程序,mget数据,发现第一次会成功。虽编译了一个local版本的程序运行,发现同样的请求,第一会命中。
5.为什么local的就能命中?为什么只第一次不命中?而后者显然是最诡异的问题!!
6.一牛相信看完libmemcached源码之后提醒:有libmemcached是用socket读取memcached的,连接建立后,会保持之,以方便在下次读取的时候,节约socket三次握手的成本。在mget的时候只是把所有请求键发到server端,而不管server是否返回数据。在调用memcached_fetch_result时,会检查都会的数据是否正常,并返回。而mget()之前,只停止memcaced,不停本地服务,本地服务会以为当前socket仍然有效,而实际服务器端已经重启。所以会第一次失败,并重连,之后就会正常。于是,停memcached的同时,停服务,再全部启动。问题解决。

【总结】

        这样解决了为什么local版本就能读到数据的问题,因为local建立的是短连接,而非长连接,所以每次都会读到数据。

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值