25

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

这个 API 使得将嵌套的 Python 列表、字典和元组存储在 memcached 中变得简单而快速,并且将这些对象读回应用程序是完全透明的——它可以正常工作。

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

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

  1. XML - 主要的好处是它是人类可读的,但这在这个应用程序中并不重要。XML 也占用大量空间,而且解析成本很高。

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

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

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

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

  2. 处理嵌套数据结构

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

  4. 最小内存占用

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

5 回答 5

7

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

如果您对此感到满意,那么您可以看一下:

  1. 协议缓冲区 - http://code.google.com/apis/protocolbuffers/docs/overview.html
  2. Thrift - http://developers.facebook.com/thrift/(更适合服务)

这两种解决方案都需要支持文件来定义每个数据结构。


如果您不想招致开发人员预定义每个结构的开销,请查看:

  1. JSON(通过 python cjson 和原生 PHP json)。如果您不需要传输二进制内容(例如图像等),两者都非常快。
  2. 另一种标记语言@ http://www.yaml.org/。如果您获得正确的库,也非常快。

但是,我认为这两种方法在传输二进制内容方面都存在问题,这就是为什么它们被排除在我们使用之外的原因。 注意: YAML 可能有很好的二进制支持,你必须检查客户端库——见这里:http: //yaml.org/type/binary.html


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

如果循环中的迭代次数过多或必须查看每个字符,PHP 和 Python 等动态语言会变得非常慢。另一方面,C 则擅长此类操作。

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

于 2009-02-19T06:14:44.950 回答
6

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

我看到 3:1 压缩,因此所有数据都适合内存缓存,并且应用程序的响应时间低于 10 毫秒,包括页面渲染。

这是 JSON、Thrift、Protocol Buffers 和 YAML 的比较,有和没有压缩:

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

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

于 2009-03-01T20:47:27.830 回答
3

“跨平台支持(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 模块。

于 2009-01-31T22:13:41.403 回答
2

您可能对此链接感兴趣:

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

另一种选择:MessagePack 似乎是最快的序列化程序。也许你可以试一试。

于 2010-09-16T02:07:53.423 回答
1

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

https://github.com/bgilmore/mustaine

该协议的官方文档可以在这里找到:

http://hessian.caucho.com/

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

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

于 2012-02-16T21:25:25.093 回答