개발/backend

[DynamoDB] AWS DynamoDB의 TTL(TimeToLive)기능을 사용해서 storage size관리를 자동화 해보자

나인에스 2022. 3. 17. 15:47

 


개요

AWS에서 NoSQL형태의 DB인 DynamoDB service를 제공합니다. 이는 AWS의 다른 서비스들과의 연계도 쉽고 NoSQL의 특성상 data를 내 맘대로 저장하기에 좋은 형태이고, AWS 내에서 여러 사용사례가 있기 때문에 아마도 AWS를 사용하는 시스템이라면 한번쯤 사용을 고려해보거나 이미 사용하고 있을거라 생각됩니다. DynamoDB를 이용해서 데이터를 저장, 검색하는 기본적인 DB의 기능으로 이용하거나 데이터 분석/저장을위해서 S3, AWS Athena, Glue등 여러 서비스와 연계해서 이용하기도 합니다. 그리고, 이렇게 이용한 데이터를 DynamoDB에 계속 저장해둘 필요가 없는 경우가 있고, 만약 불필요하게 계속 저장해둘 경우 비용이 발생하기 때문에 이를 위해서 데이터 삭제하는 여러 방법을 사용하는데, AWS DynamoDB에서 데이터 삭제시 비용이 발생하지 않고 자동으로 삭제하는 기능을 제공하고 이것이 바로 TTL(Time To Live) 기능 입니다.

 

 

DynamoDB 사용시 직면할 수 있는 문제!

DynamoDB의 특징 혹은 단점이라면 Item row를 삭제하기가 까다롭다는 점이 있습니다. 삭제를 할때에는 한번에 하나씩 혹은 최대 25개까지(batchWrite 기능 사용시)의 row item을 삭제할 수 있고, 이 마저도 삭제해야 하는 데이터를 조건식으로 분류하기 위한 partition key, sort key에 >, < 같은 조건식을 사용할 수 없고 정확하게 원하는 데이터 row item의 partition key와 sort key를 명시해야만 삭제할 수가 있습니다. 이 말은 만약 sort key가 auto generate되는 값이라면 삭제를 위해서 매번 query혹은 scan을 해서 list 를 가져온 다음에서야 데이터를 삭제 할 수 있다는 의미가 됩니다.

(물론 Table설계에 따라서 다를 수 있지만) 예를들어서, 여러 IoT device들을 어딘가에 설치 해두고 여기에서 수초당 한번씩 전달되는 sensor data를 누적 저장한다고 가정해봅시다. 이때 table 구성할때에 partition key는 device의 ID로 하고 sort key는 timestamp 로 해서 지속적으로 데이터를 누적하고, 다른 분석 툴에서 누적된 데이터를 시간 단위로 가져와서 분석을 하는 시스템을 구성했다고 하면, IoT device가 1만개 이상인 경우 매우 많은 데이터가 빠르게 DynamoDB에 저장되게 됩니다.

만약 위의 시스템을 계속 운영을 하면서 DynamoDB의 데이터를 삭제하지 않고 그냥 둘 경우 1년정도만 지나도 매달 수십 혹은 수백만원 수준의 DynamoDB Storage 비용이 발생하는 것을 보실수 있습니다. 때문에 위와 같은 시스템을 구성할 때에 여러 옵션기능을 사용해서 저장되어 있는 데이터의 size를 관리해야 합니다. 이를 위한 여러 방법이 있지만 여기서 상세히 다룰 내용은 아니기에 간략하게 설명하면 data pipeline을 구성해서 DynamoDB의 데이터를 S3로 보내고 보낸 데이터는 삭제하거나, Export to S3기능을 이용해서 주기적으로 데이터를 S3로 보낸후 table을 삭제/재생성하거나등의 방법이 있습니다. 

 3개월 이상 오래된 데이터는 더이상 DynamoDB에 저장해둘 필요가 없다면 이를 삭제해야 하고 삭제를 위해서는 partition key and/or sort key 범위를 이용해서 데이터를 scan or query후 불러온 데이터의 timestamp를 일일이 넣어서 한땀한땀 삭제해야하는 일이 발생합니다.. 만약 삭제해야하는 데이터가 10억개라면?? 10억번의 deleteItem을 호출하거나 batchWrite를 이용한다고해도 4천만번의 loop를 돌아야겠죠.(대충....몇날 몇일을 돌려놔야...)

