1. 程式人生 > >記一次後臺儲存方案優化

記一次後臺儲存方案優化

序列化方案

  1. Json
  2. protobuf
  3. JDK Serializable

測試方法

 String line = "{很複雜的json,需要保密}";
        DataStructure d = json.fromJson(line, DataStructure.class);
        long time = System.currentTimeMillis();
        long size = 0;
        for(int i = 0;i< 1000000; i++){
            d.setCostTime(i);
            String b = json.toJson
(d); size = size + b.getBytes().length; } System.out.println("time :" + (System.currentTimeMillis() - time) +",and size:" + size);

測試結果

  • 序列化:
方式 耗時(毫秒) 結構化儲存資料大小(byte)
json 8954 777888890
protobuf2 5255 517983488
protobuf3 3247 357983488
jdk 7281 1067000000

* 反序列化:

方式 耗時(毫秒)
json 5107
protobuf2 4082
protobuf3 3123
jdk 22779

插曲

測試過程種出現過一次異常:

序列化:

方式 耗時(毫秒) 結構化儲存資料大小(byte)
protobuf2 28653 517983488
protobuf3 25878 357983488

反序列化:

方式 耗時(毫秒)
protobuf3 22779

經查,由於在Java Object 轉 pb Object 過程中,使用了反射

Class<? extends DataStructure> clazz = DataStructure.class;
        Field[] fields = clazz.getDeclaredFields();
        for(Field field : fields){
            String name = field.getName();
            String up = captureName(name);
            if(field.getAnnotation(SerializableTag.class) != null)
            //填入資料
        }

這段程式碼導致速度下降了6~8倍

總結

  1. protobuf 效能全面優於 Json,速度加快大概在30%~40% 左右,儲存資料量下降30%+
  2. 由於專案中的 Java Object 帶Map屬性在使用支援Map的 protobuf 3.0 時,效能還能有大幅提升 (目前spark 只支援2.5 Map 使用jdk序列化,再以byte方式序列化到pb)
  3. 線上環境全面使用 set,get 方法替代反射注入,提升效能(不要怕麻煩)。