php的memcache擴(kuò)展和memcached擴(kuò)展讀寫數(shù)組數(shù)據(jù)不相兼容原因探究

出處:http://www.akayzhang.com/article/6

背景

最近公司許多團(tuán)隊(duì)進(jìn)行升級php7,目前支持php7讀取mc的擴(kuò)展只有memcached。

但是公司許多項(xiàng)目都會共用一個(gè)mc集群來存取用戶session數(shù)據(jù),存的時(shí)候是登陸時(shí)用memcache擴(kuò)展以array的形式寫進(jìn)去,讀的時(shí)候自然是用memcache擴(kuò)展以array的形式讀出來。 但是現(xiàn)在只能使用memcached進(jìn)行讀取。但是據(jù)我所知兩者讀取array形式的數(shù)據(jù)是互不兼容的,因此想探究一下究竟是為什么。

驗(yàn)證

驗(yàn)證memcache擴(kuò)展和memcached擴(kuò)展讀寫數(shù)組數(shù)據(jù)是否不相兼容

測試腳本:

echo "========== test? string? ============\n";

$mc = new Memcache;

$mc->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? ============\n";

$key2 = 'testArray';

$mc->set($key2, [1,2,3]);

var_dump($mc->get($key2));

var_dump($mc2->get($key2));

執(zhí)行結(jié)果:

?? ~ 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)

從結(jié)果來看,印證了我們之前的說法。以字符串類型的數(shù)據(jù)

猜測原因

由于string沒有問題,出問題是在array格式里面。所以懷疑是array存進(jìn)mc時(shí)的序列化方法不同。于是乎進(jìn)行進(jìn)一步的測試:

編寫測試腳本

echo "========== test? array? ============\n";

$mc = new Memcache;

$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));

執(zhí)行結(jié)果:

?? ~ 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進(jìn)行查看

?? ~ 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

從結(jié)果來看,我們可以發(fā)現(xiàn),memcache和memcached寫到mc里面的結(jié)果是一樣的,也就是說我們的猜測是錯(cuò)誤的。兩個(gè)值的序列化處理一模一樣,區(qū)別在于值的flag不同。 memcache存儲array數(shù)據(jù)的時(shí)候,falg為1,而memcached為4. 我們知道,mc中值的flag是提供給使用者自定義,方便再讀取的時(shí)候做不同的處理。但是為什么兩者的flag定義會不相同呢。 抱著這個(gè)疑問,試著通過閱讀兩個(gè)擴(kuò)展的源碼查找原因。

閱讀源碼

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

經(jīng)閱讀源碼,發(fā)現(xiàn)memcache將array的數(shù)組格式的flag定義為1,而memcached為了將php存進(jìn)mc中的值進(jìn)行詳細(xì)的類型區(qū)分,將數(shù)據(jù)類型定義了string,long,double等等的數(shù)據(jù)類型。

也就是說,當(dāng)你使用memcache的時(shí)候,運(yùn)行

$mc = new memcache;

$mc->addServer('10.199.189.129', 11511);

$mc->set('123',1);

var_dump($mc->get('123'));

執(zhí)行結(jié)果是:

string(1) "1"

你明明存了一個(gè)值為數(shù)字1的key,但是讀取的時(shí)候卻為字符串。 而當(dāng)你使用memcached的時(shí)候,運(yùn)行

$mc = new memcached;

$mc->addServer('10.199.189.129', 11511);

$mc->set('123',1);

var_dump($mc->get('123'));

執(zhí)行結(jié)果是:

int(1)

結(jié)論

memcache擴(kuò)展和memcached擴(kuò)展讀寫數(shù)組數(shù)據(jù)不相兼容的原因是,memcached為了詳細(xì)地區(qū)分?jǐn)?shù)據(jù)類型,定義了各種數(shù)據(jù)類型的標(biāo)示,而導(dǎo)致其中數(shù)組的標(biāo)識與memcache定義的數(shù)組標(biāo)識不一致導(dǎo)致。 經(jīng)過這次探究,也讓我認(rèn)識到許多memcached比memcache更優(yōu)秀的地方,相信隨著php7的普及,memcache會加速地被歷史所淘汰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、memcache的概念? Memcache是一個(gè)高性能的分布式的內(nèi)存對象緩存系統(tǒng),通過在內(nèi)存里維護(hù)一個(gè)統(tǒng)一的巨...
    桖辶殤閱讀 2,356評論 2 12
  • redis這個(gè)新產(chǎn)品在sns時(shí)很火,而memcache早就存在, 但redis提供出來的功能,好多網(wǎng)站均把它當(dāng)me...
    常曉曉閱讀 1,051評論 1 8
  • PHP7 已經(jīng)出來1年了,PHP7.1也即將和大家見面,這么多好的特性,好的方法,為什么不使用呢,也希望PHP越來...
    夢幻_78af閱讀 2,229評論 1 10
  • 1.為什么要使用memcache 由于網(wǎng)站的高并發(fā)讀寫需求,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫開始出現(xiàn)瓶頸,例如: 1)對數(shù)據(jù)庫的...
    蘇文星閱讀 1,881評論 0 5
  • 資訊類:人人 :http://www.woshipm.com/36氪:http://36kr.com/,看Next...
    斯瓦西里閱讀 1,974評論 2 11

友情鏈接更多精彩內(nèi)容