제 의견은 Go를 적극 추천합니다.
특히 지금 프로젝트 규모(200~300노드, 6,000명 사용자, AIStor Event, Kafka, Redis, CNPG, Kubernetes Native)를 보면 Java(Spring)보다 Go가 더 적합한 부분이 많습니다.
다만 API Server도 Go, Consumer도 Go로 하나의 코드베이스에서 관리하는 것을 추천합니다.
Prefix Management Platform
+----------------------+
| API Server | (Go)
+----------------------+
|
-------------------------
| | |
AIStor CNPG Redis
---------------------------------------------------------
+----------------------+
| Kafka Consumer | (Go)
+----------------------+
|
Kafka
|
AIStor Event
---------------------------------------------------------
+----------------------+
| Flush Worker | (Go)
+----------------------+
---------------------------------------------------------
+----------------------+
| Reconciliation Job | (Go)
+----------------------+
사실상 하나의 Repository 안에
cmd/
api/
consumer/
flush/
reconcile/
pkg/
internal/
형태가 됩니다.
이미 사용하는 것들
거의 다 Go입니다.
라이브러리도 동일합니다.
Spring
API 하나
500MB~1GB
Go
API 하나
30~100MB
대규모 K8s에서는 엄청난 차이입니다.
Kafka Consumer는
동시에
ObjectCreated
ObjectRemoved
ObjectAccessed
수천 개를 처리합니다.
Go는
goroutine 하나당
2KB 정도
Java Thread는
1MB 정도
차이가 큽니다.
Go는
docker image
30MB
Spring은
500MB
정도 됩니다.
AirGap 환경에서도 좋습니다.
저는
YES입니다.
예)
POST /prefix
↓
Validation
↓
CNPG
↓
AIStor
↓
Response
Go가 충분합니다.
Spring이 필요한 복잡한 비즈니스가 아닙니다.
보통
REST Server와는 완전히 다릅니다.
예)
Consumer Group
↓
Topic
↓
Partition
↓
Worker
↓
Redis
Go에서는
보통
main()
↓
Kafka Reader
↓
for {
ReadMessage()
↓
Handle()
}
형태입니다.
실제로는
Consumer
↓
Parser
↓
Validator
↓
Business Logic
↓
Redis
↓
Commit Offset
입니다.
제가 만들면
consumer/
main.go
handler/
object_created.go
object_removed.go
object_accessed.go
parser/
redis/
metrics/
model/
kafka/
입니다.
예)
ObjectCreated
↓
HandleObjectCreated()
↓
Extract Prefix
↓
Redis Increment
↓
Metric
↓
Commit
삭제도
HandleObjectRemoved()
입니다.
추천
Consumer Group
prefix-management
Worker
Replica
5개
Kubernetes
Deployment
replica=5
Kafka가
자동으로
Partition을
나눠줍니다.
추천
bucket-events
하나도 가능하지만
저는
bucket-object-created
bucket-object-removed
audit-log
server-log
분리 추천합니다.
이게 가장 중요합니다.
추천
bucket/prefix
입니다.
예)
bucket1/projectA
↓
Partition 1
bucket1/projectB
↓
Partition 7
그러면
같은 Prefix는
순서가 보장됩니다.
Consumer
↓
HINCRBY
usage
+100MB
입니다.
CNPG는
안 건드립니다.
별도입니다.
5초
↓
Dirty Prefix 조회
↓
UPDATE Prefix Table
예)
초당
10000
PUT
발생
Consumer
↓
DB UPDATE
10000번
망합니다.
Redis
↓
+10000
↓
5초 후
UPDATE 1번
입니다.
저는
무조건
같이 갑니다.
예)
prefix-platform
cmd
api
consumer
flush
reconcile
internal
service
repository
model
redis
kafka
aistor
auth
config
공통 코드
100%
재사용됩니다.
Go에서는
추천
Gin
또는
Echo
둘 다 충분합니다.
저는
Echo를 조금 더 선호합니다.
추천
GORM
또는
sqlx
대규모에서는 sqlx를 더 선호합니다.
추천
segmentio/kafka-go
또는
confluent-kafka-go
제가 추천하는 건
Confluent Kafka Client입니다.
이유
librdkafka 기반
성능 최고
운영 사례 많음
go-redis/v9
거의 표준입니다.
pgx
추천합니다.
성능이 가장 좋습니다.
언어는 전부 Go로 통일합니다.
| 구성요소 | 언어 | 이유 |
|---|---|---|
| API Server | Go | REST 처리량, 낮은 메모리 사용량, Kubernetes 친화적 |
| Kafka Consumer | Go | 고성능 이벤트 처리, goroutine 기반 동시성 |
| Flush Worker | Go | Redis→CNPG 배치 처리 |
| Reconciliation Job | Go | Inventory 기반 메타데이터 보정 |
| Scheduler | Go | CronJob 또는 내장 스케줄러로 충분 |
| CLI(Admin Tool) | Go | 단일 바이너리로 배포 가능 |
추가로 이 프로젝트는 이벤트 기반(Event-Driven) 구조가 핵심이므로, API Server는 가능한 한 Stateless하게 유지하고, 모든 비동기 처리는 Kafka Consumer와 Worker가 담당하도록 역할을 명확히 분리하는 것이 가장 중요합니다. 이렇게 하면 API 서버는 사용자 요청 처리에만 집중하고, 이벤트 처리량이 증가하더라도 Consumer Replica만 늘려 선형적으로 확장할 수 있습니다. 이는 현재 계획 중인 대규모 AIStor 기반 플랫폼에서 가장 안정적이고 운영하기 쉬운 구조입니다.