【发布时间】:2019-02-10 11:04:17
【问题描述】:
我正在开发一个需要存储大量简单、可扩展数据的数据系统(以及我们正在内部开发的一些专业索引,而不是这个问题的一部分)。我预计将存储数十亿条记录,因此有效的序列化是系统的关键部分。序列化需要快速、节省空间并支持多种平台和语言(因为打包和解包这些数据将是客户端组件的职责,而不是存储系统的一部分)
数据类型实际上是带有可选键/值对的散列。键将是小整数(在应用层解释)。值可以是各种简单的数据类型——字符串、整数、浮点数。
作为技术选择,我们选择了MessagePack,我正在编写代码以通过Ruby 的msgpack-ruby gem 执行数据序列化。
我不需要 Ruby 的 64 位浮点数的精度。即使在 32 位的限制下,存储的数字也没有有意义的精度。所以我想使用 MessagePack 对 32 位浮点值的支持。这绝对存在。然而,Ruby 在任何 64 位系统上的默认行为是将 Float 序列化为 64 位:
MessagePack.pack(10.3)
=> "\xCB@$\x99\x99\x99\x99\x99\x9A"
查看MessagePack代码,似乎有一个方法MessagePack::Packer#write_float32,这符合我的预期:
MessagePack::DefaultFactory.packer.write_float32(10.3).to_s
=> "\xCAA$\xCC\xCD"
。 . .但我找不到设置默认打包程序或创建新打包程序的方法,在序列化较大结构时将使用此方法。
为了测试我的理解力,我尝试了这个:
class Float
def to_msgpack_ext
packer.write_float32(self)
end
def self.from_msgpack_ext s
unpacker.read(s)
end
end
MessagePack::DefaultFactory.register_type(0, Float )
MessagePack.pack(10.3)
=> "\xCB@$\x99\x99\x99\x99\x99\x9A"
完全没有区别。 . .显然,我遗漏或误解了 MessagePack 中使用的对象模型。我想做的事是否可行,我需要做什么?
【问题讨论】: