Skip to content

Serialization‐Performance‐Report

funkye edited this page Oct 8, 2024 · 1 revision

Fury调研情况说明

License情况

Apache License 2.0许可协议,包含License(BSD-3-Clause licenses、MIT licenses)均为A类许可,无License集成问题

框架介绍

Fury是一个基于JIT的高性能多语言原生序列化框架,专注于提供极致的序列化性能和易用性:

  • 支持主流编程语言如Java/Python/Scala/Golang/JavaScript/Rust,其它语言可轻易扩展;
  • 多语言/跨语言自动序列化任意对象,无需创建IDL文件、手动编译schema生成代码以及将对象转换为中间格式;
  • 多语言/跨语言自动序列化共享引用和循环引用,用户只需要关心对象,不需要关心数据重复或者递归错误;
  • 基于JIT动态编译技术在运行时自动生成序列化代码优化性能,增加方法内联、代码缓存和死代码消除,减少虚方法调用/条件分支/Hash查找/元数据写入等,提供相比其它序列化框架20~200倍以上的性能;
  • Zero-Copy序列化支持,支持Out of band序列化协议,支持堆外内存读写;
  • 提供缓存友好的二进制随机访问行存格式,支持跳过序列化和部分序列化,并能和列存自动互转;

测试对比情况(JDK、Seata、Kryo、Hessian、Protobuf、Fury、FastJson2)

测试环境说明

  • OS: win10
  • JDK: 1.8.0_381
  • JMH: 1.37
  • Seata: 2.1.0-SNAPSHOT

选择的序列化工具和对应版本

  • JDK:1.8.0_381(同上)
  • Seata:2.1.0-SNAPSHOT(同上)
  • Kryo:5.4.0,kryo-serializers(0.45)
  • Hessian:4.0.63
  • Protobuf:3.16.3
  • Fury:0.6.0

以上存在白名单限制的均已开启,测试场景包括序列化的吞吐量对比(序列化和反序列化)、集成Seata后的事务吞吐量对比(TODO)

序列化吞吐量对比

主要是针对Seata内部RPC调用的数据对象进行序列化和反序列化的吞吐量测试,主要分为简单结构对象(属性基本为简单类型,对应基础RPC消息的场景)、嵌套对象(包含自定义对象属性,对应开启批量消息传输的场景)和复杂多重嵌套对象(对应UndoLog的序列化场景):

测试参数:Warmup (iterations 5,time 5s), Measurement(iterations 10,time 5s),Threads 1 and 4

  1. 简单结构对象(以BranchRegisterRequest为例子)

    • 对象结构说明

      {
          private String xid;
          //Enum Object
          private BranchType branchType = BranchType.AT;
          private String resourceId;
          private String lockKey;
          private String applicationData;
      }
  • 测试结果展示

    • 相同对象序列化后大小对比

      kryo byte length: 118
      seata byte length: 120
      fury byte length: 123
      protobuf byte length: 182
      fastjson2 byte length: 245
      hessian byte length: 295
      jdk byte length: 788
    • 序列化ms单位吞吐量情况

      • 单线程

      • 单线程(JDK17)

      • 多线程(Threads 4)

    • 反序列化ms单位吞吐量情况

      • 单线程

      • 单线程(JDK17)

      • 多线程(Threads 4)

  1. 较复杂的嵌套对象(以BatchResultMessage为例子)

    • 对象结构说明

      BatchResultMessage {
          //AbstractResultMessage为与测试1结构相似的消息
          private List<AbstractResultMessage> resultMessages = new ArrayList<>();
          private List<Integer> msgIds = new ArrayList<>();
      }
    • 测试结果展示

      • 相同对象序列化后大小对比

        kryo byte length: 47
        seata byte length: 50
        fury byte length: 53
        protobuf byte length: 290
        fastjson2 byte length: 347
        hessian byte length: 470
        jdk byte length: 1300
      • 序列化ms单位吞吐量情况

        • 单线程

        • 单线程(JDK17)

        • 多线程(Threads 4)

      • 反序列化ms单位吞吐量情况

        • 单线程

        • 单线程(JDK17)

        • 多线程(Threads 4)

  2. 复杂多重嵌套对象(BranchUndoLog)

    • 对象结构说明

      /**
       * 具体结构详见源码, 主要嵌套结构简单说明如下
       * https://raw.githubusercontent.com/apache/incubator-seata/2.x/rm-datasource/src/main/java/org/apache/seata/rm/datasource/undo/BranchUndoLog.java
      **/
      BranchUndoLog -> SQLUndoLog -> TableRecords -> List<Row> -> List<Field> -> Object
    • 测试结果展示

      • 相同对象序列化后大小对比

        protobuf byte length: 86
        fury byte length: 96
        fastJson2 byte length: 271
        kryo byte length: 281
        fastjson byte length: 356
        jackson byte length: 877
      • 序列化ms单位吞吐量情况

        • 单线程

          image-20240906211545209

        • 单线程(JDK17)

        • 多线程(Threads 4)

      • 反序列化ms单位吞吐量情况

        • 单线程

          image-20240906213615841

        • 单线程(JDK17)

        • 多线程(Threads 4)

集成事务吞吐量对比(TODO)

Clone this wiki locally