서버 사양 및 용량 가이드
기술지원 엔지니어가 고객 환경에 적합한 FlowKat 서버 사양을 산정하기 위한 가이드다. Docker Compose 기반 단일 호스트 배포 환경을 기준으로 한다.
1. 개요
FlowKat 서버는 7개의 Docker 서비스로 구성된다. 각 서비스는 동일한 호스트 위에서 Docker Compose로 구동되므로, 호스트 머신의 총 자원이 서비스 합산 요구량을 충족해야 한다.
사양 산정 시 입력 변수:
| 변수 | 설명 | 영향 범위 |
|---|---|---|
| 에이전트 인스턴스 수 | 수집 대상 Java/Host/Container 에이전트 총 개수 | collect-server 힙, PostgreSQL 디스크 |
| 일 평균 트랜잭션 건수 | 하루 동안 에이전트가 전송하는 XLog 건수 합계 | PostgreSQL 디스크, tx-mining-api 부하 |
| 데이터 보존 기간 (일) | PostgreSQL Cold Storage 보존 정책 | PostgreSQL 디스크 |
| 동시 접속 브라우저 수 | 대시보드 동시 사용자 수 | ui-server, dashboard-server 메모리 |
2. 서비스별 권장 사양
2.1 전체 요약
| 구성 요소 | CPU (코어) | 메모리 | 디스크 | 비고 |
|---|---|---|---|---|
| collect-server | 2 | 2~4 GB | 10 GB (filedump + log) | JVM -Xmx2g (prod) |
| api-server | 1 | 1~2 GB | 2 GB (log) | JVM -Xmx1g (prod) |
| dashboard-server | 2 | 2~3 GB | 5 GB (H2 DB + log) | JVM -Xmx2g (prod) |
| ui-server | 1~2 | 1~2 GB | 2 GB (log) | Node.js PM2 클러스터, 최대 2 GB 힙 |
| tx-mining-api | 1~2 | 1~2 GB | 2 GB (log) | JVM -Xmx1g (prod), Spring Boot 3.x |
| PostgreSQL 16 | 2~4 | 4~8 GB | 100 GB~+ | shm_size: 1gb, pg_partman 파티셔닝 |
| Valkey 9.0 | 1 | 1~2 GB | 1 GB (AOF 영속화) | Redis-compatible, 실시간 집계 캐시 |
| 전체 합계 (prod) | 10~18 | 12~23 GB | 120 GB~+ | OS 및 Docker 오버헤드 제외 |
2.2 collect-server
- 역할: 에이전트로부터 TCP 6100으로 성능 데이터(XLog, Counter)를 수신한다. 내장 DB에 5분 집계 데이터를 저장하고, XLog Plugin을 통해 PostgreSQL에 원시 트랜잭션을 기록한다.
- 기준 코드 경로:
수집 서버/conf/flowkat.conf
| 항목 | 최소 (소규모) | 권장 (중규모) | 대규모 |
|---|---|---|---|
| CPU | 2 코어 | 4 코어 | 8 코어 |
| 메모리 | 2 GB | 4 GB | 8 GB |
| JVM 힙 | -Xmx1g -Xms512m | -Xmx2g -Xms2g | -Xmx4g -Xms4g |
| 디스크 | 10 GB | 30 GB | 50 GB |
디스크 분류:
| 경로 | 용도 | 크기 추정 |
|---|---|---|
volumes/collect-server/filedump/ | 에이전트 전송 원시 데이터 임시 저장 | 에이전트 100개 기준 일 ~2 GB |
volumes/collect-server/database/ | 내장 DB (5분 집계) | 에이전트 100개 기준 일 ~500 MB |
volumes/collect-server/conf/ | 설정 파일 (flowkat.conf) | < 1 MB |
2.3 api-server
- 역할: collect-server 내장 DB를 조회하여 REST API를 제공한다. dashboard-server가 이 API를 호출한다. 외부로 포트를 노출하지 않는다(내부 6188).
- 기준 코드 경로:
API 서버/
| 항목 | 최소 | 권장 | 비고 |
|---|---|---|---|
| CPU | 1 코어 | 2 코어 | I/O 바운드 위주 |
| 메모리 | 1 GB | 2 GB | JVM -Xmx1g |
| JVM 힙 | -Xmx512m -Xms256m | -Xmx1g -Xms1g | |
| 디스크 | 2 GB | 2 GB | 로그 전용 |
2.4 dashboard-server
- 역할: api-server에서 데이터를 가져와 대시보드 화면을 렌더링한다. 메타데이터(대시보드 설정, 역할, 사용자 등)를 H2 내장 DB에 저장한다. tx-mining-api 트래픽도 프록시한다.
- 기준 코드 경로:
대시보드 서버/
| 항목 | 최소 | 권장 | 비고 |
|---|---|---|---|
| CPU | 1 코어 | 2 코어 | |
| 메모리 | 1 GB | 3 GB | JVM -Xmx2g |
| JVM 힙 | -Xmx1g -Xms512m | -Xmx2g -Xms1g | |
| 디스크 | 5 GB | 10 GB | H2 DB + 로그 |
디스크 분류:
| 경로 | 용도 | 크기 추정 |
|---|---|---|
volumes/dashboard-server/META_H2/ | H2 내장 DB (메타데이터, 대시보드 설정) | < 500 MB (운영 기준) |
volumes/dashboard-server/config/dashboard/ | 설정 파일 | < 10 MB |
2.5 ui-server
- 역할: Next.js 애플리케이션을 PM2 클러스터 모드로 구동한다. 포트 6300을 외부에 노출한다. dashboard-server(포트 6600)를 HTTP 프록시한다.
- 기준 코드 경로: 프론트엔드 서버
| 항목 | 최소 | 권장 | 비고 |
|---|---|---|---|
| CPU | 1 코어 | 2 코어 | PM2 인스턴스 수에 비례 |
| 메모리 | 1 GB | 2 GB | Node.js 힙 최대 2 GB |
| 디스크 | 2 GB | 2 GB | 로그 + 업로드 |
PM2 인스턴스 수(**PM2_INSTANCES**)와 메모리 관계:
| PM2_INSTANCES | 메모리 소비 추정 |
|---|---|
1 (기본) | ~300~500 MB |
2 | ~600 MB~1 GB |
max (CPU 수만큼) | CPU 코어당 ~300 MB 추가 |
2.6 tx-mining-api
- 역할: PostgreSQL Cold Storage와 Valkey Hot Cache를 조합하여 트랜잭션 분석(TX-Mining) API를 제공한다. Spring Boot 3.x, JDK 17 기반이다.
- 기준 코드 경로:
TX-Mining 서버/
| 항목 | 최소 | 권장 | 비고 |
|---|---|---|---|
| CPU | 1 코어 | 2 코어 | 쿼리 집약적 |
| 메모리 | 1 GB | 2 GB | JVM -Xmx1g |
| JVM 힙 | -Xmx512m -Xms256m | -Xmx1g -Xms512m | |
| 디스크 | 2 GB | 2 GB | 로그 전용 |
2.7 PostgreSQL 16
- 역할: XLog 원시 트랜잭션 데이터를 Cold Storage로 보관한다. pgvector(AI 벡터 검색)와 pg_partman(시간 기반 파티셔닝)을 사용한다.
- 기준 이미지:
flowkat/postgres-ai:16.5
| 항목 | 최소 | 권장 | 비고 |
|---|---|---|---|
| CPU | 2 코어 | 4 코어 | 파티션 쿼리 집약적 |
| 메모리 | 4 GB | 8 GB | shm_size: 1gb 필수 |
| 디스크 | 50 GB | 200 GB~ | 데이터 보존 기간에 비례 |
PostgreSQL 디스크 추정 공식:
일 디스크 사용량(GB) ≈ 일 트랜잭션 건수(만) × 0.5 KB/건 / 1024
총 디스크(GB) = 일 디스크 사용량(GB) × 보존 기간(일) × 압축 계수(1.5)
예시:
| 일 트랜잭션 | 보존 기간 | 예상 디스크 |
|---|---|---|
| 100만 건/일 | 30일 | ~22 GB |
| 500만 건/일 | 90일 | ~330 GB |
| 1,000만 건/일 | 90일 | ~660 GB |
2.8 Valkey 9.0
- 역할: tx-mining-api의 Hot Data 캐시(실시간 집계 데이터)를 담당한다. AOF 모드로 영속화한다.
- 기준 이미지:
valkey/valkey:9.0-alpine
| 항목 | 최소 | 권장 | 비고 |
|---|---|---|---|
| CPU | 1 코어 | 1 코어 | 단일 스레드 |
| 메모리 | 512 MB | 2 GB | 실시간 집계 규모에 비례 |
| 디스크 | 500 MB | 2 GB | AOF 파일 |
3. 디스크 사용량 추정
3.1 서비스별 볼륨 경로와 크기
| 서비스 | 볼륨 경로 | 용도 | 일 증가량 추정 (에이전트 50개 기준) |
|---|---|---|---|
| collect-server | volumes/collect-server/filedump/ | 원시 데이터 임시 덤프 | ~1 GB/일 |
| collect-server | volumes/collect-server/database/ | 내장 DB (5분 집계) | ~200 MB/일 |
| dashboard-server | volumes/dashboard-server/META_H2/ | H2 DB (설정 메타) | < 10 MB/일 |
| tx-mining-api | PostgreSQL (volumes/postgres/) | Cold Storage XLog | 일 트랜잭션에 비례 |
| valkey | volumes/mining-server/data/ | AOF + RDB | ~100 MB/일 |
3.2 로그 파일
FlowKat 서비스는 컨테이너 내부에서 표준 출력(stdout)으로 로그를 기록하며, Docker 로그 드라이버가 관리한다.
# 로그 확인 방법
docker logs collect-server --tail 100 -f
docker logs api-server --tail 100 -f
docker logs dashboard-server --tail 100 -f
docker logs ui-server --tail 100 -f
docker logs tx-mining-api --tail 100 -f
Docker 기본 로그 드라이버(json-file) 사용 시 컨테이너당 최대 100 MB × 3개 파일 = 300 MB가 기본 한도다. 운영 환경에서는 max-size와 max-file 제한 설정을 권장한다.
# docker-compose 로그 설정 예시
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
3.3 Docker 이미지 용량
릴리즈 번들 이미지 7개의 합산 크기다 (압축 tar 기준 추정).
| 이미지 | 압축 크기 추정 |
|---|---|
| collect-server (Java 8 Corretto Alpine) | ~200 MB |
| api-server (Java 8 Corretto Alpine) | ~200 MB |
| dashboard-server (Java 8) | ~250 MB |
| ui-server (Node.js LTS) | ~300 MB |
| mining-server (JDK 17 Alpine) | ~250 MB |
| valkey:9.0-alpine | ~20 MB |
| postgres-ai:16.5 | ~150 MB |
| 합계 | ~1.4 GB |
이미지 로드 후 Docker 레이어 캐시를 포함하면 실제 디스크 점유는 ~3~4 GB다.
4. 네트워크 사용량 추정
4.1 에이전트 → Collect Server (TCP 6100)
에이전트 1개당 대역폭 소비는 모니터링 대상 애플리케이션의 트랜잭션 부하에 비례한다.
| 에이전트 부하 | 단일 에이전트 대역폭 | 에이전트 100개 합계 |
|---|---|---|
| 저부하 (TPS < 10) | ~10 KB/s | ~1 Mbps |
| 중부하 (TPS 10~100) | ~50~200 KB/s | ~40~160 Mbps |
| 고부하 (TPS > 100) | ~200 KB/s~ | ~160 Mbps~ |
FlowKat 에이전트는 기본 net.send_buffer_size(기본값: 128 KB) 단위로 배치 전송한다. Collect Server는 TCP 6100 단일 포트로 모든 에이전트를 수신한다.
4.2 서비스 간 내부 통신
Docker 브리지 네트워크 내부 통신은 루프백에 준하는 속도다. 외부 방화벽 규칙 대상이 아니다.
| 경로 | 프로토콜 | 특성 |
|---|---|---|
| api-server ↔ collect-server | HTTP REST (내부 6188) | 폴링 주기 5s, 요청당 < 10 KB |
| dashboard-server ↔ api-server | HTTP REST (내부 6188) | 브라우저 요청에 비례 |
| dashboard-server ↔ tx-mining-api | HTTP REST (내부 8090) | TX-Mining 쿼리 요청 |
| ui-server ↔ dashboard-server | HTTP Proxy + WebSocket (내부 6600) | WebSocket 실시간 스트림 포함 |
| tx-mining-api ↔ postgres | JDBC TCP (내부 5432) | 쿼리 응답 크기에 비례 |
| tx-mining-api ↔ valkey | Redis 프로토콜 (내부 6379) | < 1 KB/요청 |
4.3 브라우저 → UI Server (HTTP/WS 6300)
| 동시 접속자 | 예상 대역폭 |
|---|---|
| 1~5명 | ~5 Mbps |
| 10~20명 | ~20~50 Mbps |
| 50명 이상 | ~100 Mbps~ (실시간 차트 데이터 포함) |
WebSocket 연결은 대시보드 실시간 차트 갱신에 사용되며, 연결 1개당 ~5~20 KB/s의 지속 트래픽이 발생한다.
5. 용량 한계 (Maximum Capacity)
5.1 Collect Server 에이전트 한계
Collect Server 1개 인스턴스의 실질적 최대 처리 용량이다. JVM 힙 -Xmx2g 기준.
| 한계 항목 | 기준값 | 비고 |
|---|---|---|
| 동시 에이전트 연결 수 | ~500개 | TCP 연결 유지 기준 |
| 초당 수신 트랜잭션(TPS) | ~5,000 TPS | 단일 Collect Server 기준 |
| filedump 쓰기 처리량 | ~100 MB/s | 디스크 I/O 한계 |
에이전트 수가 200개를 초과하거나 평균 TPS가 2,000 이상이면 -Xmx4g 이상으로 힙을 증가한다.
5.2 동시 브라우저 세션
UI Server(Next.js PM2) + Dashboard Server 조합의 동시 접속 한계.
| 항목 | 기준값 | 비고 |
|---|---|---|
| 권장 동시 접속 | 20명 이하 | PM2_INSTANCES=2 기준 |
| 최대 동시 접속 | 50명 | CPU/메모리 한계, 응답 지연 발생 가능 |
5.3 X-View 검색 한계
X-View(XLog 검색)는 PostgreSQL xlog 파티션 테이블에 직접 쿼리한다.
| 항목 | 기준값 | 비고 |
|---|---|---|
| 단일 쿼리 시간 범위 | 최대 24시간 | 초과 시 응답 지연 |
| 동시 X-View 쿼리 | 5개 이하 | 초과 시 PostgreSQL 연결 풀 포화 |
| 결과 반환 최대 건수 | 10,000건 | API Server 기본 제한 |
5.4 TX-Mining 쿼리 한계
| 항목 | 기준값 | 비고 |
|---|---|---|
| 단일 분석 시간 범위 | 최대 7일 | 초과 시 pgvector 쿼리 타임아웃 |
| 동시 분석 쿼리 | 3개 이하 | Valkey 캐시 히트율에 영향 |
| 파티션 보존 기간 | pg_partman 설정에 의존 | retention 파라미터 참조 |
6. 환경별 권장 구성
Docker Compose 단일 호스트 배포 기준이다. 모든 서비스를 1대의 서버에서 운영한다.
| 규모 | 에이전트 수 | CPU 합계 | 메모리 합계 | OS 포함 디스크 | 네트워크 |
|---|---|---|---|---|---|
| 소규모 | 1~50개 | 8 코어 | 16 GB | 150 GB SSD | 1 Gbps |
| 중규모 | 51~200개 | 16 코어 | 32 GB | 500 GB SSD | 1 Gbps |
| 대규모 | 201~500개 | 32 코어 | 64 GB | 1 TB SSD + 별도 PG 스토리지 | 10 Gbps |
소규모 환경 (에이전트 1~50개)
# .env.production 힙 설정 (소규모)
COLLECT_SERVER_JAVA_OPTS=-Xmx1g -Xms512m
API_SERVER_JAVA_OPTS=-Xmx512m -Xms256m
DASHBOARD_SERVER_JAVA_OPTS=-Xmx1g -Xms512m
TX_MINING_JAVA_OPTS=-Xmx512m -Xms256m
중규모 환경 (에이전트 51~200개)
# .env.production 힙 설정 (중규모)
COLLECT_SERVER_JAVA_OPTS=-Xmx2g -Xms2g
API_SERVER_JAVA_OPTS=-Xmx1g -Xms1g
DASHBOARD_SERVER_JAVA_OPTS=-Xmx2g -Xms1g
TX_MINING_JAVA_OPTS=-Xmx1g -Xms512m
대규모 환경 (에이전트 201~500개)
# .env.production 힙 설정 (대규모)
COLLECT_SERVER_JAVA_OPTS=-Xmx4g -Xms4g
API_SERVER_JAVA_OPTS=-Xmx2g -Xms1g
DASHBOARD_SERVER_JAVA_OPTS=-Xmx4g -Xms2g
TX_MINING_JAVA_OPTS=-Xmx2g -Xms1g
대규모 환경에서는 PostgreSQL을 별도 전용 서버로 분리하는 것을 권장한다. 단일 호스트 PostgreSQL은 대용량 파티션 쿼리 시 CPU 경합으로 전체 서비스 성능에 영향을 준다.
7. 주의사항
7.1 알려진 병목 포인트
PostgreSQL I/O 병목
- 증상: TX-Mining 쿼리 응답 지연, X-View 로딩 느림
- 원인: 대용량 파티션 테이블에 대한 순차 스캔
- 조치: SSD 사용 필수. HDD 환경에서 TX-Mining 기능은 성능 저하가 심각하다. PostgreSQL 전용 볼륨을 별도 마운트한다.
Collect Server GC 중단
- 증상: 에이전트에서 주기적인 데이터 전송 지연 발생
- 원인: 에이전트 연결 수 증가로 JVM 힙 소진 → Full GC 발생
- 조치:
-Xmx값을 증가한다. G1GC 사용이 기본값이므로 별도 GC 튜닝은 불필요하다.
# Collect Server GC 상태 확인
docker exec collect-server jstat -gcutil 1 5000
Valkey 메모리 한계 초과
- 증상: TX-Mining 실시간 집계 데이터 오류
- 원인: Valkey maxmemory 정책 미설정 시 OOM
- 조치:
volumes/mining-server/config/valkey.conf에maxmemory설정 추가
# volumes/mining-server/config/valkey.conf
maxmemory 1gb
maxmemory-policy allkeys-lru
7.2 스케일링 고려사항
수평 확장 불가 (Docker Compose 단일 노드 제약)
FlowKat 5.0.27은 Docker Compose 단일 노드 배포를 전제로 한다. collect-server는 상태를 로컬 파일시스템(filedump, 내장 DB)에 유지하므로, 여러 인스턴스로 수평 확장이 불가하다.
에이전트 500개 이상 규모는 벤더(개발팀)에 별도 아키텍처 검토를 요청한다.
메모리 스왑 비활성화
JVM 기반 서비스(collect-server, api-server, dashboard-server, tx-mining-api)는 스왑 사용 시 GC 지연이 급격히 증가한다. 운영 서버에서는 스왑을 비활성화한다.
# 스왑 상태 확인
free -h
swapon --show
# 스왑 비활성화
sudo swapoff -a
# /etc/fstab에서 swap 항목 주석 처리 (영구 적용)
Docker 로그 드라이버 설정
기본 json-file 드라이버는 무제한 증가하므로, 프로덕션에서는 반드시 max-size와 max-file을 설정한다. 미설정 시 디스크 풀(disk full)로 서비스가 중단될 수 있다.
PostgreSQL **shm_size** 요구사항
flowkat/postgres-ai:16.5 이미지는 Docker Compose에서 shm_size: 1gb가 설정되어 있다. 호스트의 /dev/shm 여유 공간이 1 GB 미만이면 PostgreSQL 컨테이너가 기동되지 않는다.
# 공유 메모리 확인
df -h /dev/shm
관련 문서
- 아키텍처 개요 → 아키텍처 및 기술 스택
- Docker Compose 환경변수 →
[16.docker-compose.md](./16.docker-compose.mdx) - 포트/방화벽/프로토콜 →
[17.network-ports.md](./17.network-ports.mdx)