资讯专栏INFORMATION COLUMN

php的memcache扩展和memcached扩展读写数组不相兼容原因探究

adam1q84 / 2826人阅读

摘要:背景最近公司许多团队进行升级,目前支持读取的扩展只有。验证验证扩展和扩展读写数组数据是否不相兼容测试脚本执行结果从结果来看,印证了我们之前的说法。为了保证扩展和扩展直接写的数据可以相互读取,只能用的格式写入。

背景

最近公司许多团队进行升级php7,目前支持php7读取mc的扩展只有memcached。
但是公司许多项目都会共用一个mc集群来存取用户session数据,存的时候是登陆时用memcache扩展以array的形式写进去,读的时候自然是用memcache扩展以array的形式读出来。 但是现在只能使用memcached进行读取。但是据我所知两者读取array形式的数据是互不兼容的,因此想探究一下究竟是为什么。

验证

验证memcache扩展和memcached扩展读写数组数据是否不相兼容
测试脚本:

addServer("10.199.189.129", 11511); 
$key = "testString"; 
$mc->set($key, "test success"); 
var_dump($mc->get($key)); 
$mc2 = new memcached; 
$mc2->addServer("10.199.189.129", 11511); 
var_dump($mc2->get($key)); 
echo "========== test array ============
"; 
$key2 = "testArray"; 
$mc->set($key2, [1,2,3]); 
var_dump($mc->get($key2)); 
var_dump($mc2->get($key2));

执行结果:

➜ ~ php /apps/dat/test.php 
========== test string ============ 
string(12) "test success" 
string(12) "test success" 
========== test array ============ 
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } 
int(0)

从结果来看,印证了我们之前的说法。

猜测原因

由于string没有问题,出问题是在array格式里面。所以怀疑是array存进mc时的序列化方法不同。于是乎进行进一步的测试:
编写测试脚本

addServer("10.199.189.129", 11511); 
$mc2 = new memcached; 
$mc2->addServer("10.199.189.129", 11511); 
$key2 = "testArray1"; 
$key3 = "testArray2"; 
$mc->set($key2, [1,2,3]); 
$mc2->set($key3, [1,2,3]); 
var_dump($mc->get($key2)); 
var_dump($mc2->get($key3));

执行结果:

➜ ~ php /apps/dat/test.php 
========== test array ============ 
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } 
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

接下来直接连接mc进行查看

➜ ~ telnet 10.199.189.129 11511 
Trying 10.199.189.129... 
Connected to 10.199.189.129
Escape character is "^]". 
get testArray1 
VALUE testArray1 1 30 
a:3:{i:0;i:1;i:1;i:2;i:2;i:3;} 
END 
get testArray2 
VALUE testArray2 4 30 
a:3:{i:0;i:1;i:1;i:2;i:2;i:3;} 
END

从结果来看,我们可以发现,memcache和memcached写到mc里面的结果是一样的,也就是说我们的猜测是错误的。两个值的序列化处理一模一样,区别在于值的flag不同。 memcache存储array数据的时候,falg为1,而memcached为4. 我们知道,mc中值的flag是提供给使用者自定义,方便再读取的时候做不同的处理。但是为什么两者的flag定义会不相同呢。 抱着这个疑问,试着通过阅读两个扩展的源码查找原因。

阅读两个扩展的源码 memcache

php_memcache.h:

#define MMC_SERIALIZED 1 
#define MMC_COMPRESSED 2
memcached

php_memcached.c

#define MEMC_VAL_IS_STRING 0 
#define MEMC_VAL_IS_LONG 1 
#define MEMC_VAL_IS_DOUBLE 2 
#define MEMC_VAL_IS_BOOL 3 
#define MEMC_VAL_IS_SERIALIZED 4 
#define MEMC_VAL_IS_IGBINARY 5 
#define MEMC_VAL_IS_JSON 6 
#define MEMC_VAL_IS_MSGPACK 7

经阅读源码,发现memcache将array的数组格式的flag定义为1,而memcached为了将php存进mc中的值进行详细的类型区分,将数据类型定义了string,long,double等等的数据类型。
也就是说,当你使用memcache的时候,运行

