KeepWorlds

팰월드 서버 메모리 누수: 갈수록 무거워지는 원인과 예약 재시작

팰월드 전용 서버는 엔진에 알려진 메모리 누수로 며칠 만에 튕기고, 메모리를 늘려도 낫지 않아요. 유일한 답은 예약 재시작. 메모리 용량별 주기, 누수를 빠르게 하는 설정, 세이브를 잃지 않는 자동 재시작 스크립트를 정리했어요.

팰월드 전용 서버는 대개 같은 길을 걸어요. 첫날은 쾌적하고, 일주일쯤 지나면 가끔 끊기고, 둘째 주에는 새벽에 전원이 튕기고, 그다음부터는 튕기는 간격이 점점 짧아지다가 어느 아침 세이브가 안 열려요. 설정을 잘못 잡은 게 아니에요. 이 게임의 서버에는 알려져 있지만 아직 고쳐지지 않은 메모리 누수가 있어서, 프로세스의 메모리는 오르기만 하고, 오래 켜 둘수록 물리 한계에 다가가다가 결국 OS가 죽여 버려요.

이 글은 누수가 어떻게 생기는지, 어떤 설정이 그걸 앞당기는지, 메모리를 늘려도 왜 낫지 않는지, 그리고 유일하게 실제로 듣는 방법인 예약 재시작을 어떻게 자동화하는지를 다뤄요. 머신 사양 자체가 충분한지부터 확인하고 싶다면 필요 사양을 먼저 보세요.

정말 이 문제인지부터 확인하기

세 가지 신호가 같이 나타나면 거의 확실해요.

신호확인 방법
메모리 사용량이 계속 오르고, 플레이어가 나가도 안 내려온다top / htop에서 서버 프로세스의 RES를 본다. Windows는 작업 관리자
가동 시간이 길수록 무거워지고, 재시작하면 바로 나아진다재시작이 가장 좋은 진단이에요. 나아지면 누수, 안 나아지면 머신 부족
프로세스가 조용히 사라지고 전원이 동시에 튕긴다Linux라면 dmesg에 OOM killer 기록이 남아요

마지막이 가장 아픈 증상이에요. 죽는 순간에 세이브를 쓰고 있었을 수 있고, 반쯤 쓰다 만 Level.sav는 다음 시작 때에야 드러나요. 누수와 백업을 같은 이야기로 봐야 하는 이유예요.

메모리는 어디로 가나

팰월드 서버의 메모리는 네 덩어리로 이루어지고, 그중 셋은 늘기만 해요.

  1. 기본 점유. 1.0 이후로는 콜드 스타트 직후에 4 GB 안팎. 이게 바닥이에요.
  2. 접속 중인 플레이어. 시야 로딩과 탐색 범위 몫으로 한 명당 대략 1.5 GB. 나가면 일부는 돌아오지만 전부는 아니에요.
  3. 월드에 쌓인 것들. 거점, 건축물, 일하는 팰, 바닥의 드롭 아이템. 플레이어가 나가도 메모리 위에서 계속 시뮬레이션돼요. 가장 큰 몫이고 줄지도 않아요. 그만둔 사람이 거점을 가져가진 않으니까요.
  4. 누수 잔여분. 엔진이 회수하지 못한 몫으로, 가동 시간에 비례해 늘어요. 월드에서 아무 일이 없어도 계속 커져요.

앞의 셋이 "메모리가 얼마나 필요한가"를 정하고, 넷째가 "얼마나 자주 재시작해야 하는가"를 정해요. 이 둘을 분리해서 생각하면 이후 판단이 또렷해져요.

1.0에서 이 문제는 얼리 액세스 때보다 무거워졌어요. 해상 거점은 헤엄치는 팰과 나는 팰의 새 경로 탐색을 가져왔고, 하늘섬과 세계수는 추가 로딩 구역이며, 개편된 습격은 한 번에 더 많은 개체를 생성해요. 예전에 8 GB로 돌아가던 월드는 1.0 이후 16 GB를 기준으로 잡으세요.

누수를 빠르게 하는 설정

네 가지 설정이 누수 속도와 직결돼요. 전부 PalWorldSettings.ini의 그 한 줄 안에 있어요(안전한 편집법은 설정 전체 해설에).

