Kryo是一个非常新颖且有趣的 Java 序列化库,并且是thrift-protobuf基准测试中速度最快的库之一。如果您使用过 Kryo,它是否已经成熟到可以在生产代码中试用?
更新(2010 年 10 月 27 日):我们正在使用 Kryo,但尚未投入生产。有关详细信息,请参阅下面的答案。
更新(2011 年 3 月 9 日):更新到最新的 Jackson 和 Kryo 库表明 Jackson 的二进制微笑序列化非常具有竞争力。
Kryo是一个非常新颖且有趣的 Java 序列化库,并且是thrift-protobuf基准测试中速度最快的库之一。如果您使用过 Kryo,它是否已经成熟到可以在生产代码中试用?
更新(2010 年 10 月 27 日):我们正在使用 Kryo,但尚未投入生产。有关详细信息,请参阅下面的答案。
更新(2011 年 3 月 9 日):更新到最新的 Jackson 和 Kryo 库表明 Jackson 的二进制微笑序列化非常具有竞争力。
我会尝试回答我自己的问题(Kyro 还是很新的!)。
我们有一组使用Restlet 框架实现的大约 120 种不同的 Web 服务。这些由通常构建在基于 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()); }
});
但这是迄今为止我发现的唯一可能的问题。我们有一组具有 String、Float、Integer、Long、Date、Boolean 和 List 字段的 JavaBean。
这里有一些粗略的基准。首先,我对描述一个电视节目的对象层次结构进行了 100,000 次序列化和反序列化(即,对其进行了 100,000 次深拷贝)。速度是:
XStream XML: 360/sec
Java Object Serialization: 1,570/sec
Jackson JSON: 5,000/sec
Kryo: 8,100/sec
接下来,我还序列化了一个包含 2000 个电视节目描述和字节数的目录:
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 的二进制“微笑”序列化程序。使用 Jackson 1.6 和 Kryo 1.04,我做了 100,000 次深拷贝(序列化/反序列化),其中有些不同的电视节目对象层次结构:
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
有一个错误报告和一个讨论线程。Kryo 附带的 DateSerializer 在大小方面比 SO 上发布的 SimpleSerializer 实现更有效,因为它使用针对正值优化的 LongSerializer。
编辑:我忘了回答原来的问题。我相信 Kryo 至少用于一些生产系统。在这篇文章中提到了它,Jive SBS 缓存重新设计:第 3 部分。在Destroy All Humans项目中,Kryo 用于与充当机器人大脑的 Android 手机进行通信(视频在这里)。
不是直接的答案,但您可以浏览Kryo 源代码和/或javadocs。查看 Kryo 类的 read* 和 write* 方法,然后查看 Serializer 类。这确实是图书馆的核心。
Kryo 是 Yahoo 的 S4(简单可扩展流系统)项目的一部分。据我所知,S4 尚未生产。
在上面Jim Ferrans的回复和评论的帮助下,我在此页面上找到了关于 Kryo 的日期序列化问题的更详细解释:http ://groups.google.com/group/kryo-users/browse_thread/thread/91969c6f48a45bdf/ 以及一个如何使用 Kryo 的 DateSerializer():
kryo.register(Date.class, new DateSerializer());
我希望这可以帮助其他人。
最新版本的 Kryo 在一些极端情况下有一些竞争条件,运行在从 Java 到 ns-3 的模拟器接口上。如果它们没有问题,可能会要求开发人员提交我的一些更改。
Kryo 网站上有关于使用 Kryo 进行生产的项目的部分
Mule ESB 也使用 Kryo 2.x,因此在生产中得到广泛应用。
2017年更新:
Flink 使用 Kryo。所以实际上任何使用 Flink 框架的东西都依赖于 Kryo。参考:https ://ci.apache.org/projects/flink/flink-docs-release-0.8/programming_guide.html#specifying-keys