๊ณ ์ฑ๋ฅ ์ด์ง ์ง๋ ฌํ๋ฅผ ์ํ Python Protocol Buffers์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์ดํด๋ณด๊ณ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋ฐ์ดํฐ ๊ตํ์ ์ต์ ํํ์ธ์.
Python Protocol Buffers: ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ํจ์จ์ ์ธ ์ด์ง ์ง๋ ฌํ ๊ตฌํ
์ค๋๋ ์ํธ ์ฐ๊ฒฐ๋ ๋์งํธ ํ๊ฒฝ์์ ๋ฐ์ดํฐ์ ํจ์จ์ ์ธ ๊ตํ์ ๋ชจ๋ ์ ํ๋ฆฌ์ผ์ด์ , ํนํ ๊ธ๋ก๋ฒ ๊ท๋ชจ๋ก ์ด์๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๊ณต์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๊ฐ๋ฐ์๊ฐ ํ์ฅ ๊ฐ๋ฅํ๊ณ ์ฑ๋ฅ์ด ๋ฐ์ด๋๋ฉฐ ์ํธ ์ด์ฉ ๊ฐ๋ฅํ ์์คํ ์ ๊ตฌ์ถํ๊ธฐ ์ํด ๋ ธ๋ ฅํจ์ ๋ฐ๋ผ ๋ฐ์ดํฐ ์ง๋ ฌํ ํ์์ ์ ํ์ ์ค์ํ ๊ฒฐ์ ์ด ๋ฉ๋๋ค. ์ฃผ์ ๊ฒฝ์์ ์ค Google์ Protocol Buffers(Protobuf)๋ ํจ์จ์ฑ, ์ ์ฐ์ฑ ๋ฐ ๊ฒฌ๊ณ ์ฑ์ผ๋ก ๋๋๋ฌ์ง๋๋ค. ์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ Python ์ํ๊ณ ๋ด์์ Protocol Buffers์ ๊ตฌํ์ ์์ธํ ์ดํด๋ณด๊ณ ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํ ์ด์ ๊ณผ ์ค์ ์ ์ฉ ์ฌ๋ก๋ฅผ ์กฐ๋ช ํฉ๋๋ค.
๋ฐ์ดํฐ ์ง๋ ฌํ ๋ฐ ์ค์์ฑ ์ดํด
Python์์ Protobuf์ ๊ตฌ์ฒด์ ์ธ ๋ด์ฉ์ ์ดํด๋ณด๊ธฐ ์ ์ ๋ฐ์ดํฐ ์ง๋ ฌํ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ํ์ ํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค. ์ง๋ ฌํ๋ ๊ฐ์ฒด์ ์ํ ๋๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ฅ(์: ํ์ผ ๋๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค)ํ๊ฑฐ๋ ์ ์ก(์: ๋คํธ์ํฌ๋ฅผ ํตํด)ํ ๋ค์ ๋์ค์ ์ฌ๊ตฌ์ฑํ ์ ์๋ ํ์์ผ๋ก ๋ณํํ๋ ํ๋ก์ธ์ค์ ๋๋ค. ์ด ํ๋ก์ธ์ค๋ ๋ค์์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ๋ฐ์ดํฐ ์์์ฑ: ๋์ค์ ๊ฒ์ํ๊ธฐ ์ํด ์ ํ๋ฆฌ์ผ์ด์ ๋๋ ๊ฐ์ฒด์ ์ํ๋ฅผ ์ ์ฅํฉ๋๋ค.
- ํ๋ก์ธ์ค ๊ฐ ํต์ (IPC): ๋์ผํ ๋จธ์ ์์ ์๋ก ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์๋๋ก ํฉ๋๋ค.
- ๋คํธ์ํฌ ํต์ : ์๋ก ๋ค๋ฅธ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํฉ๋๋ค. ์ ์ฌ์ ์ผ๋ก ๋ค์ํ ์ง๋ฆฌ์ ์์น์์ ์๋ก ๋ค๋ฅธ ์ด์ ์ฒด์ ๋๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ ์คํ๋ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ์บ์ฑ: ๋ ๋น ๋ฅธ ๊ฒ์์ ์ํด ์์ฃผ ์ก์ธ์คํ๋ ๋ฐ์ดํฐ๋ฅผ ์ง๋ ฌํ๋ ํ์์ผ๋ก ์ ์ฅํฉ๋๋ค.
์ง๋ ฌํ ํ์์ ํจ๊ณผ๋ ์ข ์ข ๋ช ๊ฐ์ง ์ฃผ์ ์งํ, ์ฆ ์ฑ๋ฅ(์ง๋ ฌํ/์ญ์ง๋ ฌํ ์๋), ์ง๋ ฌํ๋ ๋ฐ์ดํฐ ํฌ๊ธฐ, ์ฌ์ฉ ์ฉ์ด์ฑ, ์คํค๋ง ์งํ ๊ธฐ๋ฅ ๋ฐ ์ธ์ด/ํ๋ซํผ ์ง์์ผ๋ก ํ๋จ๋ฉ๋๋ค.
Protocol Buffers๋ฅผ ์ ํํด์ผ ํ๋ ์ด์
Protocol Buffers๋ JSON ๋ฐ XML๊ณผ ๊ฐ์ ๋ณด๋ค ์ ํต์ ์ธ ์ง๋ ฌํ ํ์์ ๋ํ ๋งค๋ ฅ์ ์ธ ๋์์ ์ ๊ณตํฉ๋๋ค. JSON ๋ฐ XML์ ์ฌ๋์ด ์ฝ์ ์ ์๊ณ ์น API์ ๋๋ฆฌ ์ฑํ๋์์ง๋ง ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ธํธ ๋๋ ๋์ ์ฒ๋ฆฌ๋ ์๋๋ฆฌ์ค์์๋ ์ฅํฉํ๊ณ ์ฑ๋ฅ์ด ๋จ์ด์ง ์ ์์ต๋๋ค. ๋ฐ๋ฉด์ Protobuf๋ ๋ค์ ์์ญ์์ ๋ฐ์ด๋ฉ๋๋ค.
- ํจ์จ์ฑ: Protobuf๋ ๋ฐ์ดํฐ๋ฅผ ์ปดํฉํธํ ์ด์ง ํ์์ผ๋ก ์ง๋ ฌํํ์ฌ ํ ์คํธ ๊ธฐ๋ฐ ํ์์ ๋นํด ๋ฉ์์ง ํฌ๊ธฐ๊ฐ ํจ์ฌ ์์์ง๋๋ค. ์ด๋ฅผ ํตํด ๋์ญํญ ์๋น๊ฐ ์ค์ด๋ค๊ณ ์ ์ก ์๊ฐ์ด ๋นจ๋ผ์ง๋ฏ๋ก ๋๊ธฐ ์๊ฐ ๊ณ ๋ ค ์ฌํญ์ด ์๋ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ์ฑ๋ฅ: Protobuf์ ์ด์ง ํน์ฑ ๋๋ถ์ ๋งค์ฐ ๋น ๋ฅธ ์ง๋ ฌํ ๋ฐ ์ญ์ง๋ ฌํ ํ๋ก์ธ์ค๊ฐ ๊ฐ๋ฅํฉ๋๋ค. ์ด๊ฒ์ ๋ง์ดํฌ๋ก์๋น์ค ๋ฐ ์ค์๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๊ฐ์ ๊ณ ์ฑ๋ฅ ์์คํ ์์ ํนํ ์ ์ฉํฉ๋๋ค.
- ์ธ์ด ๋ฐ ํ๋ซํผ ์ค๋ฆฝ์ฑ: Protobuf๋ ์ธ์ด์ ๊ตฌ์ ๋ฐ์ง ์๋๋ก ์ค๊ณ๋์์ต๋๋ค. Google์ ๋ค์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋ํ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋๊ตฌ๋ฅผ ์ ๊ณตํ์ฌ ์๋ก ๋ค๋ฅธ ์ธ์ด(์: Python, Java, C++, Go)๋ก ์์ฑ๋ ์์คํ ๊ฐ์ ์ํํ ๋ฐ์ดํฐ ๊ตํ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ์ด๊ฒ์ ์ด๊ธฐ์ข ๊ธ๋ก๋ฒ ์์คํ ๊ตฌ์ถ์ ์ด์์ ๋๋ค.
- ์คํค๋ง ์งํ: Protobuf๋ ์คํค๋ง ๊ธฐ๋ฐ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํฉ๋๋ค. `.proto` ํ์ผ์์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ํฉ๋๋ค. ์ด ์คํค๋ง๋ ๊ณ์ฝ ์ญํ ์ ํ๋ฉฐ Protobuf์ ๋์์ธ์ ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ ๋ฐ ์ดํ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ํ์ฉํฉ๋๋ค. ๊ธฐ์กด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๋จํ์ง ์๊ณ ๊ธฐ์กด ํ๋๋ฅผ ํ๊ธฐ๋ ๊ฒ์ผ๋ก ํ์ํ๊ฑฐ๋ ์ ํ๋๋ฅผ ์ถ๊ฐํ์ฌ ๋ถ์ฐ ์์คํ ์์ ์ํํ ์ ๋ฐ์ดํธ๋ฅผ ์ฉ์ดํ๊ฒ ํ ์ ์์ต๋๋ค.
- ๊ฐ๋ ฅํ ํ์ดํ ๋ฐ ๊ตฌ์กฐ: ์คํค๋ง ๊ธฐ๋ฐ ํน์ฑ์ ๋ฐ์ดํฐ์ ๋ํ ๋ช ํํ ๊ตฌ์กฐ๋ฅผ ์ ์ฉํ์ฌ ๋ชจํธ์ฑ์ ์ค์ด๊ณ ๋ฐ์ดํฐ ํ์ ๋ถ์ผ์น์ ๊ด๋ จ๋ ๋ฐํ์ ์ค๋ฅ ๊ฐ๋ฅ์ฑ์ ์ค์ ๋๋ค.
Protocol Buffers์ ํต์ฌ ๊ตฌ์ฑ ์์
Protocol Buffers๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋ช ๊ฐ์ง ์ฃผ์ ๊ตฌ์ฑ ์์๋ฅผ ์ดํดํด์ผ ํฉ๋๋ค.
1. `.proto` ํ์ผ(์คํค๋ง ์ ์)
์ฌ๊ธฐ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ํฉ๋๋ค. `.proto` ํ์ผ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ํด๋์ค ๋๋ ๊ตฌ์กฐ์ฒด์ ์ ์ฌํ ๋ฉ์์ง๋ฅผ ์ค๋ช ํ๊ธฐ ์ํด ๊ฐ๋จํ๊ณ ๋ช ํํ ๊ตฌ๋ฌธ์ ์ฌ์ฉํฉ๋๋ค. ๊ฐ ๋ฉ์์ง์๋ ๊ณ ์ ํ ์ด๋ฆ, ์ ํ ๋ฐ ๊ณ ์ ํ ์ ์ ํ๊ทธ๊ฐ ์๋ ํ๋๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ํ๊ทธ๋ ์ด์ง ์ธ์ฝ๋ฉ ๋ฐ ์คํค๋ง ์งํ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์ `.proto` ํ์ผ(addressbook.proto):
syntax = "proto3";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
syntax = "proto3";: Protobuf ๊ตฌ๋ฌธ ๋ฒ์ ์ ์ง์ ํฉ๋๋ค. `proto3`๋ ํ์ฌ ํ์ค์ด๋ฉฐ ๊ถ์ฅ๋๋ ๋ฒ์ ์ ๋๋ค.message Person {...}: `Person`์ด๋ผ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ํฉ๋๋ค.string name = 1;: ํ๊ทธ `1`์ ๊ฐ์ง `string` ์ ํ์ `name`์ด๋ผ๋ ํ๋์ ๋๋ค.int32 id = 2;: ํ๊ทธ `2`์ ๊ฐ์ง `int32` ์ ํ์ `id`์ด๋ผ๋ ํ๋์ ๋๋ค.repeated PhoneNumber phones = 4;: 0๊ฐ ์ด์์ `PhoneNumber` ๋ฉ์์ง๋ฅผ ํฌํจํ ์ ์๋ ํ๋์ ๋๋ค. ์ด๊ฒ์ ๋ชฉ๋ก ๋๋ ๋ฐฐ์ด์ ๋๋ค.enum PhoneType {...}: ์ ํ ์ ํ์ ๋ํ ์ด๊ฑฐํ์ ์ ์ํฉ๋๋ค.message PhoneNumber {...}: ์ ํ ๋ฒํธ์ ๋ํ ์ค์ฒฉ๋ ๋ฉ์์ง๋ฅผ ์ ์ํฉ๋๋ค.
2. Protocol Buffer ์ปดํ์ผ๋ฌ(`protoc`)
`protoc` ์ปดํ์ผ๋ฌ๋ `.proto` ํ์ผ์ ๊ฐ์ ธ์ ์ ํํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋ํ ์์ค ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ช ๋ น์ค ๋๊ตฌ์ ๋๋ค. ์ด ์์ฑ๋ ์ฝ๋๋ ์ ์๋ ๋ฉ์์ง๋ฅผ ์์ฑ, ์ง๋ ฌํ ๋ฐ ์ญ์ง๋ ฌํํ๊ธฐ ์ํ ํด๋์ค ๋ฐ ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
3. ์์ฑ๋ Python ์ฝ๋
Python์ฉ `.proto` ํ์ผ์ ์ปดํ์ผํ๋ฉด `protoc`๋ ๋ฉ์์ง ์ ์๋ฅผ ๋ฏธ๋ฌ๋งํ๋ Python ํด๋์ค๊ฐ ํฌํจ๋ `.py` ํ์ผ์ ์์ฑํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ Python ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ด๋ฌํ ํด๋์ค๋ฅผ ๊ฐ์ ธ์ ์ฌ์ฉํฉ๋๋ค.
Python์์ Protocol Buffers ๊ตฌํ
Python ํ๋ก์ ํธ์์ Protobuf๋ฅผ ์ฌ์ฉํ๋ ์ค์ ๋จ๊ณ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1๋จ๊ณ: ์ค์น
Python์ฉ Protocol Buffers ๋ฐํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ปดํ์ผ๋ฌ ์์ฒด๋ฅผ ์ค์นํด์ผ ํฉ๋๋ค.
Python ๋ฐํ์ ์ค์น:
pip install protobuf
`protoc` ์ปดํ์ผ๋ฌ ์ค์น:
`protoc` ์ค์น ๋ฐฉ๋ฒ์ ์ด์ ์ฒด์ ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๊ณต์ Protocol Buffers GitHub ๋ฆด๋ฆฌ์ค ํ์ด์ง(https://github.com/protocolbuffers/protobuf/releases)์์ ๋ฏธ๋ฆฌ ์ปดํ์ผ๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ค์ด๋ก๋ํ๊ฑฐ๋ ํจํค์ง ๊ด๋ฆฌ์๋ฅผ ํตํด ์ค์นํ ์ ์์ต๋๋ค.
- Debian/Ubuntu:
sudo apt-get install protobuf-compiler - macOS(Homebrew):
brew install protobuf - Windows: GitHub ๋ฆด๋ฆฌ์ค ํ์ด์ง์์ ์คํ ํ์ผ์ ๋ค์ด๋ก๋ํ์ฌ ์์คํ ์ PATH์ ์ถ๊ฐํฉ๋๋ค.
2๋จ๊ณ: `.proto` ํ์ผ ์ ์
์์์ ์ค๋ช
ํ ๋๋ก `.proto` ํ์ผ(์: addressbook.proto)์ ๋ง๋ค์ด ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ํฉ๋๋ค.
3๋จ๊ณ: Python ์ฝ๋ ์์ฑ
`protoc` ์ปดํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ `.proto` ํ์ผ์์ Python ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค. ํฐ๋ฏธ๋์์ `.proto` ํ์ผ์ด ํฌํจ๋ ๋๋ ํ ๋ฆฌ๋ก ์ด๋ํ์ฌ ๋ค์ ๋ช ๋ น์ ์คํํฉ๋๋ค.
protoc --python_out=. addressbook.proto
์ด ๋ช
๋ น์ ํ์ฌ ๋๋ ํ ๋ฆฌ์ addressbook_pb2.py๋ผ๋ ํ์ผ์ ๋ง๋ญ๋๋ค. ์ด ํ์ผ์๋ ์์ฑ๋ Python ํด๋์ค๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
4๋จ๊ณ: Python ์ฝ๋์์ ์์ฑ๋ ํด๋์ค ์ฌ์ฉ
์ด์ Python ์คํฌ๋ฆฝํธ์์ ์์ฑ๋ ํด๋์ค๋ฅผ ๊ฐ์ ธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์์ Python ์ฝ๋(main.py):
import addressbook_pb2
def create_person(name, id, email):
person = addressbook_pb2.Person()
person.name = name
person.id = id
person.email = email
return person
def add_phone(person, number, phone_type):
phone_number = person.phones.add()
phone_number.number = number
phone_number.type = phone_type
return person
def serialize_address_book(people):
address_book = addressbook_pb2.AddressBook()
for person in people:
address_book.people.append(person)
# Serialize to a binary string
serialized_data = address_book.SerializeToString()
print(f"Serialized data (bytes): {serialized_data}")
print(f"Size of serialized data: {len(serialized_data)} bytes")
return serialized_data
def deserialize_address_book(serialized_data):
address_book = addressbook_pb2.AddressBook()
address_book.ParseFromString(serialized_data)
print("\nDeserialized Address Book:")
for person in address_book.people:
print(f" Name: {person.name}")
print(f" ID: {person.id}")
print(f" Email: {person.email}")
for phone_number in person.phones:
print(f" Phone: {phone_number.number} ({person.PhoneType.Name(phone_number.type)})")
if __name__ == "__main__":
# Create some Person objects
person1 = create_person("Alice Smith", 101, "alice.smith@example.com")
add_phone(person1, "+1-555-1234", person1.PhoneType.MOBILE)
add_phone(person1, "+1-555-5678", person1.PhoneType.WORK)
person2 = create_person("Bob Johnson", 102, "bob.johnson@example.com")
add_phone(person2, "+1-555-9012", person2.PhoneType.HOME)
# Serialize and deserialize the AddressBook
serialized_data = serialize_address_book([person1, person2])
deserialize_address_book(serialized_data)
# Demonstrate schema evolution (adding a new optional field)
# If we had a new field like 'is_active = 5;' in Person
# Old code would still read it as unknown, new code would read it.
# For demonstration, let's imagine a new field 'age' was added.
# If age was added to .proto file, and we run protoc again:
# The old serialized_data could still be parsed,
# but the 'age' field would be missing.
# If we add 'age' to the Python object and re-serialize,
# then older parsers would ignore 'age'.
print("\nSchema evolution demonstration.\nIf a new optional field 'age' was added to Person in .proto, existing data would still parse.")
print("Newer code parsing older data would not see 'age'.")
print("Older code parsing newer data would ignore the 'age' field.")
python main.py๋ฅผ ์คํํ๋ฉด ๋ฐ์ดํฐ์ ์ด์ง ํํ๊ณผ ์ญ์ง๋ ฌํ๋ ์ฌ๋์ด ์ฝ์ ์ ์๋ ํ์์ด ํ์๋ฉ๋๋ค. ๋ํ ์ถ๋ ฅ์ ์ง๋ ฌํ๋ ๋ฐ์ดํฐ์ ์ปดํฉํธํ ํฌ๊ธฐ๋ฅผ ๊ฐ์กฐ ํ์ํฉ๋๋ค.
์ฃผ์ ๊ฐ๋ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
`.proto` ํ์ผ์ ์ฌ์ฉํ ๋ฐ์ดํฐ ๋ชจ๋ธ๋ง
`.proto` ํ์ผ์ ํจ๊ณผ์ ์ผ๋ก ์ค๊ณํ๋ ๊ฒ์ ์ ์ง ๊ด๋ฆฌ ๋ฐ ํ์ฅ์ฑ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋ค์ ์ฌํญ์ ๊ณ ๋ คํ์ญ์์ค.
- ๋ฉ์์ง ์ธ๋ถ์ฑ: ๋ ผ๋ฆฌ์ ๋ฐ์ดํฐ ๋จ์๋ฅผ ๋ํ๋ด๋ ๋ฉ์์ง๋ฅผ ์ ์ํฉ๋๋ค. ์ง๋์น๊ฒ ํฌ๊ฑฐ๋ ์ง๋์น๊ฒ ์์ ๋ฉ์์ง๋ ํผํ์ญ์์ค.
- ํ๋ ํ๊น : ๊ฐ๋ฅํ๋ฉด ํ๊ทธ์ ์์ฐจ์ ์ซ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ฐ๊ฒฉ์ด ํ์ฉ๋๊ณ ์คํค๋ง ์งํ๋ฅผ ์ง์ํ ์ ์์ง๋ง ๊ด๋ จ ํ๋์ ๋ํด ์์ฐจ์ ์ผ๋ก ์ ์งํ๋ฉด ๊ฐ๋ ์ฑ์ด ํฅ์๋ฉ๋๋ค.
- ์ด๊ฑฐํ: ๊ณ ์ ๋ ๋ฌธ์์ด ์์ ์งํฉ์ ์ด๊ฑฐํ์ ์ฌ์ฉํฉ๋๋ค. ํธํ์ฑ์ ์ ์งํ๊ธฐ ์ํด `0`์ด ์ด๊ฑฐํ์ ๊ธฐ๋ณธ๊ฐ์ธ์ง ํ์ธํ์ญ์์ค.
- ์ ์๋ ค์ง ์ ํ: Protobuf๋ ํ์์คํฌํ, ๊ธฐ๊ฐ ๋ฐ `Any`(์์ ๋ฉ์์ง์ฉ)์ ๊ฐ์ ์ผ๋ฐ์ ์ธ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋ํ ์ ์๋ ค์ง ์ ํ์ ์ ๊ณตํฉ๋๋ค. ์ ์ ํ ๊ฒฝ์ฐ ์ด๋ฌํ ์ ํ์ ํ์ฉํ์ญ์์ค.
- ๋งต: ํค-๊ฐ ์์ ๊ฒฝ์ฐ `proto3`์์ `map` ์ ํ์ ์ฌ์ฉํ์ฌ `repeated` ํค-๊ฐ ๋ฉ์์ง์ ๋นํด ๋ ๋์ ์๋ฏธ ์ฒด๊ณ์ ํจ์จ์ฑ์ ์ ๊ณตํฉ๋๋ค.
์คํค๋ง ์งํ ์ ๋ต
Protobuf์ ๊ฐ์ ์ ์คํค๋ง ์งํ ๊ธฐ๋ฅ์ ์์ต๋๋ค. ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ํํ ์ ํ์ ๋ณด์ฅํ๋ ค๋ฉด:
- ํ๋ ๋ฒํธ๋ฅผ ๋ค์ ํ ๋นํ์ง ๋ง์ญ์์ค.
- ์ค๋๋ ํ๋ ๋ฒํธ๋ฅผ ์ญ์ ํ์ง ๋ง์ญ์์ค. ๋์ ํ๊ธฐ๋ ๊ฒ์ผ๋ก ํ์ํ์ญ์์ค.
- ํ๋๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค. ๋ชจ๋ ํ๋๋ฅผ ๋ฉ์์ง์ ์ ๋ฒ์ ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
- ํ๋๋ ์ ํ ์ฌํญ์ผ ์ ์์ต๋๋ค. `proto3`์์ ๋ชจ๋ ์ค์นผ๋ผ ํ๋๋ ์์์ ์ผ๋ก ์ ํ ์ฌํญ์ ๋๋ค.
- ๋ฌธ์์ด ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
- `proto2`์ ๊ฒฝ์ฐ `optional` ๋ฐ `required` ํค์๋๋ฅผ ์ฃผ์ํด์ ์ฌ์ฉํ์ญ์์ค. `required` ํ๋๋ ์คํค๋ง ์งํ๋ฅผ ์ค๋จํ ์ ์์ผ๋ฏ๋ก ์ ๋์ ์ผ๋ก ํ์ํ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํด์ผ ํฉ๋๋ค. `proto3`๋ `required` ํค์๋๋ฅผ ์ ๊ฑฐํ์ฌ ๋ณด๋ค ์ ์ฐํ ์งํ๋ฅผ ์ด์งํฉ๋๋ค.
๋๊ท๋ชจ ๋ฐ์ดํฐ ์ธํธ ๋ฐ ์คํธ๋ฆผ ์ฒ๋ฆฌ
๋งค์ฐ ๋ง์ ์์ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ ์๋๋ฆฌ์ค์ ๊ฒฝ์ฐ Protobuf์ ์คํธ๋ฆฌ๋ฐ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ง์ ๋ฉ์์ง ์ํ์ค๋ก ์์ ํ ๋ ๋จ์ผ ๋๊ท๋ชจ ์ง๋ ฌํ ๊ตฌ์กฐ๊ฐ ์๋ ๊ฐ๋ณ ์ง๋ ฌํ๋ ๋ฉ์์ง ์คํธ๋ฆผ์ผ๋ก ์ ์กํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ๋คํธ์ํฌ ํต์ ์์ ์ผ๋ฐ์ ์ ๋๋ค.
gRPC์ ํตํฉ
Protocol Buffers๋ ๊ณ ์ฑ๋ฅ ์คํ ์์ค ๋ฒ์ฉ RPC ํ๋ ์์ํฌ์ธ gRPC์ ๊ธฐ๋ณธ ์ง๋ ฌํ ํ์์ ๋๋ค. ํจ์จ์ ์ธ ์๋น์ค ๊ฐ ํต์ ์ด ํ์ํ ๋ง์ดํฌ๋ก์๋น์ค ๋๋ ๋ถ์ฐ ์์คํ ์ ๊ตฌ์ถํ๋ ๊ฒฝ์ฐ Protobuf์ gRPC๋ฅผ ๊ฒฐํฉํ๋ ๊ฒ์ด ๊ฐ๋ ฅํ ์ํคํ ์ฒ ์ ํ์ ๋๋ค. gRPC๋ Protobuf์ ์คํค๋ง ์ ์๋ฅผ ํ์ฉํ์ฌ ์๋น์ค ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๊ณ ํด๋ผ์ด์ธํธ ๋ฐ ์๋ฒ ์คํ ์ ์์ฑํ์ฌ RPC ๊ตฌํ์ ๋จ์ํํฉ๋๋ค.
gRPC ๋ฐ Protobuf์ ๊ธ๋ก๋ฒ ๊ด๋ จ์ฑ:
- ๋ฎ์ ๋๊ธฐ ์๊ฐ: gRPC์ HTTP/2 ์ ์ก ๋ฐ Protobuf์ ํจ์จ์ ์ธ ์ด์ง ํ์์ ๋๊ธฐ ์๊ฐ์ ์ต์ํํ์ฌ ์๋ก ๋ค๋ฅธ ๋๋ฅ์ ์ฌ์ฉ์๊ฐ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ์ํธ ์ด์ฉ์ฑ: ์ธ๊ธํ๋ฏ์ด gRPC ๋ฐ Protobuf๋ ์๋ก ๋ค๋ฅธ ์ธ์ด๋ก ์์ฑ๋ ์๋น์ค ๊ฐ์ ์ํํ ํต์ ์ ๊ฐ๋ฅํ๊ฒ ํ์ฌ ๊ธ๋ก๋ฒ ํ ํ์ ๋ฐ ๋ค์ํ ๊ธฐ์ ์คํ์ ์ด์งํฉ๋๋ค.
- ํ์ฅ์ฑ: ์ด ์กฐํฉ์ ๊ธ๋ก๋ฒ ์ฌ์ฉ์ ๊ธฐ๋ฐ์ ์ฒ๋ฆฌํ ์ ์๋ ํ์ฅ ๊ฐ๋ฅํ ๋ถ์ฐ ์์คํ ์ ๊ตฌ์ถํ๋ ๋ฐ ์ ํฉํฉ๋๋ค.
์ฑ๋ฅ ๊ณ ๋ ค ์ฌํญ ๋ฐ ๋ฒค์น๋งํน
Protobuf๋ ์ผ๋ฐ์ ์ผ๋ก ์ฑ๋ฅ์ด ๋งค์ฐ ๋ฐ์ด๋์ง๋ง ์ค์ ์ฑ๋ฅ์ ๋ฐ์ดํฐ ๋ณต์ก์ฑ, ๋คํธ์ํฌ ์กฐ๊ฑด ๋ฐ ํ๋์จ์ด๋ฅผ ํฌํจํ ๋ค์ํ ์์ธ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. ํน์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ฒค์น๋งํนํ๋ ๊ฒ์ด ํญ์ ์ข์ต๋๋ค.
JSON๊ณผ ๋น๊ตํ ๋:
- ์ง๋ ฌํ/์ญ์ง๋ ฌํ ์๋: Protobuf๋ ์ด์ง ํน์ฑ๊ณผ ํจ์จ์ ์ธ ๊ตฌ๋ฌธ ๋ถ์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์ธํด ์ผ๋ฐ์ ์ผ๋ก JSON ๊ตฌ๋ฌธ ๋ถ์ ๋ฐ ์ง๋ ฌํ๋ณด๋ค 2-3๋ฐฐ ๋น ๋ฆ ๋๋ค.
- ๋ฉ์์ง ํฌ๊ธฐ: Protobuf ๋ฉ์์ง๋ ์ข ์ข ํด๋น JSON ๋ฉ์์ง๋ณด๋ค 3-10๋ฐฐ ์์ต๋๋ค. ์ด๋ ๋ฎ์ ๋์ญํญ ๋น์ฉ๊ณผ ๋ ๋น ๋ฅธ ๋ฐ์ดํฐ ์ ์ก์ผ๋ก ์ด์ด์ง๋ฉฐ ๋คํธ์ํฌ ์ฑ๋ฅ์ด ๋ค๋ฅผ ์ ์๋ ๊ธ๋ก๋ฒ ์ด์์ ํนํ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
๋ฒค์น๋งํน ๋จ๊ณ:
- `.proto` ๋ฐ JSON ํ์์ผ๋ก ๋ํ์ ์ธ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ํฉ๋๋ค.
- Protobuf์ ๋ํ ์ฝ๋๋ฅผ ์์ฑํ๊ณ Python JSON ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: `json`)๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ๋ฐ์ดํฐ์ ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ธํธ๋ฅผ ๋ง๋ญ๋๋ค.
- Protobuf์ JSON์ ๋ชจ๋ ์ฌ์ฉํ์ฌ ์ด ๋ฐ์ดํฐ ์ธํธ๋ฅผ ์ง๋ ฌํ ๋ฐ ์ญ์ง๋ ฌํํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ธก์ ํฉ๋๋ค.
- ๋ ํ์ ๋ชจ๋์ ๋ํด ์ง๋ ฌํ๋ ์ถ๋ ฅ์ ํฌ๊ธฐ๋ฅผ ์ธก์ ํฉ๋๋ค.
์ผ๋ฐ์ ์ธ ํจ์ ๋ฐ ๋ฌธ์ ํด๊ฒฐ
Protobuf๋ ๊ฐ๋ ฅํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ๋ฌธ์ ๊ฐ ์์ผ๋ฉฐ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์๋ชป๋ `protoc` ์ค์น: `protoc`๊ฐ ์์คํ ์ PATH์ ์๋์ง ํ์ธํ๊ณ ์ค์น๋ Python `protobuf` ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํธํ๋๋ ๋ฒ์ ์ ์ฌ์ฉํ๊ณ ์๋์ง ํ์ธํฉ๋๋ค.
- ์ฝ๋ ์ฌ์์ฑ ๊น๋ฐ์: `.proto` ํ์ผ์ ์์ ํ๋ฉด ์ ๋ฐ์ดํธ๋ Python ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด `protoc`๋ฅผ ๋ค์ ์คํํด์ผ ํฉ๋๋ค.
- ์คํค๋ง ๋ถ์ผ์น: ์ง๋ ฌํ๋ ๋ฉ์์ง๊ฐ ๋ค๋ฅธ ์คํค๋ง(์: ์ด์ ๋๋ ์ต์ ๋ฒ์ ์ `.proto` ํ์ผ)๋ก ๊ตฌ๋ฌธ ๋ถ์๋๋ฉด ์ค๋ฅ ๋๋ ์๊ธฐ์น ์์ ๋ฐ์ดํฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ฐ์ ์์ ์์ ์๊ฐ ํญ์ ํธํ๋๋ ์คํค๋ง ๋ฒ์ ์ ์ฌ์ฉํ๋์ง ํ์ธํ์ญ์์ค.
- ํ๊ทธ ์ฌ์ฌ์ฉ: ๋์ผํ ๋ฉ์์ง์์ ๋ค๋ฅธ ํ๋์ ํ๋ ํ๊ทธ๋ฅผ ์ฌ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ ์์ ๋๋ ์คํด๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
- `proto3` ๊ธฐ๋ณธ๊ฐ ์ดํด: `proto3`์์ ์ค์นผ๋ผ ํ๋๋ ๋ช ์์ ์ผ๋ก ์ค์ ๋์ง ์์ ๊ฒฝ์ฐ ๊ธฐ๋ณธ๊ฐ(์ซ์๋ 0, ๋ถ์ธ์ false, ๋ฌธ์์ด์ ๋น ๋ฌธ์์ด ๋ฑ)์ ๊ฐ์ต๋๋ค. ์ด๋ฌํ ๊ธฐ๋ณธ๊ฐ์ ๊ณต๊ฐ์ ์ ์ฝํ์ง๋ง ์ค์ ๋์ง ์์ ํ๋์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ช ์์ ์ผ๋ก ์ค์ ๋ ํ๋๋ฅผ ๊ตฌ๋ณํด์ผ ํ๋ ๊ฒฝ์ฐ ์ญ์ง๋ ฌํ ์ค์ ์ ์คํ๊ฒ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉ ์ฌ๋ก
Python Protocol Buffers๋ ๊ด๋ฒ์ํ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด์์ ์ ๋๋ค.
- ๋ง์ดํฌ๋ก์๋น์ค ํต์ : ์๋ก ๋ค๋ฅธ ๋ฐ์ดํฐ ์ผํฐ ๋๋ ํด๋ผ์ฐ๋ ๊ณต๊ธ์์ ๋ฐฐํฌ๋ ์๋น์ค ๊ฐ์ ๊ฐ๋ ฅํ๊ณ ๊ณ ์ฑ๋ฅ API๋ฅผ ๊ตฌ์ถํฉ๋๋ค.
- ๋ฐ์ดํฐ ๋๊ธฐํ: ํด๋ผ์ด์ธํธ ์์น์ ๊ด๊ณ์์ด ๋ชจ๋ฐ์ผ ํด๋ผ์ด์ธํธ, ์น ์๋ฒ ๋ฐ ๋ฐฑ์๋ ์์คํ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๋๊ธฐํํฉ๋๋ค.
- IoT ๋ฐ์ดํฐ ์์ง: ์ต์ํ์ ์ค๋ฒํค๋๋ก ์ ์ธ๊ณ ์ฅ์น์ ๋๋ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- ์ค์๊ฐ ๋ถ์: ๋๊ธฐ ์๊ฐ์ด ์งง์ ๋ถ์ ํ๋ซํผ์ ๋ํ ์ด๋ฒคํธ ์คํธ๋ฆผ์ ์ ์กํฉ๋๋ค.
- ๊ตฌ์ฑ ๊ด๋ฆฌ: ์ง๋ฆฌ์ ์ผ๋ก ๋ถ์ฐ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ธ์คํด์ค์ ๊ตฌ์ฑ ๋ฐ์ดํฐ๋ฅผ ๋ฐฐํฌํฉ๋๋ค.
- ๊ฒ์ ๊ฐ๋ฐ: ๊ธ๋ก๋ฒ ํ๋ ์ด์ด ๊ธฐ๋ฐ์ ๋ํ ๊ฒ์ ์ํ ๋ฐ ๋คํธ์ํฌ ๋๊ธฐํ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
๊ฒฐ๋ก
Python Protocol Buffers๋ ๋ฐ์ดํฐ ์ง๋ ฌํ ๋ฐ ์ญ์ง๋ ฌํ๋ฅผ ์ํ ๊ฐ๋ ฅํ๊ณ ํจ์จ์ ์ด๋ฉฐ ์ ์ฐํ ์๋ฃจ์ ์ ์ ๊ณตํ์ฌ ์ต์ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ํ ์ ํ์ ๋๋ค. ์ปดํฉํธํ ์ด์ง ํ์, ๋ฐ์ด๋ ์ฑ๋ฅ ๋ฐ ๊ฐ๋ ฅํ ์คํค๋ง ์งํ ๊ธฐ๋ฅ์ ํ์ฉํ์ฌ ๊ฐ๋ฐ์๋ ๋ณด๋ค ํ์ฅ ๊ฐ๋ฅํ๊ณ ์ํธ ์ด์ฉ ๊ฐ๋ฅํ๋ฉฐ ๋น์ฉ ํจ์จ์ ์ธ ์์คํ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ๋ง์ดํฌ๋ก์๋น์ค๋ฅผ ๊ฐ๋ฐํ๋ , ๋๊ท๋ชจ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ๋ , ํฌ๋ก์ค ํ๋ซํผ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ , Python ํ๋ก์ ํธ์ Protocol Buffers๋ฅผ ํตํฉํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ๊ณผ ์ ์ธ๊ณ ๊ท๋ชจ์ ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅ์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. `.proto` ๊ตฌ๋ฌธ, `protoc` ์ปดํ์ผ๋ฌ ๋ฐ ์คํค๋ง ์งํ์ ๋ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํดํ๋ฉด ์ด ๊ท์คํ ๊ธฐ์ ์ ๋ชจ๋ ์ ์ฌ๋ ฅ์ ํ์ฉํ ์ ์์ต๋๋ค.