Dubbo序列化插件smartbuf與kryo、fst、hessian二、fastjson等性能對比

介紹

本文同步發佈於GitHub、我的主頁等html

smartbuf-dubbo是一個基於smartbufdubbo序列化插件。java

它內部封裝了smartbuf序列化框架的stream模式,經過自定義的SmartbufSerializationdubbo暴露了一個名爲smartbuf的序列化器。git

關於smartbuf

smartbuf是一種新穎、高效、智能、易用的跨語言序列化框架,它既擁有不亞於protobuf的高性能,也擁有與json相仿的通用性、可擴展性、可調試性等。github

它內部採用分區序列化將鬆散的對象序列化爲若干個緊湊的分區,從而大幅提升編碼效率,具體細節請參考smartbuf項目apache

使用方式

smartbuf-dubbo內部實現很是簡單,它只是簡單地按照dubbo官方文檔提供了序列化插件,包括三個class:json

  • SmartbufObjectInput
  • SmartbufObjectOutput
  • SmartbufSerialization

以及位於core/src/main/resources/META-INF.dubbo/的插件配置。數組

此插件已打包deploy至中心倉庫,因此你能夠直接經過如下maven座標引入它:服務器

<dependency>
    <groupId>com.github.smartbuf</groupId>
    <artifactId>smartbuf-dubbo</artifactId>
    <version>1.0.1</version>
</dependency>

固然也能夠直接將以上提到的classresources配置複製入本身的工程中,同時記得手動添加smartbuf依賴。網絡

以後就能夠按照官方文檔的配置,在protocol中選擇啓用序列化插件,具體效果可能相似於:架構

<dubbo:protocol serialization="smartbuf" />

此插件支持com.alibaba版本與org.apache版本的dubbo

對比其餘序列化方案

根目錄中的demo-alibabademo-apache分別針對2.6.*版本和2.7.*版本的dubbo進行序列化測試,測試對象包括smartbuffastjsonhessian2kryofst

對比測試包括三部分:tinyuserposts,分別對比測試各個序列化框架在簡單普通複雜業務中的綜合表現。

提示:對比測試側重於單線程的序列化性能、數據壓縮率,最終數據僅用於橫向對比各個序列化框架,並不能體現dubbo自己的多併發性能。

大數據集posts測試

此測試中dubbo接口返回的數據爲100個固定的PostModel實例,其具體模型以下:

public class PostModel implements Serializable {
    private int         postId;
    private int         authorId;
    private Integer     prePostId;
    private String      title;
    private String      description;
    private ContentType contentType;
    private Visibility  visibility;
    private long        createTime;

    private List<Integer>    mentions = new ArrayList<>();
    private List<TopicModel> topics   = new ArrayList<>();
}

測試中隨機建立100PostModel對象、10TopicModel對象,而後隨機爲每一個PostModel分配若干個TopicModel,最終模擬相似實際產品應用中的queryPost結果集。

這個數據集採用json編碼時,大概20KB,各個序列化框架調用10w次的綜合表現爲:

  • fastjson: 耗時約192s, 網絡輸入輸出總計約17.88GB
  • fst: 耗時約52s, 網絡輸入輸出總計約4.01GB
  • hessian2: 耗時約115s, 網絡輸入輸出總計約11.08GB
  • kryo: 耗時約135s, 網絡輸入輸出總計約4.05GB
  • smartbuf: 耗時約75s, 網絡輸入輸出總計約2.15GB

具體表現以下圖所示,橫軸表示時間,縱軸表示網絡流量:

dubbo-comparison-posts

說明:模型中存在枚舉值ContentTypeVisibility,而測試中使用的kryo並不支持枚舉,所以在測試kryo時直接忽略了枚舉,最終致使它的測試數據並不完整。

普通數據集user測試

此測試中dubbo接口返回的數據爲1個固定的UserModel實例,其具體模型以下:

public class UserModel implements Serializable {
    private int    id;
    private String token;
    private String nickname;
    private String loginIp;
    private long   loginTime;
    private long   createTime;
    private long   updateTime;

    private List<UserModel> friends = new ArrayList<>();
}

爲了照顧kryo,此測試中再也不使用enum類型。

測試中爲friends隨機建立20UserModel對象,順便測試一下各個序列化框架對循環引用的處理。這個數據集採用json編碼時,大概4KB,各個序列化框架調用30w次的綜合表現爲:

  • fastjson: 耗時約41s, 網絡輸入輸出總計約1.11GB
  • fst: 耗時約31s, 網絡輸入輸出總計約0.55GB
  • hessian2: 耗時約32s, 網絡輸入輸出總計約0.57GB
  • kryo: 耗時約39s, 網絡輸入輸出總計約0.62GB
  • smartbuf: 耗時約41s, 網絡輸入輸出總計約0.43GB

具體表現以下圖所示,橫軸表示時間,縱軸表示網絡流量:

dubbo-comparison-user

小數據集tiny測試

此測試中dubbo接口返回的數據爲一個普通的uuid字符串,沒有太大的意義。各個序列化框架調用40w次的綜合表現爲:

  • fastjson: 耗時約46s, 網絡輸入輸出總計約130MB
  • fst: 耗時約38s, 網絡輸入輸出總計約122MB
  • hessian2: 耗時約38s, 網絡輸入輸出總計約120MB
  • kryo: 耗時約38s, 網絡輸入輸出總計約120MB
  • smartbuf: 耗時約42s, 網絡輸入輸出總計約120MB

具體表現以下圖所示,橫軸表示時間,縱軸表示網絡流量:

dubbo-comparison-tiny

測試說明

以上測試所有爲本地網絡,使用的dubbo版本號爲2.6.7

你能夠直接checkout源代碼在本地執行測試代碼。測試中用於採集網絡IO數據的NetMonitor類內部使用了nettop指令,據我瞭解它應該只支持osx操做系統,若是你在其餘系統中執行測試,可能沒法得到正確的bytes_inbytes_out

總結

因爲smartbuf在架構設計上採用了數據可複用的分區序列化,所以面對大數據集、數組、列表等結構時,能夠經過屬性複用的技術優點,顯著地提升其編碼效率。相比於kryofsthession2等時,甚至能夠提升一倍空間利用率,相比於json更是提升一個數量級

因爲smartbuf底層設計上以相似於json的方式解析數據,所以它的兼容性與json相仿,自然地解決了不一樣對象模型之間的字段兼容。且支持大多數經常使用的數據類型,也包括枚舉、泛型等等。相比之下其餘序列化框架僅支持java語言,且存在或多或少的兼容性問題,以及支持數據類型過少的問題。好比測試中發現kryo不支持enumAbstractList$SubList

在序列化性能上smartbuf相比於fst存在一些劣勢,多是分區序列化中內存複製所致,也多是代碼中某些地方存在性能問題。不過這種劣勢每每只是納秒級的,相比於數據報文在服務器、機房、區域的網絡傳輸而言,都是微不足道的。

相關文章
相關標籤/搜索