오브젝트 스토리지와 S3 · SeaweedFS — 작은 파일이 많을 때의 선택 · 이론
Haystack 모델과 마스터·볼륨·파일러
한 줄 요약
SeaweedFS 는 작은 파일 수백만 개를 몇 개의 큰 컨테이너 파일에 패킹한다. 파일 개수만큼의 inode 도, 파일 개수만큼의 메타데이터 조회도 없다.
왜 이게 필요했나
썸네일 100만 개를 파일시스템에 두면 무슨 일이 생기는지 겪어 본 사람이 많습니다. 디스크 사용량은 얼마 안 되는데 inode 가 고갈되고, ls 가 몇 분씩 걸리고, 백업 도구가 파일 하나하나를 stat 하느라 며칠을 씁니다. 4KB 파일 100만 개는 데이터로는 4GB 지만 파일시스템에는 100만 개의 메타데이터 엔트리입니다.
오브젝트 스토리지가 이걸 다 해결하지도 않습니다. 객체마다 메타데이터 레코드가 생기고 요청도 객체 단위로 붙기 때문에, 개수가 곧 비용이자 부하가 됩니다.
SeaweedFS 는 페이스북의 Haystack 논문에서 온 접근을 씁니다. 작은 파일들을 큰 볼륨 파일 안에 이어서 쓰고, 위치(오프셋과 길이)만 기억합니다. 파일 1,000개가 볼륨 파일 하나에 들어가면 inode 는 하나이고, 읽기는 오프셋 시크 한 번입니다.
어떻게 동작하나
세 종류의 데몬이 있습니다.
마스터(기본 9333)는 볼륨의 배치만 관리합니다. 어떤 볼륨이 어느 볼륨 서버에 있는지, 새 파일을 어디에 쓸지를 정합니다. 파일 메타데이터는 갖고 있지 않다는 점이 중요합니다 — 그래서 마스터가 병목이 되지 않습니다.
볼륨 서버(기본 8080번대)는 실제 데이터를 갖습니다. 볼륨 파일(.dat)과 인덱스(.idx)를 한 쌍으로 두고, 파일 ID 로 오프셋을 찾아 읽습니다.
파일러(기본 8888)는 그 위에 디렉터리 구조와 POSIX 속성을 얹는 별도의 무상태 서버입니다. 경로 기반으로 쓰고 읽고 싶으면 파일러를 통합니다. S3 게이트웨이도 이 위에 있습니다.
기본 흐름은 이렇습니다. 마스터에 /dir/assign 을 요청해 파일 ID(예: 3,01637037d6)와 볼륨 서버 주소를 받고, 그 서버에 파일을 올립니다. 읽을 때는 /dir/lookup 으로 볼륨 위치를 찾아 그 서버에서 받습니다. 이 두 단계가 SeaweedFS 의 핵심이고, 파일러와 S3 게이트웨이는 그 위의 편의 계층입니다.
현장에서 만나는 모습
선택 기준을 솔직하게 정리하면 이렇습니다. 소파일이 대량이고 개수가 곧 문제라면 SeaweedFS 가 강합니다. 큰 파일 위주이고 S3 API 만 있으면 되는 소규모라면 Garage 같은 가벼운 선택지가 낫습니다. 조직 규모가 크고 스토리지 팀이 있다면 Ceph RGW 가 검증된 선택입니다.
리스크도 정직하게 봐야 합니다. SeaweedFS 는 릴리스가 가장 활발한 축이지만 커밋 집중도가 높습니다 — 창시자의 커밋이 9,968개로 2위(530개)와 자릿수가 다릅니다. 프로젝트가 죽어 간다는 뜻이 아니라 버스 팩터에 대한 우려가 정당하다는 뜻입니다.
그리고 이 판단이 실제로 필요해진 배경이 있습니다. MinIO 커뮤니티 에디션은 2025년 5월 기능 축소, 9~10월 배포 중단, 12월 유지보수 모드를 거쳐 2026년 3~7월에 저장소가 순차 아카이브됐습니다. 라이선스는 끝까지 AGPLv3 였지만, high 등급 CVE 의 수정이 공식 이미지로는 오지 않는 형태로 전환 비용이 사용자에게 넘어왔습니다. 교훈은 "MinIO 가 나빴다"가 아니라, 단일 벤더가 CLA 를 쥔 오픈소스 인프라는 그 벤더의 사업 전환이 곧 프로젝트의 운명이라는 것입니다. 데이터가 물리적으로 눌러앉는 계층에서는 이 리스크가 이주 비용으로 직결됩니다.
다음 실습에서 할 것
마스터, 볼륨, 파일러를 직접 띄우고 파일 ID 를 발급받아 올리고 조회합니다. 소파일 500개를 넣어 볼륨 파일 개수를 확인하고, 마지막 실습에서 같은 코퍼스를 파일시스템, S3, SeaweedFS 세 곳에 넣어 특성을 숫자로 비교합니다.