MMO 서버에서 캐릭터 이동 패킷 하나의 크기를 34B에서 8B까지 줄였을 때 트래픽, 비용, 서버 대수, 패킷 수가 어떻게 달라지는지 계산한 영상이다. 이동 정보는 보는 사람 수, 갱신 빈도, 동접만큼 곱해져서 나가기 때문에 1바이트 차이도 월 단위로는 테라바이트가 된다. 모든 수치는 동접 5,000, 보는 사람 50명, 이동 갱신 10Hz, 이동이 송신의 60%(24B 기준)라는 예시 가정에서 나온 값이다.
같은 이동 정보(캐릭터 ID, x/y/z 좌표, 방향, 상태, 시각)를 네 가지 방식으로 인코딩해 바이트 칸으로 나란히 보여준다. 프로토버퍼 기본은 34B, 커스텀 기본은 24B, 커스텀 비트 패킹은 19B, 이동 전용 극단 양자화는 8B다.
프로토버퍼 행의 빨간 칸은 필드 태그와 길이다. 프로토버퍼는 필드마다 "몇 번 필드인지"를 적는 태그 바이트가 붙고, 메시지를 감싸는 래퍼에도 2바이트가 든다. 커스텀 형식은 필드 순서를 양쪽이 미리 알고 있으니 이 칸이 없다. 비트 패킹은 방향, 상태, 시각 차이(Δt)처럼 범위가 작은 값을 1~2바이트로 줄인 것이다.
8B 행은 64비트를 슬롯 12b, x 14b, y 14b, z 8b, 방향 6b, 상태 4b, Δt 6b로 나눈다. 캐릭터 ID 대신 AOI 슬롯 번호를 쓰고, 좌표는 셀 기준 상대 좌표로 양자화하고, 방향은 64단계로 줄였다. 영상은 이것을 "이동만 극단적으로 다듬은 예"라고 표시한다. 34B와 8B의 차이는 76%다.
1바이트를 줄였을 때 서버 송신량이 얼마나 변하는지 곱셈을 한 줄씩 쌓아 보여준다.
1 바이트 × 50 (한 명의 이동을 보는 사람 수) = 50B
- × 10 (초당 이동 갱신 10Hz) = 500B/s
- × 5,000 (동시접속) = 2.5MB/s, 즉
20 Mbps
- × 86,400 (하루의 초) = 216GB/일
- × 30 (한 달) = 6.5TB/월
한 사람의 이동은 그 사람을 볼 수 있는 50명에게 각각 따로 나가므로 바이트 하나가 50번 복제된다. 여기에 갱신 빈도와 동접이 곱해진다. 동접 5,000이 24시간 30일 내내 유지된다고 가정한 값이다. 서버 대수는 피크 동접으로 잡지만, 실제 월 송신량과 비용은 평균 동접으로 계산하므로 이보다 작다.
왼쪽은 플레이어 한 명 기준의 이동 트래픽이다. 24B 패킷을 10Hz로 보내면 내가 보내는 양은 240 B/s이고, 주변에 보이는 50명의 이동을 받는 양은 12.0 KB/s다. 서버 입장에서는 1을 받고 50을 내보낸다. 그래서 서버 트래픽은 수신보다 송신이 훨씬 크고, 송신 대부분이 브로드캐스트가 된다.
오른쪽은 서버 송신 구성 예시다. 이동 브로드캐스트 60%, 전투·이펙트 25%, 채팅·기타 15%로 둔다. 24B 이동 패킷에서 1바이트는 이동 몫의 1/24이므로 전체 송신의 약 2.5%가 된다.
브로드캐스트는 보는 사람 수만큼 복제되므로 줄인 바이트도 같은 배수로 줄어든다. 하나만 보면 작지만, 여러 바이트를 줄이면 그만큼 쌓인다.
네 가지 크기별로 서버 전체 월 송신량과 송신 비용을 막대로 비교한다. 이동 외 송신(전투, 채팅 등)은 고정으로 두고 계산했다.
34B: 324TB, $16.2k~29.2k/월
24B: 259TB, $13.0k~23.3k/월
19B: 227TB, $11.3k~20.4k/월
8B: 156TB, $7.8k~14.0k/월
비용은 송신 단가 $0.05~0.09/GB 예시로 계산했다. 34B에서 8B로 가면 송신 트래픽은 월 −168TB(−52%), 송신 비용은 월 −$8.4k~15.2k다. 플레이어 한 명이 받는 이동 데이터는 17.0 KB/s에서 4.0 KB/s로, 모바일 이동 데이터 사용량은 시간당 61.2MB에서 14.4MB로 준다.
서버 대수가 대역폭으로 정해진다고 가정하고 34B에서 25대가 필요하다고 두면, 24B는 20대, 19B는 18대(17.5대 올림), 8B는 12대가 된다. 34B에서 8B로 가면 13대가 줄고, 대당 월 $700 예시로 월 $9.1k다.
같은 장비로 더 받을 수 있는 인원도 보여준다. 일반 필드는 트래픽이 동접에 비례하므로 송신 총량 비율 그대로 늘어난다(24B ×1.25, 19B ×1.43, 8B ×2.08). 보스존은 모두가 모두를 보기 때문에 트래픽이 인원의 제곱(N²)에 비례한다. 그래서 수용 인원은 바이트 비율의 제곱근만큼 늘어난다(24B ×1.19, 19B ×1.34, 8B ×2.06). 바이트가 약 1/4이 되면 수용 인원은 약 2배다.
25대는 대역폭 병목을 가정한 예시 값이다. 앞의 송신량(월 324TB, 평균 약 1Gbps)을 25대로 나누면 대당 약 40Mbps라서, 이 규모에서는 실제로 대역폭이 병목이 되지 않는다. 이 계산은 대역폭이 병목일 때만 맞다. 서버가 CPU에서 먼저 막히면 패킷 크기를 줄여도 대수 효과는 작다고 영상에서 따로 표시한다.
패킷 하나의 페이로드를 최대 1,460B(예시)로 두고, 캐릭터 이동 정보가 몇 명분 들어가는지 보여준다. 34B는 42명, 24B는 60명, 19B는 76명, 8B는 182명이다.
혼잡 지역에서 60명이 보이는 경우를 예로 들어, 34B는 패킷 2개(60 × 34 = 2,040B), 24B · 19B · 8B는 1개로 충분하다(24B면 1,440B). 패킷 수가 줄면 패킷마다 붙는 헤더, 초당 패킷 수(pps), 커널의 패킷 처리 비용도 같이 준다. 바이트 총량과 별개로 패킷 개수 자체가 서버 부하가 된다.
프로토버퍼와 커스텀을 같은 수준끼리 비교한다. 기본끼리는 커스텀 24B 대 프로토 34B로 서버 송신이 +25%, 튜닝끼리는 커스텀 19B 대 프로토 26B로 +20%다. 이 퍼센트는 이동 외 송신까지 포함한 전체 송신 기준이다. 엔트리마다 하위 메시지로 담으면 필드 태그와 길이 접두가 튜닝해도 남는다. packed repeated 필드로 열 단위로 담으면 태그·길이가 배열마다 한 번만 붙는다.
대안으로 이동만 프로토버퍼의 bytes 필드 하나에 담는 방식을 보여준다. 태그·길이 3B 뒤에 8B × 50명 = 400B를 넣으면 캐릭터당 약 8.06B로 커스텀과 같은 크기가 된다.
- 나머지 메시지는 프로토버퍼를 그대로 쓴다. 스키마 진화, 클라·서버·봇 코드 생성, 디버깅 편의를 유지할 수 있다.
- 바이트는 트래픽 대부분을 차지하는 이동·전투 브로드캐스트 같은 뜨거운 경로에서만 깎는다.
- 비용을 정하는 것은 형식 이름보다 실제로 보내는 바이트 수다.
용어 정리
- 프로토버퍼 (Protocol Buffers)
- 스키마 파일로 메시지를 정의하고 여러 언어용 직렬화 코드를 생성해 주는 형식이다. 필드마다 번호 태그를 붙여 보내므로 필드 추가·삭제에 강하지만 그만큼 바이트가 붙는다.
- 필드 태그 · 길이 접두
- 프로토버퍼가 각 필드 앞에 붙이는 "필드 번호와 타입" 바이트, 그리고 중첩 메시지나 bytes 앞에 붙는 길이 값이다. 영상의 빨간 칸이 이것이다.
- 커스텀 직렬화
- 클라와 서버가 필드 순서와 크기를 미리 약속하고 값만 이어 붙이는 방식이다. 태그가 없어 작지만 형식이 바뀌면 양쪽을 같이 고쳐야 한다.
- 비트 패킹
- 값의 범위에 맞게 바이트나 비트 단위로 필드 크기를 줄여 빈틈없이 채우는 것이다. 상태 값처럼 몇 가지뿐인 값에 4바이트를 쓰지 않는 식이다.
- 양자화
- 연속된 실수 값을 정해진 단계 수로 반올림해 정수로 저장하는 것이다. 방향을 64단계(6비트)로, 좌표를 셀 기준 14비트로 줄이는 것이 그 예이며 정밀도를 일부 포기한다.
- AOI (Area of Interest)
- 한 플레이어가 볼 수 있는 주변 범위다. 서버는 AOI 안의 대상에게만 이동을 보내며, 8B 예시는 캐릭터 ID 대신 AOI 안의 슬롯 번호를 쓴다.
- 브로드캐스트
- 한 캐릭터의 상태 변화를 그 캐릭터를 보는 모든 클라에게 각각 보내는 것이다. 보는 사람이 50명이면 같은 내용이 50번 나가므로 서버 송신의 대부분을 차지한다.
- 동접 (CCU)
- 같은 시점에 접속해 있는 유저 수다. 영상의 예시는 5,000명이다.
- 갱신 빈도 (Hz)
- 1초에 몇 번 상태를 보내는지다. 이동 10Hz는 100ms마다 한 번 위치를 보낸다는 뜻이다.
- Δt
- 기준 시각과의 시간 차이다. 절대 시각 대신 작은 차이 값만 보내 바이트를 줄인다.
- 대역폭 병목
- 서버 대수가 CPU나 메모리보다 네트워크 송신량 한도에서 먼저 정해지는 상황이다. 이때만 바이트 절감이 서버 대수 절감으로 바로 이어진다.
- N² 트래픽 (보스존)
- N명이 한곳에 모여 서로를 모두 보면 각자 N명에게 받고 N명에게 보내져 전체 트래픽이 N²에 비례한다. 그래서 바이트를 줄인 효과가 수용 인원에는 제곱근으로 나타난다.
- MSS
- 패킷 하나에 실을 수 있는 최대 페이로드 크기다. 일반적인 이더넷 환경의 TCP에서 1,460B가 흔한 값이며, 영상은 이를 예시로 쓴다.
- pps (packets per second)
- 초당 처리하는 패킷 수다. 같은 바이트라도 패킷 수가 많으면 헤더와 커널·NIC 처리 비용이 늘어난다.
- 스키마 진화
- 이미 배포된 클라와 서버가 섞여 있어도 메시지에 필드를 추가하거나 빼면서 호환을 유지하는 것이다. 프로토버퍼를 쓰는 주된 이유다.