따라서, 일단 매우 커진 DynamoDB의 Storage Size를 관리도 해야하고 3개월이상 된 오래된 데이터라도 미래에 어쩌면 사용될 수도 있는 경우라면 Export To S3를 이용해서 모든 데이터를 S3에 주기적으로 backup 하도록 설정해서 데이터를 보관하고, DynamoDB에 데이터를 저장할 때에 각 item에 TTL값을 저장하는 attribute와 삭제되어도 되는 시간의 timestamp  값을 추가해서 해당 시간이 지나면 자동으로 DynamoDB가 삭제하도록 해줍니다. (비용도 없이!)

이렇게 설정을 하고나면 DynamoDB의 storage size도 계속 증가하지 않기 때문에 고정된 비용이 발생하고, 데이터의 가용성에 대해서도 오래된 데이터의 경우 AWS athena와 같은 서비스를 이용해서 분석을 할 수 있고, 최근 데이터는 DynamoDB에 직접 query 통해서 검색할 수 있습니다.

 

전제 조건 (Prerequisite)

위에서 언급한것과 같이 TTL을 이용하기 위해서는 각 item에 삭제될 시간을 저장하는 attribute가 필수로 있어야 하고 해당 attribute에 삭제되는 시간을 저장해야 합니다. 그리고 이 attribute는 약간의 제약 조건이 있습니다.

  1. TTL로 사용된 attribute는 Number type이여야 하고 초단위의 Unix epoch time format 값이 저장되어 있어야 합니다. NodeJS를 예로들면 (new date()).getTime()을 이용해서 ms단위의 timestamp를 가져오고 이값을 1000으로 나눈 값을 사용하면 됩니다.만약 형식이 맞지 않는다면 TTL은 이를 무시하게 됩니다.
  2. TTL로 사용될 값은 과거 5년 이전의 값을 설정하면 안됩니다. 만약 과거 5년 이전의 값을 설정할 경우 TTL은 이 값을 무시하고 삭제 하지 않습니다.

 

설정 방법

  • AWS Console에 접속해서 DynamoDB 페이지로 이동
  • 좌측 메뉴에서 "Update Settings" -> table 선택 -> "additional settings" 선택

 

  • "Time to Live (TTL)" Tab에서 "Enable" 버튼 클릭
  • 아래 페이지에서  TTL로 사용될 table의 attribute 이름을 "TTL attribute name"에 입력
  • Preview항목에서 특정 시간에 따라 설정된 TTL에 의해 삭제되는 item을 확인 해볼 수 있다.(주의. 이때 scan을 하기 때문에 item이 많다면 시간이 오래걸릴수 있고, capacity 에 따라실패할 수도 있다.)

주의 : 한번 enable하고나면 이것을 다시 disable하기 위해서는 어느정도 시간이 지나야만 변경 할 수 있습니다.(AWS manual에 의하면 약 1시간 소요) 그래서 enable하기 전에 꼭 "Run preview" 기능을 이용해서 테스트 해보는 것을 권장합니다.

 

Ref.

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/time-to-live-ttl-before-you-start.html#time-to-live-ttl-before-you-start-formatting

 

Using DynamoDB Time to Live (TTL) - Amazon DynamoDB

Using DynamoDB Time to Live (TTL) When using TTL, most of the hard work is done behind the scenes by DynamoDB on your behalf. You should, though, be aware of a few considerations to help your implementation proceed smoothly. Formatting an item’s TTL attr

docs.aws.amazon.com