스케일러블하고 비용 효율적인 고처리량 시계열 스토어를 위한 액세스 패턴 설계

발행: (2025년 12월 4일 오후 06:39 GMT+9)
7 min read
원문: Dev.to

Source: Dev.to

테이블 스키마 및 기본 키

속성유형역할
deviceIdString파티션 키
timestampString (ISO‑8601, e.g., 2025-12-04T12:34:56Z)정렬 키
temperature, humidity, pressureNumber페이로드
metadataString (JSON)옵션 페이로드
ttlNumber (epoch seconds)만료를 위한 TTL 속성

왜 이 PK인가?
디바이스별 모든 읽기값을 함께 저장하여 효율적인 범위 쿼리(deviceId = X AND timestamp BETWEEN …)를 가능하게 합니다. 최신 읽기값에 대한 단일 항목 쿼리는 ScanIndexForward=falseLimit=1을 사용해 수행할 수 있습니다.

인덱싱 전략

인덱스파티션 키정렬 키사용 사례
Primary TabledeviceIdtimestamp디바이스당 포인트 조회 및 범위 쿼리
Global Secondary Index (GSI) – DeviceLatestGSIdeviceIdtimestamp (projected as DESC)전체 파티션을 스캔하지 않고 최신 읽기값을 직접 조회 (Limit=1, ScanIndexForward=false)
Optional GSI – MetricGSImetricType (e.g., "temperature" constant)timestamp단일 메트릭에 대한 디바이스 간 시간 범위 쿼리 (드물게)

Note: 기본 테이블은 이미 최신‑읽기 쿼리를 지원합니다; GSI는 선택 사항이며 동일한 deviceId에 대한 동시 “최신” 읽기가 많이 발생해 핫 파티션 읽기가 발생할 것으로 예상될 때만 비용이 추가됩니다. 대부분의 경우 Limit=1을 사용한 기본 테이블이면 충분합니다.

용량 모드 및 스케일링

모드사용 시점구성
On‑Demand예측 불가능한 급증, 손쉬운 시작, 용량 관리 불필요.자동으로 초당 10 k 쓰기 처리; 요청당 비용 지불.
Provisioned + Auto Scaling예측 가능한 트래픽, 비용 제어 원함.시작 시 15,000 RCUs5,000 WCUs 사용 (각 쓰기 ≤ 1 KB당 1 WCU 소모). 자동 스케일링 목표 70 % 활용도 활성화.

Cost comparison (approx., US East 1, Dec 2025):

  • On‑Demand 쓰기: 백만 쓰기 요청 단위당 $1.25 → 초당 10 k 쓰기 기준 약 $12.5 k/월 (≈ 26 M 쓰기/일).
  • Provisioned 5,000 WCUs는 WCU‑시간당 약 $0.65 → $2.3 k/월에 자동 스케일링 버퍼 추가.

On‑Demand는 운영이 간단하고, 트래픽이 안정적이면 Provisioned가 더 저렴할 수 있습니다.

핫 파티션 위험 완화

  • Uniform deviceId distribution: 디바이스 ID가 무작위(예: UUID 또는 해시)인지 확인합니다.
  • If a few devices dominate traffic: Sharding을 사용합니다 – deviceId 앞에 무작위 샤드 접미사를 붙입니다(e.g., deviceId#shard01). 작은 설정 테이블에 샤드 개수를 저장하고, 애플리케이션이 모든 샤드를 조회해 결과를 병합합니다. 이렇게 하면 파티션당 쓰기 용량이 고르게 분산됩니다.

데이터 보존 (TTL)

숫자형 속성 ttl = timestampEpoch + 30 days 를 추가합니다.
이 속성에 DynamoDB TTL를 활성화하면 DynamoDB가 만료된 항목을 자동으로 삭제합니다(보통 만료 후 48 시간 이내).

  • 추가 Lambda가 필요 없으므로 비용이 낮습니다.

읽기 성능 최적화

  • Projection: GSI에 필요한 속성만 보관합니다(e.g., temperature, humidity, pressure, timestamp). 읽기 크기와 비용을 줄일 수 있습니다.
  • Consistent vs. eventual reads: 대부분의 쿼리는 eventual consistency를 사용합니다(더 저렴, 4 KB당 0.5 RCU). “최신 읽기”처럼 신선도가 중요한 경우 strongly consistent 읽기를 사용합니다(4 KB당 1 RCU).
  • BatchGetItem을 활용해 여러 디바이스의 최신 읽기값을 한 번에 가져올 수 있습니다.

보조 서비스 (선택 사항)

서비스목적
AWS Kinesis Data Streams들어오는 센서 데이터를 버퍼링하고, 급증하는 쓰기를 완화하며, Lambda 소비자를 통해 DynamoDB에 전달합니다.
AWS Lambda (TTL cleanup)정확히 30일에 삭제가 필요할 경우, 예약된 Lambda가 ttl이 임박한 항목을 조회·삭제할 수 있지만 보통 DynamoDB TTL만으로 충분합니다.
Amazon CloudWatch AlarmsConsumedWriteCapacityUnits, ThrottledRequests, SystemErrors 등을 모니터링해 스케일링이나 알림을 트리거합니다.
AWS Glue / AthenaDynamoDB Streams → Lambda → S3 로 내보낸 히스토리 데이터를 S3에 저장하고, ad‑hoc 분석을 수행합니다.

트레이드오프 요약

트레이드오프영향
On‑Demand vs. ProvisionedOn‑Demand는 운영이 간단하지만, 지속적인 10 k writes/s에서는 약 30 % 더 비쌀 수 있습니다. Provisioned는 용량 계획이 필요하지만 자동 스케일링을 활용하면 비용이 낮아질 수 있습니다.
Sharding vs. SimplicitySharding은 트래픽이 편중된 디바이스에서 핫 파티션 위험을 없애지만, 쿼리 로직이 복잡해집니다(디바이스당 여러 샤드 조회).
TTL vs. Lambda cleanupTTL는 저비용이며 최대 48 시간 지연될 수 있습니다. Lambda는 정확한 삭제 시점을 제공하지만 컴퓨팅 비용이 추가됩니다.
GSI for latest reading높은 부하에서도 O(1) 읽기 지연을 보장하지만, 각 쓰기마다 GSI 업데이트 비용이 발생합니다. 대부분의 경우 기본 테이블에 Limit=1을 사용하는 것이 충분합니다.
Strong vs. eventual consistency강력 일관성 읽기는 비용이 두 배이므로, 즉시 최신성이 필요한 경우
Back to Blog

관련 글

더 보기 »

Secret scanning 업데이트 — 2025년 11월

GitHub secret scanning은 지속적으로 새로운 비밀 유형에 대한 지원을 추가하고 있습니다. 11월 한 달 동안 다음과 같은 업데이트가 이루어졌습니다. - 새로운 제공자 패턴: Sec...