在PHP和Python中共享Memcache
我想在Python和PHP之间共享一个Memcache的键。Python负责写这个键,而PHP负责读取它。我使用的是Cakephp框架,搭配php-pecl-memcache(不是php-pecl-memcached),还有python-memcache这个Python库。
Python代码:
mc = memcache.Client( ["127.0.0.1:11211"])
key = "key1"
value = 1323779849
mc.set(key, value)
PHP代码:
echo Cache::read('key1', 'memcached');
但是PHP无法读取这个变量,我遇到了奇怪的错误:“MemcachePool::get() [http://php.net/memcachepool.get]: 解压数据失败”。我怀疑这和每个库中设置的memcached标志不同有关。
当我用telnet连接到memcached时,发生了以下情况:
Python设置键:
get key1
VALUE key1 1 12
1323779849
.
END
PHP设置键:
get key1
VALUE key 1 0 12
1323779849
END
- 有没有办法覆盖这些标志,让它们“各自为政”?
- 有没有更兼容的php/python memcache库可以一起使用?
- 或者,有没有简单的方法可以在Python和PHP之间创建一个公共的内存空间?
3 个回答
我遇到过类似的问题,使用的是PHP和pymemcache。我用一个叫做serialize的功能把Python字典转换成了一种格式,然后把它写入了memcache。PHP这边也有自己存储到memcache的方法,结果发现用PHP和Python写入的memcache值看起来是一样的,但PHP却无法正确读取Python写入的值,这让我很困惑。PHP把它当成了字符串,无法把它转换成数组。
后来我用netcat工具查看memcache的值,结果是这样的:
echo -e 'get my-key\r' | nc 192.168.1.17 11211
Python写入的值返回的是:
VALUE my-key 0 1460
而PHP写入的值则是:
VALUE my-key 1 1460
我不知道该如何处理这些标记,所以我在PHP那边做了个简单的处理:如果我得到的是一个字符串,比如"a:{s:6..."而不是数组,我就用PHP的unserialize()方法把它转换成数组,这样就能正常工作了。
当你通过 Python 的 memcached 存放数据时,这些数据可能是经过“腌制”(pickled)处理的。这样一来,PHP 就没办法把它“腌制”回来了。我建议你可以尝试使用一些非常基础的数据类型,比如 ctypes?或者直接用原始字符串?
终于搞定了。很多东西都没有按预期工作。
一个问题是,php和python在做不同事情时使用的标志不一样。 如果你只用php或者只用python,这不是问题,但在不同环境之间沟通时就会成问题。一个有用的资源是 http://www.hjp.at/zettel/m/memcached_flags.rxml,它显示python-memcache的标志用长整型表示为'2',而php-memcache不理解这个,所以就出现了压缩错误。我修改了python-memcache,在设置函数中加入了一个'flag-override'。这个变量可以强制使用特定的标志,不管python memcache认为应该是什么。这样我就能把Int的标志从2改成0。我可能会把当前版本的python-memcache分支出来,并提交到Github。这让我能够把python的长整型标志(2)强制改成php能理解的(0)。
CakePhp在1.3.3之前会在memcached中存储所有键时加一个额外的key_expires键,标志为768等等。没有这个额外的键,它就找不到你想要的键。幸运的是,这种行为在后来的Cakephp版本中被去掉了(我直接升级到了1.3.13),现在运行得很好。