Batch write and discover records in Amazon SageMaker Feature Store
Quick Summary
Amazon SageMaker Feature Store는 최대 25개 항목을 일괄 기록하는 BatchWriteRecord와 온라인 저장소의 레코드 식별자를 탐색하는 ListRecords를 도입해 수집 처리와 데이터 발견의 제약을 해소한다.
🖼️ 인포그래픽

🖼️ 4컷 인포그래픽

💡 한 줄 요약
Amazon SageMaker Feature Store는 최대 25개 항목을 일괄 기록하는 BatchWriteRecord와 온라인 저장소의 레코드 식별자를 탐색하는 ListRecords를 도입해 수집 처리와 데이터 발견의 제약을 해소한다.
📌 핵심 요약
- 기존 PutRecord는 호출당 하나의 특성 그룹에 레코드 하나를 기록하므로, 초당 10,000개 레코드를 5개 특성 그룹에 수집하는 예시에서는 초당 50,000회 API 호출이 필요하다.
- BatchWriteRecord는 여러 특성 그룹을 합쳐 요청당 최대 25개 항목을 처리하고 EventTime 기반 순서를 유지하며, 일부 항목이 실패해도 성공한 쓰기를 되돌리지 않는다.
- BatchWriteRecord의 TTL은 레코드 수준, 요청 수준, 특성 그룹 수준 순으로 우선 적용되며, 응답의 Errors와 UnprocessedEntries를 확인해 재시도 가능한 실패 항목과 미처리 항목만 지수 백오프로 재시도해야 한다.
- 사용하려면 최신 Boto3 또는 SageMaker Python SDK v3.8.0 이상이 필요하며, 일괄 쓰기 호출자는 대상 특성 그룹별로 sagemaker:BatchWriteRecord와 sagemaker:PutRecord 권한을 보유해야 한다.
- ListRecords는 Standard와 In-Memory 계층에서 삭제되거나 만료되지 않은 활성 레코드의 식별자를 페이지 단위로 반환하며, 응답에 NextToken이 없으면 탐색이 완료된다.
🧩 주요 포인트
- 요청당 최대 25개 항목과 특성 그룹 간 독립 처리 → 호출을 묶어 단일 레코드 수집의 연결 부담을 줄이지만, 여러 쓰기의 일괄 성공이나 롤백은 보장하지 않는다.
- EventTime 순서 보장과 TTL 우선순위 → 온라인 최신값 보호와 보존 기간 제어를 유지하면서 항목별 실패에 대응하는 처리가 필요하다.
- Standard와 In-Memory의 식별자 열거 지원 → 정확한 식별자를 미리 알아야 했던 조회·삭제 작업의 탐색 제약을 완화한다.
🧠 상세 정리
1. 특성 저장소의 역할과 기존 운영 제약
Amazon SageMaker Feature Store는 기계학습 모델에 사용하는 특성을 저장하고 공유하며 관리하는 완전관리형 저장소로, 실시간 추론을 위한 저지연 온라인 제공과 이력 보존 및 학습용 오프라인 저장을 지원한다. 스트리밍과 배치 수집을 모두 지원하지만, 기존 PutRecord는 한 번에 하나의 특성 그룹에 레코드 하나만 기록하므로 대규모 수집에서는 반복 호출이 필요했다. 원문은 초당 10,000개 레코드를 5개 특성 그룹에 반영하는 사기 탐지 파이프라인에 초당 50,000회 호출이 필요하다는 예시로 연결 부담과 처리량 문제를 설명한다. 또 다른 제약은 온라인 저장소에 어떤 레코드가 존재하는지 식별자를 열거할 방법이 없었다는 점이다. 특히 In-Memory 계층은 대체 조회에 사용할 오프라인 저장소가 없어, 버그나 파이프라인 장애로 식별자를 잃으면 저장된 레코드를 다시 찾을 수 없었다.
2. 새 API와 실행 전제 조건
원문은 대량 수집의 호출 부담을 해결하는 BatchWriteRecord와 저장된 레코드의 식별자를 발견하는 ListRecords를 새 API로 소개한다. 예제를 실행하려면 Amazon SageMaker AI 리소스를 생성할 권한이 있는 AWS 계정과, Amazon S3 및 AWS Glue 접근 권한을 갖춘 Amazon SageMaker AI 실행 역할이 필요하다. 실행 역할에는 Feature Store 데이터 영역 API를 호출할 권한도 필요하며, 제시된 IAM 정책에는 sagemaker:BatchWriteRecord, sagemaker:PutRecord, sagemaker:ListRecords가 포함된다. 클라이언트 환경은 최신 Boto3 또는 SageMaker Python SDK v3.8.0 이상을 요구하고, 이미 레코드가 수집된 하나 이상의 특성 그룹을 전제로 한다. 특히 일괄 쓰기는 각 대상 특성 그룹의 ARN에 대해 BatchWriteRecord와 PutRecord 권한을 모두 요구하며, 처리 전에 특성 그룹별 권한을 확인한다.
3. 일괄 쓰기와 최신 레코드 결정 방식
BatchWriteRecord는 한 요청에 최대 25개 항목을 받아 하나 이상의 특성 그룹으로 기록하며, 이 한도는 그룹별 개수가 아니라 요청에 포함된 전체 항목 수에 적용된다. 기존 PutRecord가 레코드 수와 특성 그룹 수를 곱한 만큼 호출을 요구했다면, 새 API는 여러 쓰기를 하나의 요청으로 묶을 수 있게 한다. 쓰기 순서는 PutRecord와 동일하게 EventTime을 기준으로 판단하며, 들어오는 레코드의 EventTime이 기존 레코드보다 최신일 때만 온라인 저장소의 최신 버전이 된다. 그렇지 않은 레코드는 오프라인 저장소가 구성된 특성 그룹에서 이력 버전으로 기록되므로, 오래된 이벤트가 온라인의 더 최신 값을 덮어쓰지 않는다. 따라서 일괄 처리로 호출 구조를 바꾸더라도 최신값을 결정하는 조건부 쓰기의 의미는 유지된다.
4. 부분 성공 응답과 선택적 재시도
BatchWriteRecord에서는 각 레코드가 독립적으로 성공하거나 실패하며, 일부 실패가 전체 요청의 실패나 성공한 쓰기의 롤백으로 이어지지 않는다. 인증·검증 오류나 서비스 제한 등으로 실패한 항목은 원래 레코드와 오류 코드 및 메시지를 포함해 Errors에 반환되고, 처리되지 않은 요청 항목은 UnprocessedEntries에 반환된다. 두 목록 어디에도 포함되지 않은 레코드는 성공한 것으로 판단하며, 애플리케이션은 반환된 항목의 상태를 구분해 후속 처리를 해야 한다. 원문은 재시도 가능한 오류에 지수 백오프를 적용하고 실패 항목만 다시 제출하도록 설명하며, 미처리 항목도 재시도할 수 있다고 명시한다. 따라서 응답을 확인하는 예제 코드는 오류와 미처리 항목을 각각 순회하고, 두 목록이 모두 비었을 때 전체 레코드가 성공적으로 기록되었다고 판단한다.
5. 여러 특성 그룹과 저장 대상 및 TTL 제어
요청의 각 항목은 FeatureGroupName과 Record를 포함하며, TargetStores를 통해 온라인 저장소와 오프라인 저장소 중 하나 또는 둘 모두를 대상으로 지정할 수 있다. 저장 대상을 생략하면 해당 특성 그룹에서 활성화한 저장소가 기본값으로 사용되므로, 같은 요청에서도 항목마다 서로 다른 저장 경로를 적용할 수 있다. 원문의 예제는 사용자 프로필 특성을 온라인에만 기록하고 클릭 특성을 온라인과 오프라인에 함께 기록하며, 한 특성 그룹의 실패가 다른 그룹으로 향하는 레코드에 영향을 주지 않는다고 설명한다. TTL은 개별 항목의 TtlDuration이 최우선이고, 이를 지정하지 않은 항목에는 요청 최상위의 기본 TtlDuration이 적용된다. 레코드 수준과 요청 수준의 TTL이 모두 없으면 특성 그룹에 설정된 TTL이 적용되어, 개별 레코드부터 그룹 기본값까지 명확한 우선순위로 보존 기간을 결정한다.
6. 식별자 중심 접근이 만든 데이터 발견 문제
기존 Feature Store의 PutRecord, GetRecord, DeleteRecord는 호출자가 정확한 레코드 식별자를 알고 있어야 사용할 수 있었으며, 특성 그룹 안의 레코드를 둘러보거나 열거하는 API는 없었다. Standard 계층에서는 Amazon Athena로 오프라인 저장소를 조회하는 우회 방법이 있었지만, 오프라인 저장소 구성이 필요하고 추가 비용이 발생하며 실시간 조회도 아니었다. In-Memory 계층에서는 기본적으로 대응하는 오프라인 저장소가 없어, 식별자를 분실한 레코드를 발견하거나 삭제할 수 없다는 문제가 더 크게 드러났다. 원문은 이러한 상태가 찾을 수 없는 데이터의 잔존과 저장 비용 낭비로 이어지고, 정보 주체의 삭제 요청에 대응할 때 규정 준수 위험도 만들 수 있다고 설명한다. ListRecords는 온라인 저장소에서 식별자를 직접 열거하도록 해 이러한 데이터 발견의 공백을 해소한다.
7. 저장 계층별 식별자 열거 방식
ListRecords는 특성 그룹 안에서 활성 상태이며 삭제되거나 만료되지 않은 레코드의 식별자만 반환하고, 반환된 식별자는 GetRecord나 DeleteRecord에 사용할 수 있다. Amazon DynamoDB 기반의 Standard 계층에서는 온라인 저장소를 스캔해 각 레코드의 최신 버전 식별자를 반환하며, 소프트 삭제되었거나 만료된 레코드는 자동으로 제외한다. Redis 기반의 In-Memory 계층에서는 키를 스캔하고 소프트 삭제된 레코드와 내부 시스템 키를 걸러낸 뒤, 키 이름에서 레코드 식별자를 추출한다. 따라서 두 계층은 내부 탐색 방식이 다르지만, 사용자는 같은 API를 통해 특성 그룹의 사용 가능한 레코드 식별자를 얻는다. 이 API의 반환 대상은 레코드 내용 전체가 아니라 식별자이므로, 내용을 확인하거나 삭제하려면 해당 식별자로 별도의 레코드 API를 호출하는 흐름이 된다.
8. 페이지 단위 탐색과 제공된 예제의 범위
ListRecords 요청은 특성 그룹을 지정한 경로로 전송되며, 첫 호출에서는 MaxResults를 설정하고 후속 호출에서는 이전 응답에서 받은 NextToken을 함께 전달한다. 응답의 RecordIdentifiers에는 레코드 식별자 목록이 들어가고, NextToken이 더 이상 반환되지 않으면 페이지 탐색이 완료된 것으로 판단한다. 원문의 요청 예시는 MaxResults를 50으로 지정하고, Boto3 반복 호출 예제는 100으로 설정한 뒤 각 응답의 식별자를 누적하는 방식을 보여준다. 예제는 다음 토큰이 있을 때만 요청에 NextToken을 추가하고 응답에서 새 토큰을 읽는 부분까지 제시되지만, 제공된 본문은 반복문 종료 조건을 작성하던 중간에서 잘려 있다. 따라서 페이지 탐색의 완료 기준은 본문에 명시된 설명으로 확인할 수 있으나, 제공되지 않은 나머지 코드나 후속 결론은 요약의 근거로 삼을 수 없다.
🧾 핵심 주장 / 시사점
- BatchWriteRecord의 핵심 변화는 호출 단위의 확대이며, EventTime 기반 최신값 판단은 유지되므로 수집 효율과 데이터 순서 보장을 함께 다룬다.
- 부분 성공 방식에서는 요청 전체의 성공 여부만으로 처리 결과를 판단할 수 없으며, Errors와 UnprocessedEntries를 구분하는 항목별 대응이 중요하다.
- ListRecords는 식별자 분실로 조회와 삭제가 막히던 문제를 완화하며, 오프라인 조회로 우회할 수 없었던 In-Memory 계층에서 특히 의미가 크다.
✅ 액션 아이템
- PutRecord 반복 수집 구간의 BatchWriteRecord 전환 검토와 요청당 최대 25개 항목 제한 반영.
- Errors와 UnprocessedEntries를 구분하고 재시도 가능한 실패 항목과 미처리 항목에만 지수 백오프 적용.
- ListRecords로 Standard와 In-Memory의 식별자를 탐색하고 NextToken 부재를 기준으로 완료 여부 확인.
❓ 열린 질문
- 현재 PutRecord 수집에서 요청당 최대 25개 항목을 묶는 BatchWriteRecord로 줄일 수 있는 호출 규모는 얼마인가?
- EventTime 순서 보장과 TTL 우선순위를 고려할 때 레코드 수준과 요청 수준의 TTL을 어떻게 구분해 적용할 것인가?
- Standard와 In-Memory에서 ListRecords로 발견한 식별자를 어떤 조회·삭제 작업에 활용할 것인가?