.NET JAVA PHP中写入及读取memcache中数据不一致问题
来源:互联网 发布:汉高百得美缝剂淘宝 编辑:程序博客网 时间:2024/06/07 17:14
如题,公司现在有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,
另外关于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中去。
目前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,
我修改整理后的BelTMemcached项目地址(带演示Demo代码) :(下载)
另外关于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中去。
- .NET JAVA PHP中写入及读取memcache中数据不一致问题
- 在线迁移中tapdisk2读取的数据不一致问题
- php将session写入memcache中。
- PHP和分布式Memcache的遇到数据不一致问题
- Session保存到Memcache中,解决读取数据慢问题
- ios sqlite中写入图片二进制数据及读取
- ios sqlite中写入图片二进制数据及读取
- Java 实现Excel表数据的读取和写入 以及过程中可能遇到的问题
- Java从.CSV文件中读取数据和写入
- Java从.CSV文件中读取数据和写入
- php向mysql中写入中文数据的问题
- php之session最优将信息写入memcache中管理
- php 读取memcache二进制数据
- 读取postgis中数据写入shapefile-1
- 读取postgis中数据写入shapefile-2
- 读取postgis中数据写入shapefile-3
- gams 从表格中读取 写入数据
- iOS中plist,数据写入与读取
- MySQL 字段数据类型/长度
- Linux下查看.so和可执行文件是否debug编译
- 不管你学的是什么专业,你都应该多少懂些管理学
- PCB板绘制经验总结
- 实用技巧:利用4G U盘安装Fedora Linux
- .NET JAVA PHP中写入及读取memcache中数据不一致问题
- AJAX 编码
- 黑马程序员-银行调度系统
- 新家
- 数组排序方法及C实现的总结
- Bitmap和Drawable相互转换方法
- Notification状态栏通知
- 四个人 “谁做的好事”,三个为说假话,一个说真话!
- Root :: AOAPC I: Beginning Algorithm Contests (Rujia Liu) :: Volume 0. Getting Started 488 -