티스토리 뷰
반응형
1. Protocol Buffer란?
- 데이터를 직렬화하기 위한, Google의 언어 / 플랫폼 중립적인 기술
- Data가 어떻게 구조화되어야하는지 한 번만 정의하면, 자동 생성된 소스 코드를 통해 다양한 데이터 스트림과 언어에서 구조화된 데이터를 쉽게 쓰고 읽을 수 있다. (= 사용할 수 있다.)
2. Encoding
i). 다음과 같이 데이터 구조를 정의했다고 가정하자.
- Test1이라고 이름 붙인 구조는 정수형 변수 a를 사용한다.
- 이를 Java에서 모델로 표현했다면, 다음과 같은 형태가 된다.
public class Test1 {
private int a;
}
- 해당 Java 모델을 통해 JSON 문서를 주고 받는다면, 다음과 같은 형식일 것이다.
{
a: [int]
}
- 즉, 실제로 주고 받는 정보의 형식은 JSON이며, 이러한 JSON 형식의 문서를 활용하기 위한 데이터 구조로 'Test1'이라는 모델을 정의한 셈이 된다.
ii). ProtoBuf에서는?
- i).의 설명에 따르면, 프로그래밍 언어별로 모델을 정의하고 사용하여야만 한다.
- Protocol Buffer를 활용할 경우, 언어 / 플랫폼 중립적인 모델의 정의가 가능해진다.
- 예시는 다음과 같다.
message Test1 {
optional int32 a = 1;
}
- 이 때, a는 int32 형 데이터이며, 직렬화에 활용하기 위한 필드 번호는 1번이다.
- a의 값을 1로 초기화한다는 의미가 아님!
iii). 예시
- JSON 모델의 a 변수에 정수 150을 넣어 전송한다고 가정하자.
{
"a": 150
}
- 이는 인코딩된 경우, 9byte로 계산된다(특수 문자 {"":} 5 + 영문 1 + 숫자 3)
- 확인 필요
- 이를 ProcolBuffer의 Test1 메시지를 통해 직렬화할 경우, 다음의 인코딩 결과를 얻게 된다.
- 08 96 01 : 0000 1000 / 1001 0110 / 0000 0001
- 결과 3byte로 계산되며, Protocol Buffer를 활용해 직렬화된 데이터의 크기가 작아지게 된다!
iv). 인코딩 순서
- 첫 byte는 다음과 같이 산출한다.
- (필드 번호) 5자리 + (wire type) 세자리
- 00001 000 = 0000 1000 = 08
- 150을 이진수로 변환한다 : 128 + 16 + 4 + 2 = 1001 0110
- msb를 버린 것을 가정하고 정리 : 000 0001 001 0110
- 뒤부터 7자리를 세면 쉽다
- 순서 변경 : 001 0110 000 0001
- least significant group이 먼저 오도록 변경
- msb 수정 : 1001 0110 0000 0001 (96 01)
- msb는 뒷 byte가 있는 경우 1, 없는 경우 0
- 1.의 결과에 2.의 결과를 붙인다 : 08 96 01
- 300의 경우 :
- 첫 byte : 08
- 300을 이진수화 : 1 0010 1100
- msb를 버린 것을 가정하고 정리 : 000 0010 010 1100
- 뒤부터 7자리를 세면 이해하기 쉽다
- least significant group이 먼저 오도록 수정 : 010 1100 000 0010
- 뒷 byte가 있음을 알리기 위해 byte별 msb 수정 : 1010 1100 0000 0010
v). 디코딩 순서
- 08 96 01을 디코딩하면,
- 08
- 0000 1000
- msb 제거 : 000 1000
- 순서 변경 : 1000 000(wire type = 0)
- 1000 > rigth shift 3 : 0001 > tag 1인 값은 varInt형이며
- 96 01
- 1001 0110 0000 0001
- 001 0110 / 000 0001
- 000 0001 / 001 0110
- 뒤에서부터 여덟자리 : 1001 0110 > 값은 150이다.
- 08 AC 02를 디코딩하면,
- 0000 1000
- 000 1000 : wire type 0
- 1000 >> 3 : 필드 번호 1
- AC 02 : 1010 1100 0000 0010
- msb 제거 : 010 1100 000 0010
- 순서 변경 : 000 0010 / 010 1100
- 붙여 읽기 : 1 0010 1100 > 256 + 32 + 8 + 4 = 300
번외 :
message Person {
// 생략
int64 num = 2;
}
- num 1337이면?
인코딩
- 1337 > 539 > 0101 0011 1001 (2진수 변환)
- 000 1010 / 011 1001 (뒤에서부터 7자리)
- 1011 1001 / 0000 1010 (순서 바꾼 후 MSB 추가)
- > 10 B9 0A
10 B9 0A 디코딩
- 0001 0000 > 00010 000 > wiretype / 필드 번호 2
- B9 0A > 1011 1001 0000 1010
- 011 1001 / 000 1010
- 000 1010 / 011 1001
- 101 0011 1001 > 1337
'Dev.' 카테고리의 다른 글
[Redis] docker redis 간단 사용 및 mac redis 설치 (1) | 2021.05.26 |
---|---|
[Spring Boot] LOG_PATH_IS_UNDEFINED 폴더가 생성되는 문제 (0) | 2021.05.24 |
[Ansible] regexp 및 $(달러) 기호 이스케이프 (0) | 2021.01.05 |
[Eureka] Eureka Basic (0) | 2020.12.14 |
[ThymeLeaf] th:if와 th:each 함께 사용하기 (0) | 2020.11.19 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 코딩테스트
- Spring Cloud Config
- postgresql
- Git
- eureka
- spring boot
- Linux
- kotlin
- IntelliJ
- AWS IoT
- javascript
- shell
- AWS
- Vault
- Puppeteer
- react
- Database
- mysql
- RancherDesktop
- Docker
- JEST
- hashicorp
- jQuery
- pgloader
- terraform
- Java
- etc
- JPA
- Gradle
- Node.js
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
글 보관함