Kryo序列化库:在生产中是否被使用?

38

Kryo是一个非常新颖和有趣的Java序列化库,也是在thrift-protobuf基准测试中最快的之一。如果您已经使用过Kryo,它是否已经达到足够的成熟度可以在生产代码中尝试?

更新(10/27/2010):我们正在使用Kryo,但尚未在生产环境中使用。有关详情,请参见下面的答案。

更新(3/9/2011):更新到最新的Jackson和Kryo库后,发现Jackson的二进制Smile序列化相当有竞争力。


关于“smile / jackson-manual”,它确实与Kryo在速度上相当。当然,Kryo是二进制的,所以更小。最大的区别在于序列化代码:[smile / jackson-manual](https://github.com/eishay/jvm-serializers/blob/kannan/tpc/src/serializers/JsonJacksonManual.java)和[Kryo](https://github.com/eishay/jvm-serializers/blob/kannan/tpc/src/serializers/Kryo.java#L57)。 Kryo只有约3行代码,而手动Jackson则有很多页。其他JSON基准测试,例如“smile / jackson-databind”不是手动的,只有几行代码,但速度慢了约2倍。 - NateS
NateS -- true,与“手动”版本的比较并不完全是苹果和苹果之间的比较;但我认为它们确实表明了所讨论格式的理论极限(kryo数据绑定比jackson更优化,在这方面做得很好!)。不过需要澄清的是:Smile也是一种二进制格式;不同之处在于,由于它是1对1的JSON序列化,因此它保留了字段名称。 - StaxMan
9个回答

23

我将尝试回答自己的问题(Kyro还非常新!)。

我们有一组约120个不同的Web服务,使用Restlet框架实现。这些服务通常由基于Restlet的客户端库构建的Web服务客户端所使用。服务器和客户端之间发送和接收的表示包括XML(使用XStream序列化库),JSON(使用Jackson),XHTML,Java对象序列化,以及截至昨天的Kryo。因此,我们可以进行一些坚实的并排比较。

Kryo 1.0.1似乎相当稳定。一旦我真正阅读了如何使用API,我发现唯一的真正问题是默认的java.util.Date序列化程序似乎会将日期提前几个月。我只需要提供自己的覆盖:

kryo.register(Date.class, 
  new SimpleSerializer<Date>() {
   @Override public void write (ByteBuffer b, Date d) { b.putLong(d.getTime()); }
   @Override public Date read (ByteBuffer b) { return new Date(b.getLong()); }
  });

但这是我目前发现的唯一可能的问题。我们有一组JavaBeans,其中包含String、Float、Integer、Long、Date、Boolean和List字段。

以下是一些粗略的基准测试结果。首先,我进行了100,000次对象层次结构的序列化和反序列化,该层次结构描述了一个电视节目(即制作了100,000个深度副本)。速度如下:

XStream XML:                 360/sec
Java Object Serialization: 1,570/sec
Jackson JSON:              5,000/sec
Kryo:                      8,100/sec

接下来,我还序列化了一份包含2,000个电视节目描述的目录,并统计了字节数:

XStream XML:         6,837,851 bytes
Jackson JSON:        3,656,654 bytes
Kryo:                1,124,048 bytes

我也发现注册序列化程序非常重要:

kryo.register(List.class);
kryo.register(ArrayList.class);
// ...
kryo.register(Program.class);
kryo.register(Catalog.class);
// ...

如果我不这样做,序列化的大小几乎是原来的两倍,速度可能会慢40%左右。
我们还对使用这四种序列化方法之一的几个Web服务进行了完整的端到端测试,并且它们也显示Kryo比其他方法运行得更快。
因此,总的来说,Kryo似乎相当健壮。 我将在我们的代码库中保留对它的支持,并且随着我们对它的经验积累,希望在更多地方使用它。 感谢Kryo团队!
更新(2011年3月9日):我最终尝试了@StaxMan建议尝试Jackson 1.6的二进制“Smile”序列化器。 使用Jackson 1.6和Kryo 1.04,我对一个稍微不同的电视节目对象层次结构进行了10万次深度复制(序列化/反序列化):
XStream XML:     429/sec    5,189 bytes
Jackson JSON:  4,474/sec    2,657 bytes
Kryo:          4,539/sec    1,066 bytes  
Jackson Smile: 5,040/sec    1,689 bytes

这个测试与宏观测试不相符,我在一个REST web服务中尝试了不同的序列化程序,该服务提供了许多这些对象。整个系统吞吐量支持@StaxMan对性能的直觉。
Jackson JSON:     92 requests/sec
Jackson Smile     97 requests/sec
Kryo:            108 requests/sec

2
好东西,谢谢你分享!一个有趣而相对容易测试的事情是看看“Smile”格式(二进制 JSON 兼容变体,请参见 http://wiki.fasterxml.com/JacksonBinaryFormat)的表现如何。由于它与 Jackson 捆绑在一起并且具有与 Jackson 的 JSON 处理完全相同的 API,因此应该很容易看到。就性能和大小而言,它应该比 Jackson/JSON 更快,但它与 Kryo 有多接近则很难说——可能在 JSON 和 Kryo 之间,也许更接近 Kryo。 - StaxMan
1
@StaxMan:你的直觉是正确的。Smile非常具有竞争力。 - Jim Ferrans
非常好,谢谢你分享这个。数据点越多,画面就越清晰。Kryo非常快速,优化得很好,很高兴知道Smile也表现良好——这两者有些不同的目标,但有时可以同时使用。 - StaxMan
@NateS:谢谢,看起来非常有前途!我现在在做另一个项目,但已经告诉我的同事们这个好消息了。听起来他们会转换过来。 - Jim Ferrans
感谢您发布问题和答案。在RESTful服务中,如何使用kyro?是否有一个从HTTP连接发送/读取kro的示例?提前致谢。 - Jose Martinez
显示剩余4条评论

17

这里有一个错误报告和一个讨论主题。Kryo自带的DateSerializer在大小方面比SO发布的SimpleSerializer实现略微更加高效,因为它使用了优化了正值的LongSerializer。

编辑:我忘记回答原始问题了。我相信Kryo至少被用在一些生产系统中。这篇文章中提到了它,Jive SBS缓存重设计:第三部分。在Destroy All Humans项目中,Kryo被用于与作为机器人大脑的Android手机通信(视频在此处)。

虽然不是直接的答案,但您可以浏览Kryo源代码和/或javadocs。查看Kryo类的read*和write*方法,然后查看Serializer类。这实际上是该库的核心。


1
+1:已点赞。感谢Nate开发Kryo,它真的很棒! - Jim Ferrans

4

Kryo是雅虎的S4(简单可扩展流处理系统)项目的一部分。据我所知,S4目前尚未投入生产。


2

1

最新版的Kryo在某些极端情况下存在一些竞态条件,从Java运行在ns-3的模拟器接口上。如果我的更改没有问题,可能会要求开发人员将其中一些提交回去。


1
是的,我相信他们会很高兴看到你的修复。 - Jim Ferrans
3
Kryo v2 不再尝试保证线程安全。应用程序需要为每个线程使用一个 Kryo 实例。 - NateS

1

1

Apache Storm在将消息从一个任务传递到另一个任务之前使用序列化

因此,它必须非常稳定,因为Storm被多家大型公司使用,例如Twitter和Spotify。


1

1
Kryo 2.x也被Mule ESB使用,并且在生产中被广泛使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接