使用 BooPickle 和 RocksDb 将额外字节添加到序列化
Extra bytes being added to serialization with BooPickle and RocksDb
所以我在将 Scala classes 写入 RocksDB 之前使用 BooPickle 对其进行序列化。序列化一个 class,
case class Key(a: Long, b: Int) {
def toStringEncoding: String = s"${a}-${b}"
}
我有这个隐含的class
implicit class KeySerializer(key: Key) {
def serialize: Array[Byte] =
Pickle.intoBytes(key.toStringEncoding).array
}
方法 toStringEncoding
是必要的,因为 BooPickle 没有以一种能够很好地满足 RocksDb 对键排序的要求的方式序列化 case class。然后我将一堆键值对写入几个 SST 文件并将它们摄取到 RocksDb 中。然而,当我从数据库中查找密钥时,却找不到它们。
如果我遍历数据库中的所有键,我发现键已成功写入,但是额外的字节被写入数据库中的字节表示。例如,如果 key.serialize
输出这样的内容
Array[Byte] = Array( 25, 49, 54, 48, 53, 55, 52, 52, 48, 48, 48, 45, 48, 45, 49, 54, 48, 53, 55, 52, 52, 48, 51, 48, 45, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...)
我会在数据库中找到类似这样的东西
Array[Byte] = Array( 25, 49, 54, 48, 53, 55, 52, 52, 48, 48, 48, 45, 48, 45, 49, 54, 48, 53, 55, 52, 52, 48, 51, 48, 45, 48, 51, 101, 52, 97, 49, 100, 102, 48, 50, 53, 5, 8, ...)
额外的非零字节替换字节数组末尾的零字节。此外字节数组的大小也不同。当我调用 serialize
方法时,字节数组的大小为 512,但当我从数据库中检索密钥时,大小为 4112。有人知道是什么原因造成的吗?
我没有使用 RocksDb 或 BooPickle 的经验,但我猜问题出在调用 ByteBuffer.array
上。
它 returns 支持字节缓冲区的整个数组而不是相关部分。
你可以看看这里 Gets byte array from a ByteBuffer in java
如何从 ByteBuffer 中正确提取数据。
BooPickle docs 建议使用以下方法将 BooPickled 数据作为字节数组获取:
val data: Array[Byte] = Array.ofDim[Byte](buf.remaining)
buf.get(data)
所以在你的情况下它会是这样的
def serialize: Array[Byte] = {
val buf = Pickle.intoBytes(key.toStringEncoding)
val arr = Array.ofDim[Byte](buf.remaining)
buf.get(arr)
arr
}
所以我在将 Scala classes 写入 RocksDB 之前使用 BooPickle 对其进行序列化。序列化一个 class,
case class Key(a: Long, b: Int) {
def toStringEncoding: String = s"${a}-${b}"
}
我有这个隐含的class
implicit class KeySerializer(key: Key) {
def serialize: Array[Byte] =
Pickle.intoBytes(key.toStringEncoding).array
}
方法 toStringEncoding
是必要的,因为 BooPickle 没有以一种能够很好地满足 RocksDb 对键排序的要求的方式序列化 case class。然后我将一堆键值对写入几个 SST 文件并将它们摄取到 RocksDb 中。然而,当我从数据库中查找密钥时,却找不到它们。
如果我遍历数据库中的所有键,我发现键已成功写入,但是额外的字节被写入数据库中的字节表示。例如,如果 key.serialize
输出这样的内容
Array[Byte] = Array( 25, 49, 54, 48, 53, 55, 52, 52, 48, 48, 48, 45, 48, 45, 49, 54, 48, 53, 55, 52, 52, 48, 51, 48, 45, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...)
我会在数据库中找到类似这样的东西
Array[Byte] = Array( 25, 49, 54, 48, 53, 55, 52, 52, 48, 48, 48, 45, 48, 45, 49, 54, 48, 53, 55, 52, 52, 48, 51, 48, 45, 48, 51, 101, 52, 97, 49, 100, 102, 48, 50, 53, 5, 8, ...)
额外的非零字节替换字节数组末尾的零字节。此外字节数组的大小也不同。当我调用 serialize
方法时,字节数组的大小为 512,但当我从数据库中检索密钥时,大小为 4112。有人知道是什么原因造成的吗?
我没有使用 RocksDb 或 BooPickle 的经验,但我猜问题出在调用 ByteBuffer.array
上。
它 returns 支持字节缓冲区的整个数组而不是相关部分。
你可以看看这里 Gets byte array from a ByteBuffer in java 如何从 ByteBuffer 中正确提取数据。
BooPickle docs 建议使用以下方法将 BooPickled 数据作为字节数组获取:
val data: Array[Byte] = Array.ofDim[Byte](buf.remaining)
buf.get(data)
所以在你的情况下它会是这样的
def serialize: Array[Byte] = {
val buf = Pickle.intoBytes(key.toStringEncoding)
val arr = Array.ofDim[Byte](buf.remaining)
buf.get(arr)
arr
}