Ale*_*lex 131 serialization bson deserialization messagepack msgpack
最近我发现了MessagePack,这是Google的Protocol Buffers和JSON的替代二进制序列化格式,它也优于两者.
还有MongoDB用于存储数据的BSON序列化格式.
有人可以详细说明BSON与MessagePack的差异和优势吗?
只是为了完成高效的 二进制序列化格式列表:还有Gobs将成为Google协议缓冲区的继承者.然而,与所有其他提到的格式相比,这些格式不是语言无关的,并且依赖于Go的内置反射,至少还有除Go之外的其他语言的Gobs库.
小智 183
//请注意我是MessagePack的作者.这个答案可能有偏见.
格式设计
与JSON的兼容性
尽管名称如此,但与MessagePack相比,BSON与JSON的兼容性并不高.
BSON有特殊类型,如"ObjectId","Min key","UUID"或"MD5"(我认为这些类型是MongoDB所必需的).这些类型与JSON不兼容.这意味着当您将对象从BSON转换为JSON时,某些类型信息可能会丢失,但当然只有当这些特殊类型位于BSON源中时才会丢失.在单一服务中同时使用JSON和BSON可能是一个缺点.
MessagePack旨在从/向JSON透明转换.
MessagePack小于BSON
MessagePack的格式比BSON简洁.因此,MessagePack可以序列化小于BSON的对象.
例如,简单映射{"a":1,"b":2}使用MessagePack以7字节序列化,而BSON使用19字节.
BSON支持就地更新
使用BSON,您可以修改存储对象的一部分,而无需重新序列化整个对象.假设地图{"a":1,"b":2}存储在文件中,并且您想要将"a"的值从1更新为2000.
使用MessagePack,1仅使用1个字节,但2000使用3个字节.因此"b"必须向后移动2个字节,而"b"不会被修改.
对于BSON,1和2000都使用5个字节.由于这种冗长,你不必移动"b".
MessagePack有RPC
MessagePack,Protocol Buffers,Thrift和Avro支持RPC.但BSON没有.
这些差异意味着MessagePack最初是为网络通信而设计的,而BSON是为存储而设计的.
实现和API设计
MessagePack具有类型检查API(Java,C++和D)
MessagePack支持静态类型.
与JSON或BSON一起使用的动态类型对于Ruby,Python或JavaScript等动态语言非常有用.但对于静态语言来说却很麻烦.您必须编写无聊的类型检查代码.
MessagePack提供了类型检查API.它将动态类型的对象转换为静态类型的对象.这是一个简单的例子(C++):
#include <msgpack.hpp>
class myclass {
private:
std::string str;
std::vector<int> vec;
public:
// This macro enables this class to be serialized/deserialized
MSGPACK_DEFINE(str, vec);
};
int main(void) {
// serialize
myclass m1 = ...;
msgpack::sbuffer buffer;
msgpack::pack(&buffer, m1);
// deserialize
msgpack::unpacked result;
msgpack::unpack(&result, buffer.data(), buffer.size());
// you get dynamically-typed object
msgpack::object obj = result.get();
// convert it to statically-typed object
myclass m2 = obj.as<myclass>();
}
Run Code Online (Sandbox Code Playgroud)
MessagePack有IDL
它与类型检查API有关,MessagePack支持IDL.(规范可从以下网址获得:http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL)
Protocol Buffers和Thrift需要IDL(不支持动态类型)并提供更成熟的IDL实现.
MessagePack有流API(Ruby,Python,Java,C++,...)
MessagePack支持流式反序列化器.此功能对网络通信很有用.这是一个例子(Ruby):
require 'msgpack'
# write objects to stdout
$stdout.write [1,2,3].to_msgpack
$stdout.write [1,2,3].to_msgpack
# read objects from stdin using streaming deserializer
unpacker = MessagePack::Unpacker.new($stdin)
# use iterator
unpacker.each {|obj|
p obj
}
Run Code Online (Sandbox Code Playgroud)
Tra*_*er1 16
我知道这个问题在这一点上有点陈旧......我认为提到它取决于你的客户端/服务器环境是什么样的,这一点非常重要.
如果您在没有检查的情况下多次传递字节,例如使用消息队列系统或将日志条目传输到磁盘,那么您可能更喜欢使用二进制编码来强调紧凑的大小.否则,这是针对不同环境的个案问题.
有些环境可以对msgpack/protobuf进行非常快速的序列化和反序列化,而其他环境则没有那么多.通常,语言/环境越低级,二进制序列化就越好.在更高级的语言(node.js,.Net,JVM)中,您经常会看到JSON序列化实际上更快.那么问题就是你的网络开销或多或少比你的内存/ cpu约束?
关于msgpack vs bson vs协议缓冲区... msgpack是该组的最小字节,协议缓冲区大致相同.BSON定义了比其他两种更广泛的本机类型,并且可能更好地匹配您的对象模式,但这使它更加冗长.协议缓冲区的优点是可以设计为流...这使得它成为二进制传输/存储格式的更自然的格式.
就个人而言,我倾向于直接提供JSON提供的透明度,除非明确需要更轻的流量.通过带有gzip压缩数据的HTTP,网络开销的差异甚至不是格式之间的问题.
小智 11
那么\xef\xbc\x8cas 作者说\xef\xbc\x8cMessagePack 最初是为网络通信设计的,而 BSON 是为存储设计的。
\n\nMessagePack 比较紧凑,而 BSON 比较冗长。\nMessagePack 旨在节省空间,而 BSON 则专为 CURD(节省时间)而设计。
\n\n最重要的是,MessagePack的类型系统(前缀)遵循Huffman编码,这里我画了MessagePack的Huffman树(点击链接看图片)\xef\xbc\x9a
\n\n\n尚未提及的一个关键区别是 BSON 包含整个文档和进一步嵌套的子文档的大小信息(以字节为单位)。
document ::= int32 e_list
Run Code Online (Sandbox Code Playgroud)
这对于尺寸和性能都很重要的受限环境(例如嵌入式)有两个主要好处。
| 归档时间: |
|
| 查看次数: |
60228 次 |
| 最近记录: |