晓夏

北漂的女孩

Good Luck To You!

PHP扩展memcache、memcached扩展不兼容导致缓存的数据序列化

浏览量:442

背景

最近公司许多团队进行升级php7,目前支持php7读取mc的扩展只有memcached。

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

验证

验证memcache扩展和memcached扩展读写数组数据是否不相兼容

<?php
echo "========== test  string  ============\n";
$mc = new Memcache;
$mc->connect('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  ============\n";
$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时的序列化方法不同。于是乎进行进一步的测试:

<?php
echo "========== test  array  ============\n";
$mc = new Memcache;
$mc->connet('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 msession.vip.vip.co.

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定义会不相同呢。 抱着这个疑问,试着通过阅读两个扩展的源码查找原因。



神回复

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。