在PHP和Python中共享Memcache

2 投票
3 回答
2652 浏览
提问于 2025-04-17 08:17

我想在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 个回答

0

我遇到过类似的问题,使用的是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()方法把它转换成数组,这样就能正常工作了。

0

当你通过 Python 的 memcached 存放数据时,这些数据可能是经过“腌制”(pickled)处理的。这样一来,PHP 就没办法把它“腌制”回来了。我建议你可以尝试使用一些非常基础的数据类型,比如 ctypes?或者直接用原始字符串?

3

终于搞定了。很多东西都没有按预期工作。

  1. 一个问题是,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)。

  2. CakePhp在1.3.3之前会在memcached中存储所有键时加一个额外的key_expires键,标志为768等等。没有这个额外的键,它就找不到你想要的键。幸运的是,这种行为在后来的Cakephp版本中被去掉了(我直接升级到了1.3.13),现在运行得很好。

撰写回答