기존 GIS 엔진은 모놀리식 시스템입니다.
전국 단위 데이터를 한 번에 처리하는 파이프라인은 수십 시간에서 많게는 수백 시간이 걸렸습니다.
이를 개선하기 위해 멀티노드 기반의 병렬 빌드 시스템으로 전환했습니다. 그 과정에서 모듈화 리팩토링을 진행했습니다.
하지만 초기에 하나의 모듈에 많은 책임을 주어 확장성과 유지보수성을 떨어트렸습니다.
이 글에서는 SRP(Single Responsibility Principle)를 만족하지 않는 모듈이 어떤 문제를 일으키는지,
그리고 이 문제를 해결하기 위해 SRP를 만족하는 모듈로 어떻게 구현 했는지 정리했습니다.
모듈화 전/후 구조 차이

모듈화 전: 프로세스가 1개의 모듈을 실행하고, 해당 모듈에서 여러 내부 메서드(기능)를 실행하는 구조
모듈화 후: 프로세스가 1개의 모듈을 실행하고, 해당 모듈에서 여러 모듈을 실행하는 구조 (모듈 : 내부 기능 = 1: 1)
(내부 기능은 핵심 기능을 의미합니다.)
목차
1. 용어
2. 배경: 빌드 과정
3. 기존 구조: 한 모듈이 모든 작업을 하는 방식
4. 결합도가 높은 모듈의 문제점 정리
1) 기능 확장이 어렵다 (OCP 위반)
2) 단계별 장애·예외 추적이 어렵다
3) 리소스(CPU/GPU) 활용 효율이 낮다
4) 테스트·디버깅 비용이 증가한다
5. 모듈화 과정
5.1. 모듈화 목표
5.2. 모듈 설계 원칙
5.3. 실제 모듈 분리 구조
6. 결론
1. 용어
모듈화 과정에서, GIS 빌드 단계의 용어입니다.
| 용어 | 대응 개념 | 설명 |
| Subtree | 도시 (City) | 전체 지역 단위 (예: 서울, 부산, 전주) - (타일 구조 파일 : .subtree) |
| Tile | 구역 (District) | 실제 모델이 배치되는 구역 단위 - (실제 콘텐츠 파일 : .glb) |
| Feature | 공간 정보 (Feature) | 실제 객체 정보 (위치, 크기, 속성 등) - (DB에 저장된 레코드) |
참고: Tile 크기 단위를 크고 작게 함에 따라 (Tile : Subtree = 1 : 1) 또는 (Tile : Feature =1 : 1)이 가능합니다.
- 대한민국에는 서울, 부산, 전주 같은 여러 도시를 포함한다. (전국 : 도시 = 1 : N)
- 도시 서울에는 강남구, 관악구 같은 여러 구역를 포함한다. (도시 : 구역 = 1 : N)
- 구역 강남구에는 코엑스, 스타벅스를 이루는 여러 공간 정보를 포함한다. (구역 : 공간= 1 : N)
2. 배경: 빌드 과정
빌드 규모 예시
- 전국에는 N개의 서브트리(도시)가 존재한다.
- 각 도시에는 M개의 타일(구역)이 존재한다.
- 각 구역에는 P개의 피처가 존재한다.
총 N × M × P개의 단위 작업(Task)이 존재합니다.
비즈니스 규칙으로 빌드의 원자 단위를 서브트리(도시)로 설정했습니다.
즉, 하나의 서브트리에 속한 모든 타일(M개)과, 각 타일 내부의 모든 피처(P개)를 한 번에 처리합니다.
따라서 '서브트리 단위 빌드' 모듈을 만들었습니다.
이 모듈 안에서 “서브트리 → 타일 → 피처” 전체 빌드 과정을 모두 수행했습니다.
서브트리 단위 빌드 과정
서브트리 단위 빌드는 아래 두 과정을 순차적으로 수행합니다.
- 서브트리에 포함된 모든 타일 빌드
- 모든 타일 빌드가 끝나면 서브트리 빌드
1) 서브트리에 포함된 모든 타일 빌드
서브트리 빌드의 첫 단계는, 서브트리에 속한 M개의 타일을 모두 생성하는 과정입니다.
- 서브트리에 포함된 모든 타일(M개)의 식별자를 조회한다.
- 각 타일의 메타데이터(위치, 크기, 바운딩 볼륨, 텍스처 레벨 등)를 수집한다.
- 각 타일에 포함된 모든 피처(P개)의 식별자를 조회한다.
- 조회된 피처(P개)의 메타데이터(좌표, 크기, 모델 식별자, 속성 정보 등)를 수집한다.
- 타일 메타데이터 + 해당 타일의 P개 피처 모델을 조합하여 하나의 타일(GLB)을 생성한다.
이 작업은 서브트리에 속한 M개의 타일에 대해 반복합니다.
for (타일 식별자 in M개의 타일 식별자) {
var 타일 메타데이터 = 타일 메타데이터 조회(타일 식별자) // (2)
var 피처 식별자들(P개) = 타일 메타데이터.피처 식별자들 // (3)
var 피처 메타데이터들(P개) = 피처(P개) 메타데이터 조회(피처 식별자들(P개)) // (4)
var 타일GLB = 타일 빌드(타일 메타데이터 + 피처 메타데이터들(P개) + 타일 빌드 옵션) // (5)
}
2) 모든 타일 빌드가 끝나면 서브트리 빌드
- 빌드된 타일들의 결과(타일 메타데이터)를 모아서
- 하나의 .subtree 파일로 구성한다.
이 두 단계가 하나의 서브트리에 대해 완성되는 순간,
서브트리는 최종적으로 "정상 빌드" 상태가 됩니다. (= DB 트랜잭션 원자성)
3. 기존 구조: 한 모듈이 모든 작업을 하는 방식
초기에는 ‘서브트리 단위 빌드 모듈’ 하나가 전체 빌드 과정을 모두 담당하는 구조로 개발했습니다.
이 모듈은 다음 두 단계를 순차적으로 수행했습니다.
- 서브트리에 포함된 모든 타일(M개) 빌드
- 모든 타일 빌드가 끝난 후 서브트리 빌드
서브트리 단위 빌드 모듈은 다음 작업을 모두 포함했습니다.
- 서브트리 메타데이터 조회(DB ㅡ 조회)
- 타일(M개) 메타데이터 조회(DB ㅡ 조회)
- 피처(P개) 메타데이터 조회(DB ㅡ 조회)
- 타일 빌드 타입 선택 (건물, 포인트 클라우드 등)
- 타일 빌드 (= GLB 파일 생성)
- 타일 상태 업데이트(DB ㅡ 쓰기)
- 서브트리 빌드 (= Subtree 파일 생성)
- 서브트리 상태 업데이트(DB ㅡ 쓰기)
- 모듈 내부 예외 처리
즉, 조회 → 연산 → 빌드 → 쓰기→ 예외 처리까지
하나의 모듈이 다양한 기능을 수행하는 결합도가 높은 구조였습니다.
처음에 이렇게 개발한 이유
- 빌드의 원자적 단위가 ‘서브트리’다
- 서브트리에 속한 모든 타일과 피처를 한 번에 처리하기 때문에, 서브트리 단위로 빌드 로직을 묶는 게 자연스럽다고 생각했다. - 유지보수 측면에서도 “서브트리 단위로 로직을 관리하면 된다”고 생각했다
- 빌드 단위인 특정 서브트리 빌드에 문제가 생기면 → 해당 모듈 로그만 보면 된다.
- 병렬 처리를 하더라도 → “서브트리 단위”로 병렬 처리하면 충분하다고 판단했다.
즉, “빌드의 원자 단위가 서브트리이니, 서브트리 내부의 모든 빌드 로직도 한 모듈에 넣어도 된다.”라는 접근이었습니다.
결합도가 높은 모듈의 한계
빌드 원자성 단위로 서브트리로 묶는 것은 적절했지만,
서브트리 내부의 모든 빌드 로직을 한 모듈에 몰아넣는 구조는 다음과 같은 한계가 있습니다.
- 책임이 과도하게 집중되어 SRP 위반
- 서브트리에 속한 타일 속성이 변경될 때마다 전체 모듈 수정 필요
- 타일 빌드 방식(건물, 포인트 클라우드 등)이 추가되고, 해당 타일의 속성이 다르면 전체 모듈 수정 필요
- 병렬 처리, GPU 빌드 등 새로운 기능 추가 시 전체 모듈 수정 필요
- 타일/피처/서브트리 실패를 구분하기 어려움
- CPU/GPU 자원 분리 불가 → 성능 확장 어려움
- 테스트·검증·디버깅 비용 증가
결국,
- “서브트리를 원자 단위로 묶는 것”
- “서브트리 내부 로직을 하나의 모듈로 묶는 것”
이 둘은 서로 다른 문제라는 점을 알았습니다.
이후에는 빌드 과정을 단계별 책임 기반으로 분리하는 모듈화 작업을 진행했습니다.
4. 결합도가 높은 모듈의 문제점 정리
- 기능 확장이 어렵다 (OCP 위반)
- 단계별 장애·예외 추적이 어렵다
- 리소스(CPU/GPU) 활용 효율이 낮다
- 테스트·디버깅 비용이 증가한다
1) 기능 확장이 어렵다 (OCP 위반)
단일 모듈이 타일 빌드 방식, 피처 빌드 방식, 병렬 처리 전략 등
여러 기능을 모두 내부에서 처리하는 구조였기 때문에,
- 새로운 타일 빌드 방식(건물, 포인트클라우드 등)을 추가하거나
- GPU 기반 빌드, 타일 단위 병렬 빌드 같은 새로운 전략을 도입할 때마다
- 반드시 기존 서브트리 빌드 모듈을 수정해야 했습니다.
이는 OCP(개방–폐쇄 원칙)을 명확히 위반하며,
기능이 늘어날수록 모듈이 계속 비대해지고 유지보수성이 급격히 저하되는 구조였습니다.
기존 구조에서 해결 방법
- 새로운 기능을 추가할 때마다 기존 모듈을 직접 수정할 수밖에 없습니다. (OCP 위반)
모듈화 했다면
- “새로운 타일 빌더 모듈”, “병렬 빌더 모듈”만 독립적으로 추가하여 확장할 수 있습니다.
- 기존 서브트리 빌드 모듈을 수정하지 않고도 기능 확장이 가능합니다(OCP 준수).
2) 단계별 장애·예외 추적이 어렵다
기존 구조에서는 서브트리, 타일, 피처 등 서로 다른 단계에서 발생한 오류가 모두 동일한 예외로 처리됐습니다.
예를 들어,
- 타일 빌드 실패 → InvalidDataException (C#에서 지원하는 예외)
- 서브트리 빌드 실패 → 동일한 InvalidDataException
이처럼 예외가 동일하게 처리되면 “어떤 단계에서 문제가 발생했는지” 추적하기 어렵습니다.
기존 구조에서 해결 방법
예외 구분을 위해 다음 두 가지 방식 중 하나를 적용해야 합니다.
- 모든 내부 메서드를 호출할 때마다 try-catch를 직접 둘러싸기
- TileBuildException, SubtreeBuildException 같은 커스텀 예외를 직접 정의하기
모듈화 했다면
- 어떤 모듈에서 예외가 발생했는지 호출자가 명확히 알 수 있습니다.
- 예외 처리를 모듈 내부가 아니라 모듈 호출자(조립자)에서 수행할 수 있어,
동일한 예외라도 상황에 따라 다양한 대응 전략을 취할 수 있습니다. - 단계별 장애 추적이 명확해져 디버깅 비용이 감소합니다.
3) 리소스(CPU/GPU) 활용 효율이 낮다
서브트리 빌드는 CPU 중심 작업이며, 타일 빌드는 GPU 중심 작업입니다.
그러나 기존 구조는 하나의 모듈에서 모든 작업을 순차적으로 실행했기 때문에,
- 서브트리 빌드 중에는 GPU 자원이 놀고 있고
- 타일 빌드 중에는 CPU 자원이 놀고 있는
리소스 활용도가 매우 낮은 비효율적 구조입니다.
기존 구조에서 해결 방법
- 구조가 단일 모듈이기 때문에 자원을 병렬로 활용할 방법이 없습니다.
- CPU와 GPU를 각각 독립적으로 확장하는 것도 불가능했습니다.
모듈화 했다면
- CPU 기반 빌드 모듈과 GPU 기반 타일 빌드 모듈을 독립적으로 병렬화할 수 있습니다.
- CPU/GPU 클러스터를 별도로 스케일 아웃하여 자원을 최적으로 사용할 수 있습니다.
- 전체 빌드 속도 향상뿐만 아니라 인프라 효율성도 크게 증가합니다.
4) 테스트·디버깅 비용이 증가한다
기존 서브트리 빌드 모듈은 조회, 빌드, 저장, 예외 처리까지 모든 단계를 모두 수행하는 구조입니다.
이로 인해 다음과 같은 문제가 발생했습니다.
- 작은 기능만 수정해도 전체 파이프라인을 다시 검증해야 합니다.
- 특정 단계만 독립적으로 단위 테스트하기 어렵습니다.
- 여러 단계가 하나의 호출 흐름에 섞여 있어 문제가 어디서 발생했는지 빠르게 파악하기 어렵습니다.
기존 구조에서 해결 방법
- 특정 단계만 테스트할 수 없기 때문에 전체 빌드를 반복 실행해야 합니다.
모듈화 했다면?
- 모듈을 단위별로 독립 테스트할 수 있습니다.
(타일 빌드 모듈, 서브트리 빌드 모듈, SubtreeBuildModule 각각 테스트 가능) - 모듈 경계가 명확해져 어떤 단계에서 장애가 발생했는지 즉시 파악할 수 있습니다.
- 전체 파이프라인을 재빌드하지 않아도 문제가 있는 모듈만 선택적으로 검증·수정할 수 있습니다.
참고
다음 두 문제는 다른 문제입니다.
- 2) 단계별 장애·예외 추적이 어렵다
- 4) 테스트·디버깅 비용이 증가한다
2번 = “차가 고장 났는데, 엔진이 문제인지 타이어가 문제인지 구분이 안 되는 상황” = 원인 식별 문제
4번 = “엔진이 문제라는 걸 알아도, 차 전체를 분해해야만 수리 가능한 상황” = 원인을 알고 이를 고치기 위한 비용 문제
5. 모듈화 과정
기존 구조는 서브트리 빌드에 필요한 모든 로직(타일 조회, 피처 조회, 빌드, 저장)을 하나의 모듈에 몰아넣은 구조였습니다.
이를 개선하기 위해 빌드 과정을 단계별 책임(SRP)으로 분리하고,
각 모듈의 Input/Output을 명확히 정의해 조립 가능한 빌드 파이프라인을 설계했습니다.
5.1 모듈화 목표
모듈화를 진행할 때 정한 목표는 다음 세 가지였습니다.
1) 단일 책임(SRP) 기반 분리
하나의 모듈이 조회·연산·빌드·저장을 모두 담당하지 않도록, 각 단계가 정확히 하나의 역할만 수행하도록 분리했습니다.
2) 모듈 간 결합도 최소화
각 모듈은 서로의 내부 구현을 몰라도 되며, Input/Output 타입만 알고 호출할 수 있는 구조로 만들었습니다.
즉, 모듈 간의 I/O 인터페이스만 맞으면 내부 로직은 자유롭게 교체할 수 있는 형태입니다.
3) 빌드 파이프라인을 ‘조립 가능한 구조’로 구성
각 모듈을 독립적으로 실행 가능한 유닛으로 만들고,
전체 빌드 과정은 조립자(Orchestrator)가 다음과 같이 순서대로 실행합니다.
- 모듈1 실행 → 결과를 모듈2에 전달
- 모듈2 실행 → 다음 모듈로 전달
- …
- 최종적으로 빌드된 타일/서브트리에 ID에 대해 DB 상태 업데이트 1회 수행
이런 구조를 통해 개별 모듈은 독립된 기능에만 집중할 수 있게 되었습니다.
5.2. 모듈 설계 원칙
모듈화를 진행할 때 정한 목표는 다음 세 가지였습니다.
1) 입/출력을 명확하게 정의
모든 모듈은 다음 형태를 따릅니다.
- 입력: 핵심 기능을 수행하는 데 필요한 최소 정보
- 출력: 다음 모듈이 사용할 수 있는 구조화된 데이터
이 원칙을 기반으로 모듈을 설계하면, 기능을 교체하거나 조합하는 것이 쉬워집니다.
| 기능 | 입력 | 출력 |
| 서브트리 조회 | 서브트리 ID | 서브트리 메타 데이터, 타일 ID 목록 (M개) |
| 타일 조회(M번) | 타일 ID | 타일 메타데이터, 피처 ID 목록(P개) |
| 피처 조회(P번) | 피처 ID | 피처 메타데이터 |
| 타일 빌드 | 타일 메타데이터(M개), 피처 메타데이터(P개), 타일 빌드 옵션들(텍스처 여부 등) |
GLB 바이너리 파일 |
| 서브트리 빌드 | 서브트리 메타데이터, 타일 메타데이터(M개) |
subtree 파일 |
2) 입출력은 도메인 및 DB에 의존하지 않고 POJO(Plain Old Java Object), POCO로 구현
- 모듈 I/O가 도메인에 의존하면, 도메인이 변 할 경우 모듈 기능은 같아도 모듈 I/O코드를 변경해야 한다.
3) 외부 I/O(DB, 파일 저장)를 단계 밖으로 분리
- 네트워크 I/O
- 파일 쓰기
- DB 상태 업데이트
같은 부수효과(side effect)는 모두 빌드 연산 모듈에서 제거했습니다.
즉, 빌드 모듈은 “순수한 계산”만 수행하고 DB 상태 업데이트는 마지막 단계에서 한 번만 수행합니다.
이는 트랜잭션 안정성, 유지 보수성, 재시도 가능성, 테스트 용이성 모두를 높입니다.
5.3. 실제 모듈 분리 구조
- 서브트리 단위 빌드 실행 모듈 (Orchestrator)
- 타일 빌더 호출 모듈
- 타일 빌드 모듈
- 서브트리 빌드 모듈
1) 서브트리 단위 빌드 실행 모듈 (Orchestrator)
역할: 전체 빌드 과정을 순서대로 조립하는 최상위 모듈
입력: 서브트리 ID, 타일 빌드 옵션
출력: 서브트리 ID / 빌드된 타일 ID 목록
작업 흐름:
- 서브트리에 속한 타일 메타데이터 DB 조회 (1회)
- “타일 빌더 호출 모듈” 실행
- “서브트리 빌드 모듈” 실행
- 모든 타일/서브트리에 대해 DB 상태 업데이트를 1회 수행
→ 서브트리 단위 빌드 실행 모듈은 오케스트레이션만 담당하며 연산은 하지 않습니다.
2) 타일 빌더 호출 모듈
입력:
- 타일 ID 목록(M개)
- 피처 메타데이터(P개)
- 빌드 옵션들 (타일 종류, 텍스처, Normal, QuantizeMesh 등)
출력:
- GLB 파일 목록
- 타일 메타데이터 (서브트리 빌드용)
책임:
- 타일별 메타데이터 조회
- 피처 메타데이터(P개) 전달
- 타일 종류(Building, PointCloud 등)에 맞는 타일 빌더 선택 및 호출 (건물 타일 / 포인트클라우드 타일 빌드 모듈 등)
왜 타일 빌더 호출 모듈이 메타데이터 조회 책임까지 지나요?
원칙적으로는 타일 메타데이터 조회, 피처 메타데이터 조회, 타일 빌더 호출을 각각 분리하는 것이 SRP에 이상적입니다.
그러나 실제 도메인에서는 타일 종류(건물, 포인트 클라우드 등)가 달라도 입력 데이터 구조는 완전히 동일합니다.
- 모든 타일은 같은 형태의 타일 메타데이터를 사용하고
- 모든 타일은 동일한 피처 메타데이터(P개)를 사용합니다.
즉, “타일을 빌드하기 위해 필요한 데이터”는 타일 종류와 무관하게 항상 동일합니다. (타일 메타데이터 관리를 공통 포맷만 관리)
따라서 타일 빌더 호출 모듈이
- 타일별 메타데이터 조회
- 피처 메타데이터 조회
- 적절한 타일 빌더 호출
을 하나의 책임 안에서 처리하는 것은 SRP 위반이 아니라고 생각했습니다.
SRP는 “단일 책임”을 지키라는 원칙입니다. 여기서 책임의 기준은 도메인의 목적입니다.
따라서 타일 빌더 호출 모듈의 단일 책임은
“서브트리에 속한 각 타일을 빌드하기 위해 필요한 데이터를 준비하고 적절한 타일 빌더를 호출하는 것” 으로 정의했습니다.
그럼 왜 서브트리 빌드 모듈(프로세스 진입점)에서 모든 타일/피처 메타데이터를 한 번에 조회하지 않나요?
피처는 메타데이터만 존재하는 것이 아니라, 각 피처와 1:1 매핑된 모델(이미지, 바이너리 데이터)이 존재합니다.
이 모델은 크기 편차가 매우 큽니다.(수 KB ~ 수십 MB)
서브트리 당 평균 2~300개의 타일이 존재하고,
타일 당 평균 2~300개의 피처와 모델이 존재합니다.
즉, 1개의 서브트리는 최대 90,000개의 모델이 존재할 수 있습니다.
최상위 모듈에서 이 90,000개의 모델을 한 번에 로드하면
수백 MB~수 GB의 메모리를 점유하게 되어 OOM 가능성이 생깁니다.
따라서 실제 빌드 과정에서는
- 서브트리에 속한 모든 타일 메타데이터는 서브트리 단위로 1회 조회하고
- 각 타일에 속한 피처/모델 메타데이터(P개)는 “타일 빌드 직전”에 필요한 것만 지연 로딩합니다.
3) 타일 빌드 모듈(타일 타입별 빌더)
예시:
- 건물 타일 빌드 모듈
- 포인트클라우드 타일 빌드 모듈
입력: 타일 메타데이터 + 피처 메타데이터(P개) + 빌드 옵션
출력: .glb 바이너리 파일
책임: 3D 모델 생성 (GLB) ㅡ Normal 처리, Texture 적용, Draco/양자화 등 옵션 처리
→ '타일 종류'에 따라 타일 빌더를 교체하면 다른 타입의 타일 빌드를 쉽게 확장할 수 있습니다.
4) 서브트리 빌드 모듈
입력:
- 서브트리 메타데이터
- 빌드된 타일 메타데이터(M개)
출력: .subtree 파일
책임: 서브트리 파일 생성
6. 결론
SRP(단일 책임 원칙)의 핵심은 “모듈이 무엇을 책임져야 하는가”를 도메인 관점에서 명확히 정의하는 것입니다.
모듈화를 진행하면서 빌드 파이프라인의 기능 자체는 동일하지만,
- 누가 어떤 단계를 책임지는지(책임 재정의)
- 각 단계가 어떻게 실행되는지(구조 정리)
이 두 가지를 재정립했습니다.
그 결과, 빌드 과정의 조회 · 연산 · 빌드 · 저장 단계가 도메인 단위로 명확하게 분리되었고,
다음과 같은 요구에도 독립적·유연하게 대응할 수 있게 되었습니다.
- 다양한 타일 종류(건물, 포인트클라우드 등) 확장
- DB 트랜잭션 처리 전략 변경
- 네트워크 I/O 예외 처리 구조 개선
특히 타일 빌드 단계를 모듈 단위로 분리한 덕분에,
다음과 같은 요청이 들어와도 기존 코드를 수정하지 않고 해결할 수 있는 구조가 되었습니다.
- 새로운 빌드 타입 추가
- 서브트리 단위/타일 단위 병렬 실행 전략 전환
- 파일 업로드 예외 처리 방식 변경
단순히 새로운 모듈을 추가하고, 호출자에서는 전략 패턴을 통해 해당 모듈을 선택하는 방식으로 확장할 수 있습니다.
즉, 기능 확장은 “기존 코드 수정 → 새로운 코드 추가” 방식으로 바뀌었고, 유지보수성은 크게 향상되었습니다.
네트워크 I/O 예외 처리에 대하여
이 글에서는 다루지 않았지만, 빌드된 파일(.subtree, .glb)을 S3·MinIO·SeaweedFS 등으로 업로드할 때
수십~수천 개 파일에서 발생할 수 있는 누락·중복 업로드 문제는 별도의 예외 처리 전략이 필요했습니다.
모듈화를 통해 확보한 확장성을 바탕으로 업로드 단계를 독립적으로 개선할 수 있었고,
이에 대한 설계와 구현 방식은 다음 글에서 정리할 예정입니다.
'개발 노트 > 실무 프로젝트' 카테고리의 다른 글
| 3D 모델 요청/응답 API 설계 (0) | 2025.12.22 |
|---|---|
| [마이그레이션] Spring 4 → Boot 3.4: Java 17, Gradle, JAR, 그리고 제어권의 변화 (0) | 2025.12.12 |
| 대용량 파일 업로드의 정합성 보장 전략: Atomic Rename과 SeaweedFS 활용 (0) | 2025.11.27 |
| Gzip, Zstandard, Brotli 압축 비교 - 3D 모델 파일 (0) | 2025.10.07 |
| 전 세계 공간정보를 관리하는 자료구조 구현기 - Implicit Tiling (7) | 2025.07.20 |