设为首页 收藏本站
查看: 1019|回复: 0

[经验分享] .NET JAVA PHP中写入数据及读取memcache数据不一致问题

[复制链接]

尚未签到

发表于 2015-8-31 08:41:03 | 显示全部楼层 |阅读模式
如题,公司现在有asp网站,有java工程,未来需要逐步把asp网站改成php网站,公司缓存使用memcache及redis,
目前asp是通过调用.NET开发的com+组件读取写入数据到memcache中,原来没发现什么问题,最近手里有个工程用java做的,发现java和.NET组件对memcach操作后,数据得到的不一致甚至得不到数据。.NET组件使用的开源代码,我选择的版本是:beitmemcached,项目地址:http://code.google.com/p/beitmemcached/  
java使用的是java_memcached-release_2.5.2.jar
php使用的是http://pecl.php.net/package/memcached
通过telnet memcache服务及memcache协议发现flag不一致,进一步分析源码,得到以下不同:
.NET
    internal enum SerializedType : ushort
    {
        ByteArray    = 0,
        Object        = 1,
        String        = 2,
        Datetime    = 3,
        Bool        = 4,
        //SByte        = 5, //Makes no sense.
        Byte        = 6,
        Short        = 7,
        UShort        = 8,
        Int            = 9,
        UInt        = 10,
        Long        = 11,
        ULong        = 12,
        Float        = 13,
        Double        = 14,
        CompressedByteArray    = 255,
        CompressedObject    = 256,
        CompressedString    = 257,
    }

JAVA:
    public static final int MARKER_BYTE             = 1;
    public static final int MARKER_BOOLEAN          = 8192;
    public static final int MARKER_INTEGER          = 4;
    public static final int MARKER_LONG             = 16384;
    public static final int MARKER_CHARACTER        = 16;
    public static final int MARKER_STRING           = 32;
    public static final int MARKER_STRINGBUFFER     = 64;
    public static final int MARKER_FLOAT            = 128;
    public static final int MARKER_SHORT            = 256;
    public static final int MARKER_DOUBLE           = 512;
    public static final int MARKER_DATE             = 1024;
    public static final int MARKER_STRINGBUILDER    = 2048;
    public static final int MARKER_BYTEARR          = 4096;
    public static final int F_COMPRESSED            = 2;
    public static final int F_SERIALIZED            = 8;
修改了.NET中部分flag定义,考虑到每种语言的不同性,所以只保证简单的字符串能够在各语言中通用,把 String        = 2,改为 String        = 32,
这样也能保证php中没问题。php在$mem->set(key,value,32expire);这个32是必须的(表示字符串)。对象的话可以转为json再存到memcache中去,(这是使用pecl中memcache这个客户端的情况)
另外关于hash算法的,考虑到通用,使用crc32来做hash算法,需要修改ServerPool中
internal ServerPool(string[] hosts) {
    List<SocketPool> pools = new List<SocketPool>();
    foreach(string host in hosts) {
        SocketPool pool = new SocketPool(this, host.Trim());
        pools.Add(pool);
    }
    hostList = pools.ToArray();
}
internal SocketPool GetSocketPool(uint hash) {
    if (hostList.Length == 1) {
        return hostList[0];
    }
    return hostList[hash % hostList.Length];
}
及MemcachedClient中hash方法的代码为使用crc32
写到这问题并没有完全解决,当使用http://pecl.php.net/package/memcache做php客户端的情况,这个客户端不支持选择自己需要的hash算法,并且此客户端已经很久没有更新了。
首推使用http://pecl.php.net/package/memcached做php客户端,问题还没完,进过测试发现这样的情况:
java写入,php、.net均可正常读取
.net写入,php、java均可正常读取
php写入,java无法正常读取,.net可正常读取,
分析源代码发现,这个php客户端写入数据的时候,flag总设置为0,没有设置成我们需要的,为了保证三大语言均能正常读取写入,我们可以更改源代码php_memcached.c中的static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool by_key)方法,在switch(op)增加一行代码    flags = 32;这样设置后,phpize、./configure、make、make install。
这样设置有个前提,所有存入memcache中的对象均需序列号,数据读取出来后再反序列化即可,当然,其它简单数据类型也需要转换成字符串才能存入到memcache中去。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-106556-1-1.html 上篇帖子: memcache(三)内存管理 下篇帖子: php上的memcache和memcached两个pecl库
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表