S3 Tables 와 S3 Vectors (Iceberg 테이블 버킷, 벡터 버킷)
Apache Iceberg 테이블을 관리형으로 담는 S3 Tables(테이블 버킷, 자동 압축, 2025-12 의 복제와 Intelligent-Tiering)와, 임베딩 벡터를 S3 에 싸게 저장하고 검색하는 S3 Vectors(2025-12 GA, 인덱스당 20 억 벡터)의 구조, 한도, 쓰임새를 정리합니다.
버킷 종류가 늘었다
예전에는 S3 버킷이 한 종류였지만 지금은 용도별로 나뉩니다.
| 버킷 | 담는 것 | 대표 API |
|---|---|---|
| 범용 버킷 | 아무 객체 | PutObject, GetObject |
| 디렉터리 버킷 | S3 Express One Zone 객체 | 같은 S3 API, 한 자릿수 ms |
| 테이블 버킷 (S3 Tables) | Apache Iceberg 테이블 | CreateTable, Iceberg REST 카탈로그 |
| 벡터 버킷 (S3 Vectors) | 임베딩 벡터와 메타데이터 | PutVectors, QueryVectors |
S3 Tables
S3 Tables 는 re:Invent 2024 에 나온 Iceberg 전용 관리형 테이블 저장소입니다. 범용 버킷에 Iceberg 테이블을 직접 두면 작은 파일 압축(compaction), 스냅숏 만료, 참조 안 되는 파일 정리를 모두 직접 돌려야 하는데, 테이블 버킷은 이것을 자동으로 해 줍니다.
구조
- 테이블 버킷 안에 네임스페이스(데이터베이스 같은 것)가 있고, 그 안에 테이블이 있습니다.
- 각 테이블은 Iceberg 형식이라 Athena, Redshift, EMR, Glue, Apache Spark, Trino, DuckDB 같은 Iceberg 호환 엔진이 읽고 씁니다.
- AWS 분석 서비스와는 Glue Data Catalog(SageMaker 의 레이크하우스 아키텍처)에 통합해서 쓰고, 바깥 엔진은 Iceberg REST 카탈로그 엔드포인트로 붙습니다.
- 권한은 테이블 단위 IAM 정책과 Lake Formation 으로 줍니다.
aws s3tables create-table-bucket --name analytics-tables --region ap-northeast-2
aws s3tables create-namespace --table-bucket-arn arn:aws:s3tables:ap-northeast-2:111122223333:bucket/analytics-tables --namespace sales-- Athena 에서 (카탈로그 통합 후)
CREATE TABLE sales.orders (
order_id string, customer_id string, amount decimal(12,2), ordered_at timestamp
) PARTITIONED BY (day(ordered_at))
TBLPROPERTIES ('table_type' = 'iceberg');
2025-12 에 더해진 것
- 복제: 테이블을 다른 리전이나 다른 계정의 테이블 버킷으로 자동 복제해 읽기 전용 사본을 둡니다. 재해 복구와 지역별 분석에 씁니다.
- Intelligent-Tiering: 테이블 데이터도 접근 패턴에 따라 자동으로 싼 계층으로 옮깁니다.
- S3 Storage Lens 지표를 S3 Tables 로 내보내 SQL 로 분석할 수도 있습니다.
비용 요소
저장(GB-월), 요청, 객체 모니터링, 그리고 압축 처리량(처리한 객체 수와 바이트)에 요금이 붙습니다. 스트리밍으로 작은 파일을 아주 많이 쓰면 압축 요금이 커지니, 쓰는 쪽에서 배치 크기를 키우는 것이 먼저입니다.
팁 "범용 버킷의 Iceberg" 와 "S3 Tables" 중 고민된다면, 압축과 정리 작업을 직접 운영할 인력이 없을수록 S3 Tables 가 낫습니다. 이미 Spark 기반 유지 보수 파이프라인이 잘 돌고 있다면 서두를 이유는 적습니다.
S3 Vectors
S3 Vectors 는 2025-07 에 Preview 로 나와 2025-12-02 에 GA 된 벡터 저장소입니다. 임베딩 벡터를 S3 의 내구성과 가격 구조로 저장하고, 전용 API 로 유사도 검색을 합니다. GA 때 서울을 포함한 14 개 리전에서 시작했습니다.
한도 (2026-10 문서 기준)
| 항목 | 값 |
|---|---|
| 인덱스당 벡터 | 최대 20 억 개 (Preview 때 5,000 만) |
| 벡터 버킷당 인덱스 | 10,000 개 |
| 차원 | 1 부터 4,096 |
| 거리 함수 | 코사인, 유클리드 |
| 벡터당 메타데이터 | 합계 40 KB, 키 50 개, 필터 가능한 메타데이터 2 KB |
| 필터 불가 메타데이터 키 | 인덱스당 10 개 |
| 쓰기 | 인덱스당 초당 PutVectors, DeleteVectors 요청 1,000 건, 한 번에 500 개 |
| 질의 지연 | 드문 질의는 1 초 미만, 잦은 질의는 100 ms 안팎 |
쓰는 법
import boto3
s3v = boto3.client("s3vectors", region_name="ap-northeast-2")
s3v.put_vectors(
vectorBucketName="kb-vectors",
indexName="docs-ko",
vectors=[{
"key": "doc-001#3",
"data": {"float32": embedding}, # 예: 1024 차원
"metadata": {"source": "manual", "lang": "ko", "text": chunk_text},
}],
)
res = s3v.query_vectors(
vectorBucketName="kb-vectors", indexName="docs-ko",
queryVector={"float32": query_embedding}, topK=5,
filter={"lang": "ko"}, returnMetadata=True, returnDistance=True,
)원문 텍스트처럼 필터에 안 쓰는 큰 값은 인덱스를 만들 때 필터 불가 메타데이터로 지정해 두면 질의 비용 계산에서 빠집니다.
어디에 맞나
| 상황 | 추천 |
|---|---|
| 수천만에서 수십억 벡터, 질의는 가끔, 비용이 중요 | S3 Vectors |
| 초당 수천 질의, 수 ms 지연, 하이브리드 검색 | OpenSearch Service(벡터 엔진) |
| 이미 PostgreSQL 을 쓰고 벡터가 적음 | Aurora PostgreSQL 이나 RDS 의 pgvector |
| 둘 다 | S3 Vectors 에 전체를 두고 자주 쓰는 부분만 OpenSearch 로 올리는 계층 구성 |
S3 Vectors 는 Bedrock Knowledge Bases 의 벡터 저장소로 바로 고를 수 있고, OpenSearch Service 가 S3 Vectors 를 저장 계층으로 쓰는 통합도 GA 입니다. AWS 는 전용 벡터 DB 대비 최대 90% 비용 절감을 내세웁니다.
비용 요소
요금은 세 축입니다. (1) PUT 한 벡터의 논리 GB(벡터, 메타데이터, 키 포함), (2) 인덱스 전체의 논리 저장량, (3) 질의 API 호출 요금과 인덱스 크기에 따른 TB 당 요금. 인덱스가 10 만 벡터를 넘으면 TB 당 질의 단가가 내려갑니다. 단가는 리전마다 다르니 S3 요금 페이지의 Vectors 탭에서 확인합니다.
자주 하는 실수
- 임베딩 모델을 바꾸고 같은 인덱스에 섞어 넣음: 차원과 거리 공간이 달라 검색이 엉망이 됩니다. 모델이 바뀌면 인덱스를 새로 만듭니다.
- 메타데이터에 원문을 통째로 넣고 필터 가능으로 둠: 2 KB 필터 한도를 넘고 질의 비용도 늘어납니다.
- S3 Tables 에 작은 INSERT 를 초당 수십 번: 압축 요금과 스냅숏이 폭증합니다. Firehose 나 배치로 모아서 씁니다.
- 테이블 버킷을 범용 S3 API 로 다루려 함: 테이블 버킷 안 파일은 Iceberg 엔진과 S3 Tables API 로 다룹니다.