【问题标题】:Extra bytes being added to serialization with BooPickle and RocksDb使用 BooPickle 和 RocksDb 将额外字节添加到序列化中
【发布时间】:2021-03-28 15:33:23
【问题描述】:

所以我使用 BooPickle 在将 Scala 类写入 RocksDB 之前对其进行序列化。要序列化一个类,

case class Key(a: Long, b: Int) {

def toStringEncoding: String = s"${a}-${b}"
}

我有这个隐式类

  implicit class KeySerializer(key: Key) {
    def serialize: Array[Byte] = 
      Pickle.intoBytes(key.toStringEncoding).array
  }

toStringEncoding 方法是必要的,因为 BooPickle 没有以一种能够很好地满足 RocksDb 对密钥排序的要求的方式序列化案例类。然后我将一堆键值对写入几个 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。有人知道可能是什么原因造成的吗?

【问题讨论】:

  • 您知道 boopickle 的文档明确表示它不适合存储用例吗?

标签: scala rocksdb upickle


【解决方案1】:

我没有使用 RocksDb 或 BooPickle 的经验,但我想问题出在调用 ByteBuffer.array 上。 它返回支持字节缓冲区的整个数组,而不是相关部分。

你可以看看例如这里Gets byte array from a ByteBuffer in java 如何正确地从 ByteBuffer 中提取数据。

【讨论】:

    【解决方案2】:

    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多