제가 이 프로젝트를 맡는다면 API Server 하나를 만드는 것이 아니라, "Prefix Management Platform(PMP)"라는 하나의 제품으로 설계합니다.
현재 요구사항(6,000 Prefix, 수십~수백억 Object, Kafka Event, Redis, CNPG, AIStor)을 보면 단순 CRUD API 구조로는 2~3년 후 반드시 한계가 옵니다.
제가 추천하는 구조는 MSA까지는 아니지만 Domain별 모듈형(Monolithic Modular Architecture) 입니다.
+----------------------+
| Web / Portal |
+----------+-----------+
|
REST / gRPC / OpenAPI
|
========================
Prefix API Gateway
========================
|
----------------------------------------------------------------
| | | | | | |
Prefix Object Quota Policy Event Admin Search
Service Service Service Service Service Service Service
| | | | | |
---------------- Shared Domain ----------------
|
Metadata Repository(CNPG)
|
Redis <--> Event Worker
^
|
Kafka Consumer Group
^
|
AIStor Bucket Notification
여기서 중요한 것은 API Server가 Event를 직접 처리하지 않는 것입니다.
API Server는 Control Plane입니다.
절대로
를 하지 않습니다.
API Server는 오직
사용자 요청
↓
Validation
↓
Business Logic
↓
MetaDB
↓
AIStor API
만 수행합니다.
Spring Boot 기준으로 설명하면
src
api
PrefixController
ObjectController
QuotaController
PolicyController
AdminController
service
PrefixService
ObjectService
QuotaService
PolicyService
repository
PrefixRepository
ObjectRepository
domain
Prefix
Object
Quota
Event
integration
AIStorClient
KafkaProducer
RedisClient
KeycloakClient
batch
ReconciliationJob
common
이 구조를 추천합니다.
예)
Prefix 생성
POST /prefix
↓
Validation
↓
CNPG
INSERT Prefix
↓
AIStor
PUT .placeholder
↓
History 저장
↓
Response
API Server 아닙니다.
별도
Event Worker
입니다.
이게 핵심입니다.
역할
Kafka
↓
Event Parsing
↓
Redis Update
↓
Flush Scheduler
↓
CNPG Update
Worker는
REST API가 없습니다.
Kafka만 봅니다.
Kafka는
Message Queue가 아니라
Event Bus
입니다.
추천 Topic
bucket-event
audit-event
server-event
quota-event
system-event
Event Flow
AIStor
↓
Kafka
↓
Consumer
↓
Redis
↓
CNPG
Kafka가 필요한 이유
Consumer는
비즈니스 로직을 수행합니다.
예)
ObjectCreated
↓
bucket
projectA
size
100MB
prefix
train/
↓
Consumer
↓
Redis
usage +=100MB
count +=1
↓
끝
DB는 안 건드립니다.
Redis는
Cache가 아닙니다.
저는
Aggregation Engine
으로 씁니다.
예)
동시에
10000
ObjectCreated
발생
DB
10000 UPDATE
하지 않습니다.
Redis
usage +=100MB
usage +=200MB
usage -=30MB
계속 누적
5초마다
670MB
만
DB 반영
이게 Redis의 가장 중요한 역할입니다.
추천
Hash
prefix_usage
projectA
delta_size
delta_count
또
Sorted Set
top_upload
또
Set
dirty_prefix
별도 Worker입니다.
Redis
↓
Dirty Prefix
↓
CNPG
UPDATE
왜 필요한가?
Redis에는
최신값
DB에는
최종값
CNPG는
Source of Truth
입니다.
Redis는 아닙니다.
CNPG 저장
Prefix
Quota
Alias
Owner
History
Object Summary
Daily Statistics
Object 전체는?
저는
30일만 저장 추천합니다.
API Server 내부
Search Service
추천
GET
/search
↓
SQL
↓
CNPG
이것도 분리
Grant
↓
AIStor IAM
↓
Attach
↓
History
Object Service는
Object를 저장하지 않습니다.
Wrapper입니다.
Download
↓
Presigned URL
Upload
↓
Presigned URL
Delete
↓
DeleteObjects
API Server 안에는
Consumer가 없습니다.
Event Service는
Kafka Producer만 있습니다.
예)
관리자가
Quota 변경
↓
quota-event
발행
API Server
Scheduler
Inventory Compare
ILM Check
Cleanup
Quota Scan
제가 만들면
Worker도 나눕니다.
Event Consumer
Flush Worker
Reconciliation Worker
Alert Worker
Statistic Worker
Kafka
↓
Threshold
↓
Alertmanager
↓
Slack
↓
매일 새벽
Inventory
↓
Parquet
↓
Spark
↓
Difference
↓
CNPG Fix
| Service | 역할 | AIStor 호출 | Redis | Kafka | CNPG |
|---|---|---|---|---|---|
| Prefix Service | Prefix CRUD | O | X | O | O |
| Object Service | Upload/Download | O | X | X | 조회 |
| Policy Service | IAM | O | X | O | O |
| Quota Service | Quota CRUD | X | 조회 | O | O |
| Search Service | 검색 | X | X | X | O |
| Event Consumer | Event 처리 | X | O | Consume | X |
| Flush Worker | Redis Flush | X | O | X | O |
| Statistic Worker | 통계 생성 | X | O | X | O |
| Reconciliation | 정합성 | Inventory | X | X | O |
| Alert Worker | 알람 | Metric | 조회 | Consume | 조회 |
현재 프로젝트 규모를 고려하면 "Hexagonal Architecture(Ports & Adapters) + Event-Driven Architecture + CQRS(Read/Write 분리)"를 권장합니다.
즉,
이 구조의 가장 큰 장점은 AIStor는 Data Plane, Prefix Management Platform은 Control Plane으로 명확히 역할이 분리된다는 점입니다. 향후 Prefix가 6,000개에서 60,000개로 증가하거나, 이벤트가 초당 수만 건 수준으로 늘어나더라도 API 서버를 수정하지 않고 Consumer와 Worker만 확장하여 대응할 수 있습니다. 이는 현재 추진 중인 대규모 Cloud Native Data Lakehouse 환경에 가장 적합한 아키텍처라고 판단됩니다.