【问题标题】:data stored by pylibmc cannot be uncompressed in php memcachedpylibmc 存储的数据无法在 php memcached 中解压
【发布时间】:2012-12-17 10:40:55
【问题描述】:

我们有一个应用程序,我们使用 python 在 memcached 中存储大量数据。我们在 python 中使用 pylibmc,在 php 端,我们使用 php-memcached 库。总结

  • pylibmc v.1.2.3
  • php-memcached v.2.0.1
  • libmemcached v1.0.8。

除了压缩发挥作用外,其他一切都很好。这就是python中数据的压缩方式

import pylibmc

mem = pylibmc.Client(['10.90.15.104:11211'], binary=True)
mem.set('foo','this is a rather long string. this is a rather '+
'long string. this is a rather long string. this is a rather' + 
'long string. this is a rather long string', 0, 10)

在 telnet 中检查我们看到一些乱码值,这意味着它被压缩了。现在用 php 读取它。

$memd = new Memcached();
$memd->addServer('10.90.15.104', 11211);
echo $memd->get('foo');

当上面运行时,我们得到相同的乱码值,这意味着它没有被解压缩。 pylibmc 正在使用 zlib,因此我也将 php 的压缩类型更改为 zlib。还需要做什么设置?请帮忙。

为了进一步参考,这里是在 python pylibmc 中设置字符串后 memcached 的输出

get foo
VALUE foo 8 40
x+��,V�D��Ē��"����t�⒢̼t=���g\5#
END

这是使用 PHP 的 memcached 客户端存储的字符串的 memcached 输出:

get foo
VALUE foo 48 44
�x�+��,V�D��Ē��"����t�⒢̼t=���g\5#
END

如您所见,这其中有些可疑之处。 pylibmc 中的压缩大小为 40 字节,使用 php-memcached 压缩的相同数据为 44 字节。另请注意,使用 pylibmc 存储时标志为 8,使用 php-memcached 存储时标志为 48!

【问题讨论】:

    标签: php python memcached zlib libmemcached


    【解决方案1】:

    我认为您观察到的原因是 memcache 本身没有实现压缩 所以每个库都以自己的方式进行,只需比较用于指示压缩正在使用的标志

    pylibmc定义

    #define PYLIBMC_FLAG_ZLIB (1 << 3) (所以这是标志 == 8)

    php-memcached

    #define MEMC_VAL_COMPRESSED (1<<4)

    #define MEMC_VAL_COMPRESSION_ZLIB (1<<5)

    #define MEMC_VAL_COMPRESSION_FASTLZ (1<<6)

    所以我认为除非您愿意修改其中一个库以使其标志与另一个一致,否则没有出路

    编辑: 好的,这是一个小补丁,它为 pylibmc 和 php-memcached 同步提供压缩支持。见我的githubfork of pylibmc

    Big fat warring - 它只适用于字符串,所以如果你想存储对象,你必须自己进行反序列化(JSON)。

    【讨论】:

    • 哇,谢谢你把它挖出来。但是这些标志的修改会起作用吗?
    • 我会说它也取决于存储的类型,对于像 ints 这样简单的东西,它应该可以工作(前提是你会让库就类型标志达成一致,并且如果你将 php 压缩方法从 FASTLZ 更改为ZLIB),对于对象,它会有所不同,因为我相信 php 将它们存储为 JSON 并将 python 存储为泡菜
    • 好吧,那么(对于字符串)只要统一压缩方法和标志就可以了:)
    • 你会是我的救星!! :)
    • 好的,无论出于何种原因,我认为标志是十六进制的,而实际上它们是二进制的,所以 php 似乎同时设置了 MEMC_VAL_COMPRESSEDMEMC_VAL_COMPRESSION_ZLIB(如 OP 中所见),尝试过并得到了 @ 987654330@ 所以这 4 个字节会有所不同
    【解决方案2】:

    拉伯,

    正如你所说,我做了改变

    1. 将 php 压缩方法从 FASTLZ 更改为 ZLIB
    2. 在 _pylibmcmodule.h 文件中将 pyLibmc 标志更改为 1

      #define PYLIBMC_FLAG_ZLIB (1 << 5)
      

    这些更改是否正确? 还需要做些什么吗? 因为它不起作用,所以出现以下错误

    Warning: Memcached::get(): unknown payload type in uaTestMemcached.php on line 5
    
    bool(false)
    

    【讨论】:

    • 抱歉,我知道关于 php 的 zilch,它支持 memcache,什么是 uaTestMemcached.php?,还有当你存储通过 python 和 php 压缩的东西时,标志现在看起来如何?
    • uaTestMemcached.php 是这里使用的 php 测试脚本。这是在 python pylibmc 中设置字符串后 memcached 的输出(在您建议的更改之后)get fooVALUE foo 8 42x+��,V�D��Ē��"����t�⒢̼t=�*�m0&lt;05END
    • 看来你对pylibmc的修改没有生效,我无法重现,因为php-memcached不会为我压缩任何东西(不知道为什么)
    • 需要在php.ini中设置memcached.compression_threshold为'10'字节,默认为2000字节memcached.compression_threshold=10
    • @amolrajoba:我知道那种痛苦。在文档中给出 100 字节,但默认为 2000 ! :O
    猜你喜欢
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    相关资源
    最近更新 更多