【问题标题】:Fast json Deserialization with Map as field使用 Map 作为字段的快速 json 反序列化
【发布时间】:2021-05-29 00:59:30
【问题描述】:

我想将 Json 格式的 Array[Byte] 反序列化为下面描述的 Event 类,并且我想尽快完成。 Event 类有几个 Int/String 字段,这应该不是问题。 json 格式的 Byte 数组的所有内容都必须转换为 Map。 json/Map的key是未知的,没有嵌套的jsonObjects或数组。

例如 Json: {"someKey1": "someval", "someInt": 34, "anotherKey": 56} -> toMap

这是我到目前为止所做的

import play.api.libs.json.{JsObject, Json}

...

  override def line2Event(
                           line: Array[Byte],
                           id: Int
                         ): Event = {
    val map = Json.parse(line).as[JsObject].value.toMap
    val timestamp = map.getOrElse("timestamp", id).toString.toLong
    Event(id, "GenericJson", timestamp, map)


class Event(
             val id: Int,
             val eventType: String,
             val timestamp: Long,
             extraArgs: Map[String, Any]
           )

此播放 api 实现对某些数据集的速度约为 25K 消息/秒。我想改进它。使用其他一些框架会有所帮助吗?例如jsoniter 之类的?

然而,就我而言,我没有具有特定字段的类(即,json 的所有键值对都存储到事件的 Map 字段中)。这个或另一个框架是否包含类似于我使用但速度更快的解析方法?

【问题讨论】:

  • github 中有一些存储库,用于比较 Scala 中 jaon 库的性能。例如:github.com/yanns/scala-json-parsers-performance
  • 你最好的选择就是尝试一下。 Play json 是 scala 上相对较慢的 json 实现。 jsoniter 几乎肯定会更快。 Circe 是我个人的偏好,主要是因为 API,但它通常也比播放 json 更快。
  • 您能解释一下Event 值是如何使用的吗?它们应该只是序列化为 JSON 到一些响应消息还是以某种方式不同?您是否有可能更改 Event 类定义?
  • @AndriyPlokhotnyuk 不幸的是,我无法更改 Event 类。你能给我提供一种方法,用 jsoniter 将 Array[Byte](里面有 json)反序列化为 immutable.Map[String, Any] 吗?

标签: json scala performance serialization apache-flink


【解决方案1】:

所以,我也尝试过使用杰克逊解析

  lazy val module = new MapModule{}
  lazy val mapper = JsonMapper.builder()
  .addModule(module)
  .build()
  ...
  val map: Map[String, Any] = mapper.readValue(line, classOf[Map[String, Any]])

因为我需要一个不可变的 scala 映射,所以我还注册了 DefaultScalaModule。

不幸的是,因为这个类是在 Flink 中使用的,所以它需要是可序列化的,而 DefaultScalaModule 不是(ObjectMapper 是)。其他库(如 jsoniter)也出现了类似的问题。该怎么办?我应该创建一个新任务吗?

编辑:我为映射器和 scalaModule 使用了惰性 val(仅获得了 MapModule),现在它们在需要时被初始化(即在 flink worker 中)。 See "I have a NotSerializableException." part

速度约为 80K 事件/秒,比之前的实现快了至少 3 倍。也许将字节数组直接解析到 Map 也可以与 play json 一样快,但我找不到办法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 2017-01-02
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 2013-12-05
    相关资源
    最近更新 更多