설정기본값권장이유
bEnableInvaderEnemyTrueFalse거점 습격은 가장 큰 누수 원인으로 알려져 있어요. 습격마다 대량의 AI 개체와 경로 데이터가 생성되고, 격퇴한 뒤에도 엔진이 다 치우지 못해요. 끄면 같은 월드에서 메모리가 대략 절반이 돼요
BaseCampWorkerMaxNum15기본값 유지일하는 팰 한 마리마다 행동 시뮬레이션이 돌아요. 거점이 많은 서버에서 50으로 올리는 건 코어 하나를 꽉 채우는 지름길이에요
DropItemAliveMaxHours1.00.5주인 없는 드롭 아이템이 남는 시간(시간 단위). 절반으로 줄이면 개체 회수가 빨라져요
AutoSaveSpan30기본값 유지, 늘려도 60까지자동 저장 간격이고 단위는 초예요. 짧을수록 디스크 쓰기가 잦아져서 느린 디스크에선 저장할 때마다 멈춰요. 하지만 60초를 넘기진 마세요. 크래시 때 잃는 진행이 딱 그 간격만큼이에요

첫 줄은 따로 짚을게요. bEnableInvaderEnemy를 꺼도 사라지는 건 스크립트로 발생하는 거점 습격뿐이에요. 야생 팰이 거점에 들어오는 일상은 그대로고 PvP에도 영향이 없어요. 불규칙하게 모이는 그룹에서 습격은 대개 아무도 없을 때 일어나고, 돌아오면 잔해만 남아 있죠. 꺼서 아쉬워하는 사람은 거의 없고, 대신 메모리 여유의 절반이 돌아와요.

메모리를 늘려도 낫지 않는 이유

가장 흔한 오진이에요. 16 GB를 32 GB로 올려서 얻는 건 "안 튕긴다"가 아니라 "사흘에 한 번이 엿새에 한 번이 된다"예요. 누수는 주어진 용량을 언젠가 채워요. 시간문제일 뿐이에요.

메모리 증설로 사는 건 재시작 사이의 간격이고, 그것 자체는 가치가 있어요. 네 시간마다가 아니라 새벽에 한 번으로 끝낼 수 있는지를 정하는 게 이 여유거든요. 하지만 재시작을 대신하진 못해요.

반대로 하지 말아야 할 것도 있어요.

  • bIsUseBackupSaveData를 끄지 마세요. 백업은 누수 원인이 아니고, 끄면 튕긴 날에 돌아갈 길이 하나 줄 뿐이에요.
  • ServerReplicatePawnCullDistance를 5000 아래로 내리지 마세요. 팰 동기화 거리의 공식 하한이고, 그 아래로 내리면 플레이어에게 멈춰 있는 팰이 보여요.
  • 한 머신에서 팰월드 서버 둘을 돌리지 마세요. 누수가 이중으로 쌓여서 OOM이 두 배 빨리 와요.

얼마나 자주 재시작할까

머신의 메모리와 습격 여부로 정해요. 실제 운영에서 통하는 기준이에요.

머신 메모리습격재시작 간격
8 GB1~2시간마다
8 GB2~4시간마다
16 GB 이상2~4시간마다
16 GB 이상4~6시간마다

고정 멤버 서버라면 실용적인 답은 더 단순해요. 16 GB 이상, 습격 끔, 새벽에 하루 한 번. 이 조합이면 하루 안에 누수가 위험선까지 가지 않고, 새벽 네 시 재시작은 거의 아무도 못 느껴요. 하루 종일 누군가 있는 공개 서버만 몇 시간마다 재시작이 필요해요.

간격이 충분한지는 재시작 직전의 메모리 사용량이 물리 한계에서 얼마나 떨어져 있는지로 봐요. 여유가 20% 아래로 내려가면 간격을 줄이거나, 메모리를 더해서 간격을 벌리세요.

세이브를 잃지 않는 자동 재시작

프로세스를 그냥 kill하는 건 매일 크래시를 손수 만드는 것과 같아요. 제대로 된 재시작은 네 단계, 공지 → 강제 저장 → 정지 → 시작이고 전부 공식 REST API로 해요(RCON은 지원 중단됐으니 새 스크립트의 바탕으로 삼지 마세요).

먼저 PalWorldSettings.ini에서 API를 켜고, 로컬호스트에만 열어요.

RESTAPIEnabled=True
RESTAPIPort=8212
AdminPassword="충분히 긴 비밀번호"

인증은 HTTP Basic이고 사용자 이름은 항상 admin, 비밀번호는 AdminPassword예요. 개발사는 공식 문서에서 이 API가 인터넷에 직접 노출되도록 설계되지 않았다고 명시했으니 방화벽에서 8212를 열지 마세요.

Linux에서 그대로 쓸 수 있는 스크립트예요.

#!/bin/bash
# /home/palserver/restart.sh: 공지, 저장, 재시작
PW='충분히 긴 비밀번호'
API='http://127.0.0.1:8212/v1/api'

curl -s -u "admin:$PW" -X POST "$API/announce" \
     -H 'Content-Type: application/json' \
     -d '{"message":"Server restarts in 5 minutes for maintenance"}'