addServer("10.199.189.129", 11511); 
$mc->set("123",1); 
var_dump($mc->get("123"));

执行结果是:

 string(1) "1"

你明明存了一个值为数字1的key,但是读取的时候却为字符串。 而当你使用memcached的时候,运行

addServer("10.199.189.129", 11511); 
$mc->set("123",1); 
var_dump($mc->get("123"));

执行结果是:

 int(1)
结论

memcache扩展和memcached扩展读写数组数据不相兼容的原因是,memcached为了详细地区分数据类型,定义了各种数据类型的标识,而其中数组的标识与memcache定义的数组标识不一致导致。
为了保证memcache扩展和memcached扩展直接写的数据可以相互读取,只能用string的格式写入mc。
经过这次探究,也让我认识到许多memcached比memcache更优秀的地方,相信随着php7的普及,memcache会加速地被历史所淘汰。

转载注明来源:
作者: Akay
本文地址: [http://www.akayzhang.com/arti...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21937.html

相关文章

  • phpmemcache扩展memcached扩展读写数组不相兼容原因探究

    摘要:背景最近公司许多团队进行升级,目前支持读取的扩展只有。验证验证扩展和扩展读写数组数据是否不相兼容测试脚本执行结果从结果来看,印证了我们之前的说法。为了保证扩展和扩展直接写的数据可以相互读取,只能用的格式写入。 背景 最近公司许多团队进行升级php7,目前支持php7读取mc的扩展只有memcached。但是公司许多项目都会共用一个mc集群来存取用户session数据,存的时候是登陆时用...

    dreamtecher 评论0 收藏0
  • PHP面试常考内容之MemcacheRedis(1)

    摘要:以下正文的部分内容来自程序员面试笔试宝典书籍,如果转载请保留出处一什么是是一个开源免费高性能的分布式对象缓存系统,它基于一个存储键值对的来存储数据到内存中。预告面试常考内容之和将于本周三更新。 你好,是我琉忆。继上周(2019.2-11至2-15)发布的PHP面试常考内容之面向对象专题后,发布的第二个专题,感谢你的阅读。本周(2019.2-18至2-22)的文章内容点为以下几点,更新时...

    wenyiweb 评论0 收藏0
  • PHP面试常考内容之MemcacheRedis(1)

    摘要:以下正文的部分内容来自程序员面试笔试宝典书籍,如果转载请保留出处一什么是是一个开源免费高性能的分布式对象缓存系统,它基于一个存储键值对的来存储数据到内存中。预告面试常考内容之和将于本周三更新。 你好,是我琉忆。继上周(2019.2-11至2-15)发布的PHP面试常考内容之面向对象专题后,发布的第二个专题,感谢你的阅读。本周(2019.2-18至2-22)的文章内容点为以下几点,更新时...

    nanfeiyan 评论0 收藏0
  • Mac安装memcached扩展支持sasl

    摘要:安装扩展支持在服务以及扩展中,默认都是不支持用户名和密码,但是如果需要可以通过打开来提供用户名和密码服务。最后在修改对应的文件增加扩展重启,大功告成以上内容仅供参考 Mac安装memcached扩展支持sasl Memcached在服务以及扩展中,默认都是不支持用户名和密码,但是如果需要可以通过打开sasl来提供用户名和密码服务。所以在memcached的扩展与服务器安装时都需要启用s...

    qieangel2013 评论0 收藏0
  • Mac安装memcached扩展支持sasl

    摘要:安装扩展支持在服务以及扩展中,默认都是不支持用户名和密码,但是如果需要可以通过打开来提供用户名和密码服务。最后在修改对应的文件增加扩展重启,大功告成以上内容仅供参考 Mac安装memcached扩展支持sasl Memcached在服务以及扩展中,默认都是不支持用户名和密码,但是如果需要可以通过打开sasl来提供用户名和密码服务。所以在memcached的扩展与服务器安装时都需要启用s...

    TANKING 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<