Post

(TIL) 2025-01-07

(TIL) 2025-01-07

프로토파일(ProtoFile) 로드


프로토파일(ProtoFile)은 Protocol Buffers(약칭 protobuf)라는 데이터 직렬화 형식을 정의하는 파일이다. 프로토파일은 데이터 구조를 정의하는 역할을 하며, 컴퓨터 간에 데이터를 효율적으로 교환하기 위한 형식이다. 이 파일은 보통 .proto 확장자를 가지고 있고, 내부에 데이터를 어떻게 표현할지에 대한 규격이 정의되어 있다. 이 파일을 로드한다는 것은 프로토파일에 정의된 규격을 바탕으로 데이터를 읽고, 사용할 준비를 하는 과정을 의미한다.

Protocol Buffers

Protocol Buffers(protobuf)는 Google에서 만든 고속, 효율적인 데이터 직렬화 형식이다. JSON, XML처럼 데이터를 표현하는 형식이지만, 더 빠르고 용량이 작고 효율적인 장점이 있다. protobuf는 데이터가 어떻게 표현될지에 대해 프로토파일(.proto)이라는 파일에서 규격을 정의하고, 이를 바탕으로 여러 프로그래밍 언어에서 데이터를 자동으로 변환할 수 있게 해준다.

프로토파일(.proto) 내용

프로토파일은 기본적으로 데이터 구조(스키마)와 타입을 정의한다. 예를 들어, 사용자 정보를 나타내는 데이터를 정의한다고 할 때, 프로토파일은 그 안에 어떤 데이터가 들어갈지, 어떤 타입으로 저장할지를 정의한다.

1
2
3
4
5
6
7
8
9
10
11
12
syntax = "proto3";

package common;

// 공통 패킷 구조
message Packet {
    uint32 handlerId = 1;      // 핸들러 ID (4바이트)
    string userId = 2;         // 유저 ID (UUID, 16바이트)
    string clientVersion = 3;  // 클라이언트 버전 (문자열)
    uint32 sequence = 4;       // 유저의 호출 수 (42억)
    bytes payload = 5;         // 실제 데이터
}

위의 예시에서 User라는 메시지(message)가 정의되어 있고, 이 메시지는 3개의 필드(handlerId, userId, clientVersion, sequence, payload)를 가지고 있습니다. 각 필드는 타입과 번호를 가집니다.

string handlerId = 1; : handlerId 필드는 32비트 정수이고, 필드 번호는 1 이다. int32 userId = 2; : userId 필드는 문자열이고, 필드 번호는 2 이다. string clientVersion = 3; : clientVersion 필드는 문자열이고, 필드 번호는 3 이다. string sequence = 4; : sequence 필드는 32비트 정수이고, 필드 번호는 4 이다. string payload = 5; : payload 필드는 bytes 이고, 필드 번호는 5 이다.

프로토파일 로드와 사용

프로토파일을 로드한다고 할 때는, 이 프로토파일에 정의된 내용을 컴퓨터 프로그램에서 사용할 수 있는 형태로 변환하는 과정이다. 이를 위해서는 컴파일이 필요하다.

  • Python: .py 파일 생성
  • Java: .java 파일 생성
  • JavaScript: .js 파일 생성

프로토파일 컴파일 과정

  1. .proto 파일 작성: 먼저 위와 같이 .proto 파일을 작성한다.
  2. 프로토콜 컴파일러 사용:

    • protoc라는 도구를 사용해 .proto 파일을 컴파일한다.
    • 이 과정에서 .proto 파일을 각 프로그래밍 언어에 맞는 코드로 변환한다.
  3. 로드 예시(JavaScript)
const fs = require("fs");
const protobuf = require("protobufjs");

// 프로토파일 로드
protobuf.load("person.proto").then((root) => {
  // "Person" 메시지 가져오기
  const Person = root.lookupType("Person");

  // 데이터를 정의
  const message = { id: 1, name: "Alice", email: "alice@example.com" };

  // 데이터 직렬화
  const buffer = Person.encode(Person.create(message)).finish();
  console.log("Serialized Data:", buffer);

  // 데이터 역직렬화
  const decoded = Person.decode(buffer);
  console.log("Deserialized Data:", decoded);
});

프로토파일 로드란, protobuf로 정의된 데이터 형식을 프로그램 내에서 사용할 수 있게 만드는 일련의 과정이다. 이 과정은 대개 아래와 같다

  1. 프로토파일 작성: 먼저 .proto 파일을 작성하여 메시지 구조를 정의합니다.
  2. 컴파일러 실행: protoc을 통해 .proto 파일을 사용하려는 언어(예: Python, Java, C++)에 맞게 컴파일합니다.
  3. 프로토파일 로드: 컴파일된 파일을 프로그램에 불러와 데이터를 다루는 데 사용합니다.

주의사항

  • 버전 호환성: 프로토파일을 수정할 때, 기존 데이터를 잘못 처리하지 않도록 필드 번호를 변경하지 않도록 주의해야 한다.
    • .proto 파일이 변경되면 클라이언트와 서버 모두 변경된 버전에 맞게 업데이트 필요
    • 오래된 버전의 클라이언트와 새 버전의 서버 간 통신 시 문제가 발생할 수 있음. 이를 방지하기 위해 필드 추가 시 기존 필드 번호를 유지하는 방식으로 관리.
  • 데이터 크기: protobuf는 작은 크기로 효율적으로 데이터를 직렬화할 수 있지만, 필드를 잘못 정의하면 오히려 비효율적일 수 있다.
  • 타입과 필드 번호: 각 필드는 고유한 번호를 가지고 있고, 이 번호는 변경하지 말아야한다. 번호가 바뀌면 이전 버전과 호환되지 않을 수 있다.

정리

  • 프로토파일은 protobuf 데이터 형식을 정의하는 .proto 파일이다.
  • 프로토파일 로드는 .proto 파일을 컴파일하여 코드로 변환하고, 이를 사용해 데이터를 직렬화/역직렬화하는 과정을 말하며 이를 통해 데이터를 효율적으로 저장하거나 네트워크 통신에서 사용할 수 있다.
This post is licensed under CC BY 4.0 by the author.