memcached中对象的最佳序列化方法是什么?

时间:2009-01-31 21:17:24

标签: python serialization xml-serialization memcached protocol-buffers

我的Python应用程序当前使用python-memcached API来设置和获取memcached中的对象。此API使用Python的本机pickle module来序列化和反序列化Python对象。

这个API使得在memcached中存储嵌套的Python列表,字典和元组变得简单快捷,将这些对象读回应用程序是完全透明的 - 它只是起作用。

但是我不想仅限于使用Python,如果所有的memcached对象都是用pickle序列化的,那么用其他语言编写的客户端将无法工作。

这是跨平台的序列化我考虑过的选项:

  1. XML - 主要的好处是它是人类可读的,但在这个应用程序中并不重要。 XML也占用了很多空间,解析起来很昂贵。

  2. JSON - 似乎是一个很好的跨平台标准,但我不确定它是否在从memcached读回时保留了对象类型的特征。例如,根据this post,使用simplejson时元组会转换为列表;此外,似乎向JSON结构添加元素可能会破坏写入旧结构的代码

  3. Google Protocol Buffers - 我对此非常感兴趣,因为它看起来非常快速和紧凑 - 至少比XML小10倍且速度快;它不是人类可读的,但对于这个应用程序来说并不重要;它似乎旨在支持增长结构而不破坏旧代码

  4. 考虑到这个应用程序的优先级,memcached的理想对象序列化方法是什么?

    1. 跨平台支持(Python,Java,C#,C ++,Ruby,Perl)

    2. 处理嵌套数据结构

    3. 快速序列化/反序列化

    4. 最小内存占用

    5. 在不破坏旧代码的情况下灵活地更改结构

5 个答案:

答案 0 :(得分:7)

一个主要考虑因素是“您是否希望指定每个结构定义”

如果你对此感到满意,那么你可以看看:

  1. Protocol Buffers - http://code.google.com/apis/protocolbuffers/docs/overview.html
  2. Thrift - http://developers.facebook.com/thrift/(更倾向于服务)
  3. 这两种解决方案都需要支持文件来定义每个数据结构。


    如果您不想承担预先定义每个结构的开发人员费用,请查看:

    1. JSON(通过python cjson和本机PHP json)。如果您不需要传输二进制内容(例如图像等),两者都非常快。
    2. 另一种标记语言@ http://www.yaml.org/。如果你得到合适的图书馆,也非常快。
    3. 但是,我认为这两者都存在传输二进制内容的问题,这就是为什么它们被排除在我们的使用之外。 注意: YAML可能具有良好的二进制支持,您必须检查客户端库 - 请参阅此处:http://yaml.org/type/binary.html


      在我们公司,我们推出了自己的库(Extruct),用于跨语言序列化和二进制支持。我们目前在Python和PHP中具有(相当)快速的实现,尽管由于在所有字符串上使用base64(二进制支持),它不是非常易读的。最终我们将它们移植到C并使用更多标准编码。

      如果在循环中有太多迭代或者必须查看每个字符,PHP和Python等动态语言会变得非常慢。另一方面,C对此类行动感到非常满意。

      如果你想看看Extruct的实现,请告诉我。 (联系信息在{关于我“”下的http://blog.gahooa.com/

答案 1 :(得分:7)

我尝试了几种方法,并将压缩的JSON作为速度和内存占用之间的最佳平衡。 Python的原生Pickle函数稍微快一些,但生成的对象不能与非Python客户端一起使用。

我看到3:1压缩,所以所有数据都适合memcache,应用程序的响应时间不到10毫秒,包括页面渲染。

以下是JSON,Thrift,Protocol Buffers和YAML的比较,包括和不包含压缩:

http://bouncybouncy.net/ramblings/posts/more_on_json_vs_thrift_and_protocol_buffers/

看起来这个测试得到了与压缩JSON相同的结果。由于我不需要预先定义每个结构,这似乎是最快和最小的跨平台答案。

答案 2 :(得分:2)

“跨平台支持(Python,Java,C#,C ++,Ruby,Perl)”

太糟糕了,这个标准是第一位的。大多数语言背后的意图是表达基本数据结构和处理方式不同。这就是使多种语言成为“问题”的原因:它们都是不同的。

在多种语言中表现良好的单一表示通常是不可能的。代表性,表现性或模糊性的丰富性存在妥协。

JSON很好地满足了剩下的标准。消息是紧凑的并且快速解析(与XML不同)。嵌套处理得很好。在不破坏代码的情况下更改结构总是不确定的 - 如果删除某些内容,旧代码将会中断。如果您更改了所需的内容,旧代码将会中断。但是,如果您要添加内容,JSON也会处理此问题。

我喜欢人类可读的。它有助于进行大量的调试和故障排除。

让Python元组变成列表的微妙之处并不是一个有趣的问题。接收应用程序已经知道正在接收的结构,并且可以对其进行调整(如果重要的话。)


编辑效果。

http://developers.de/blogs/damir_dobric/archive/2008/12/27/performance-comparison-soap-vs-json-wcf-implementation.aspx

解析XML和JSON文档

xmlParse 0.326 jsonParse 0.255

对于相同的内容,

JSON似乎要快得多。我在Python 2.5.2中使用了Python SimpleJSON和ElementTree模块。

答案 3 :(得分:2)

您可能对此链接感兴趣:

http://kbyanc.blogspot.com/2007/07/python-serializer-benchmarks.html

另一种选择:MessagePack似乎是最快的串行器。也许你可以尝试一下。

答案 4 :(得分:1)

Hessian满足您的所有要求。这里有一个python库:

https://github.com/bgilmore/mustaine

该协议的官方文档可在此处找到:

http://hessian.caucho.com/

我经常在Java和Python中使用它。它工作,不需要编写协议定义文件。我无法告诉你Python序列化程序如何执行,但Java版本相当有效:

https://github.com/eishay/jvm-serializers/wiki/