Json을 대체할 몇가지 형식..

tony·2023년 10월 30일
0
post-thumbnail

RESTful API를 개발하다 보면 주로 JSON으로 데이터를 주고 받는다. 응답속도 향상을 위해 JSON이 왜 병목이고, 대체제와 어떻게 효율적으로 향상시켰는지에 대한 case들을 확인해 보고자 한다.


이 글의 목적은 Json을 폄하하는 것이 아니라 한계를 이해하고, 응답성과 성능 최적화를 위한 더 나은 전략이 있는지 살펴보는 것이다.


P99 latency

LinkedIn Integrates Protocol Buffers With Rest.li for Improved Microservices Performance.

1.Parsing Overhead
2. Serialization and Deserialization

수많은 마이크로서비스 내에서 여러 메세지를 주고 받을 시 JSON에서 오버헤드가 발생할 수 있다.

  1. String manipulation
  2. 지원하지 않는 데이터 타입
  3. Verbosity

The first challenge is that JSON is a textual format, which tends to be verbose. This results in increased network bandwidth usage and higher latencies, which is less than ideal.
— LinkedIn

  1. 바이너리 미지원
  2. 다중 중첩
    특정 경우에는 재귀와 순회 알고리즘에 필요하고 이러한 요소들이 최적화 없이는 성능에 영향을 미칠 수 있다.

JSON은 가장 많이 사용하는 데이터 형식이지만 특정 상황에서의 성능 제한으로 대체제를 알아보려 한다.


  1. Protocol Buffers (protobuf)
  • 구글에서 개발한 바이너리 직렬화 형태이다. protobuf의 바이너리 특성으로 직렬화-역직렬화 시 JSON보다 나은 효율을 기대한다. IOT나 네트워크 대역폭이 제한적인 마이크로 서비스 환경에서 고성능의 데이터 상호 교환이 필요할 때 주로 사용된다.
  1. BSON(Binary JSON)
  • 바이너리로 인코딩된 JSON이다. JSON의 유연성과 바이너리 인코딩을 통한 성능향상이 특징이고 주로 몽고DB에서 사용된다.

이외에도 Message Pack이나 Apache Avro등이 있다.

Json, protobuf, MessagePack, BSON, Avro의 차이

JSON

    
{
  "id": 1,                                 // 14 bytes
  "name": "John Doe",                      // 20 bytes
  "email": "johndoe@example.com",          // 31 bytes
  "age": 30,                               // 9 bytes
  "isSubscribed": true,                    // 13 bytes
  "orders": [                              // 11 bytes
    {                                      // 2 bytes
      "orderId": "A123",                   // 18 bytes
      "totalAmount": 100.50                // 20 bytes
    },                                     // 1 byte
    {                                      // 2 bytes
      "orderId": "B456",                   // 18 bytes
      "totalAmount": 75.25                 // 19 bytes
    }                                      // 1 byte
  ]                                        // 1 byte
}   
    
Total JSON Size: ~139 bytes

Json 형식은 다양하게 사용되며 사용하기 쉽지만 문자 기반이라는 것이 단점이다. 모든 문자, 공백, 심지어 쌍따옴표(")도 성능효율에 관련이 있다.

효율 챌린지! - 바이너리 형식을 통한 사이즈 줄이기

proto buf

syntax = "proto3";

message User {
  int32 id = 1;
  string name = 2;
  string email = 3;
  int32 age = 4;
  bool is_subscribed = 5;
  repeated Order orders = 6;

  message Order {
    string order_id = 1;
    float total_amount = 2;
  }
}
0A 0E 4A 6F 68 6E 20 44 6F 65 0C 4A 6F 68 6E 20 44 6F 65 65 78 61 6D 70 6C 65 2E 63 6F 6D 04 21 00 00 00 05 01 12 41 31 32 33 03 42 DC CC CC 3F 05 30 31 31 32 34 34 35 36 25 02 9A 99 99 3F 0D 31 02 42 34 35 36 25 02 9A 99 99 3F

Total Protocol Buffers Size: ~38 bytes


BSON (Binary JSON)

Binary Representation (Hexadecimal):
3e0000001069640031000a4a6f686e20446f6502656d61696c006a6f686e646f65406578616d706c652e636f6d1000000022616765001f04370e4940

Total BSON Size: ~43 bytes

(참고 자료 용으로 실제 값은 다를 수 있으며 일반적인 이해를 돕기위한 수치입니다.)

protobuf, BSON등 내부 구조에 따른 인코딩 메커니즘이 다르기 때문에 같은 데이터 값이라도 조금씩 크기가 다를 수 있다.


결과적으로 4개의 형식에 대해 요약하자면...


JSON 형식 개선 예시

  1. LinkedIn’s Protocol Buffers Integration
  2. Uber’s H3 Geo-Index
  3. Slack’s Message Format Optimization
  4. Auth0’s Protocol Buffers Implementation

목적과 요구사항에 따라 JSON 이외에 다른 format에 대해 알아보았고, 개선할 수 있는 방법을 알아보았다. 추후에 성능 비교 테스트도 진행해 볼 예정이다.

profile
백엔드 서버 엔지니어

0개의 댓글