sleep 240
curl -s -u "admin:$PW" -X POST "$API/announce" \
     -H 'Content-Type: application/json' \
     -d '{"message":"Saving and restarting in 60 seconds"}'
sleep 60
curl -s -u "admin:$PW" -X POST "$API/save"
sleep 10
sudo systemctl restart palworld

cron에 걸어 매일 새벽 네 시에 돌려요.

0 4 * * * /home/palserver/restart.sh >> /home/palserver/restart.log 2>&1

서버가 구축 가이드대로 systemd 서비스로 등록돼 있다는 전제예요. Restart=on-failure는 크래시 뒤에 다시 띄우는 것만 맡고, 메모리가 차오르는 데는 아무것도 하지 않아요. 둘 다 필요해요.

Windows도 같은 생각이에요. PowerShell의 Invoke-RestMethodannouncesave를 차례로 부르고, Stop-ProcessPalServer-Win64-Shipping을 멈춘 뒤 PalServer.exe를 다시 띄우고, 작업 스케줄러에 매일 실행으로 걸어 두면 돼요.

업데이트도 같이 묶기

게임이 업데이트되면 옛 빌드에 남은 서버에는 아무도 못 들어와요. 어차피 하루에 한 번 멈추니까, 시작할 때마다 버전을 확인하게 해도 비용은 0이에요.

# palworld.service의 [Service] 섹션에 한 줄 추가
ExecStartPre=/usr/games/steamcmd +force_install_dir /home/palserver/palworld +login anonymous +app_update 2394010 validate +quit

시작 전에 매번 설치를 검증하고 패치가 있으면 받아요. 시작에 1~2분 더 걸리는 대신, 패치가 나온 날 아침에 서버는 이미 새 빌드예요. 업데이트 전 백업은 남겨 두세요. 세이브 형식이 버전에 따라 바뀌기도 해요.

자주 묻는 질문

팰월드 서버는 왜 메모리가 계속 늘어나나요?

세 가지가 겹쳐요. 거점, 팰, 드롭 아이템은 플레이어가 나가도 메모리 위에서 계속 시뮬레이션되며 쌓이기만 하고, 엔진에는 회수되지 않는 알려진 누수가 있고, 거점 습격마다 치워지지 않는 개체가 남아요. 앞의 둘은 필요한 메모리 양을 정하고, 마지막은 그냥 끌 수 있어요.

습격을 끄면 무엇을 잃나요?

스크립트로 발생하는 거점 습격만이에요. 야생 팰의 침입, PvP, 보스는 영향이 없어요. 대신 같은 월드의 메모리 사용량이 대략 절반이 돼요.

팰월드 서버는 얼마나 자주 재시작해야 하나요?

16 GB 이상에 습격을 껐다면 새벽에 하루 한 번이면 충분해요. 8 GB이거나 습격을 켰다면 2~4시간마다로 줄이세요. 기준은 재시작 직전의 여유이고, 20% 아래면 간격을 줄여요.

메모리를 늘리면 서버가 안 튕기나요?

그것만으론 낫지 않아요. 누수는 어떤 용량이든 채워 버리고, 증설은 튕기는 간격을 벌릴 뿐이에요. 몇 시간마다가 아니라 새벽 네 시 한 번으로 끝낼 수 있게 되는 점은 가치가 있지만, 재시작 자체는 건너뛸 수 없어요.

호스팅에선 스위치 하나

위 절차에서 어려운 건 어느 한 단계가 아니에요. 아무도 지켜보지 않는 상태로 오래 제대로 돌아가야 한다는 점이에요. 스크립트를 쓸 사람, 비밀번호를 관리할 사람, cron을 지켜볼 사람, 튕기면 새벽에 일어날 사람이 필요하죠. 첫 주에는 돌아가도 석 달 뒤에 아직 살아 있는지 기억하는 사람은 없어요.

KeepWorlds팰월드 전용 서버에서는 이것들이 콘솔의 항목 몇 개로 모여요. 매일 예약 재시작은 체크박스와 시각뿐이라 「매일 자동으로 재시작」을 켜고 조용한 시간대를 고르면 끝이에요. 튕긴 프로세스는 자동으로 다시 뜨고, 세이브는 정해진 간격으로 자동 백업되며 그 전에 API로 강제 저장이 들어가요. 습격이나 거점당 팰 수 같은 설정은 게임 설정 폼에서 바꿀 수 있어서 ini를 만질 일이 없어요. 각 항목의 뜻은 설정 전체 해설에 있어요.

다른 언어로 보기

직접 운영하지 않아도 돼요

게임과 요금제만 고르면 전용 머신에 서버가 올라가요. 백업과 게임 업데이트, 기한 알림은 저희가 챙길게요.

지원 게임 보기