TTL Indexes
참고
스토리지 비용을 절약하기 위해 문서를 제거하려는 경우 MongoDB Atlas의 Online Archive를 고려해 보세요. Atlas Online Archive는 자주 액세스하지 않는 데이터를 관리형 S3 버킷에 자동으로 보관하여 비용 효율적인 데이터 계층화를 지원합니다.
TTL 인덱스는 MongoDB가 일정 시간 후 또는 특정 클럭 시간에 컬렉션에서 문서를 자동으로 제거하는 데 사용할 수 있는 특수 단일 필드 인덱스입니다. 데이터 만료는 시스템에서 생성한 이벤트 데이터, 로그, 세션 정보 등 데이터베이스에 한정된 기간 동안만 유지되는 특정 유형의 정보에 유용합니다.
MongoDB Atlas에서 호스팅되는 배포를 위해 UI에서 TTL 인덱스를 생성하고 관리할 수 있습니다.
TTL 인덱스 만들기
경고
TTL 인덱스를 생성한 후에는 한 번에 삭제할 적격 문서가 매우 많을 수 있습니다. 이러한 대규모 작업 부하로 인해 서버 성능 문제가 발생할 수 있습니다. 이러한 문제를 방지하려면 업무 외 시간에 색인을 만들거나, 향후 문서에 대한 색인을 만들기 전에 적격 문서를 일괄 삭제하도록 계획하세요.
TTL 인덱스를 생성하려면 createIndex()
를 사용합니다. 날짜 유형 또는 날짜 유형 값을 포함하는 배열인 인덱스 필드를 지정합니다. expireAfterSeconds
옵션을 사용하여 TTL 값을 초 단위로 지정합니다.
TTL 인덱스 expireAfterSeconds
값은 0
과 2147483647
사이여야 합니다.
예를 들어 eventlog
컬렉션의 lastModifiedDate
필드에 TTL 값이 3600
초인 TTL 인덱스를 만들려면 mongosh
의 다음 연산을 사용합니다.
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
MongoDB 6.3부터는 시계열 컬렉션에 부분 TTL 인덱스를 생성할 수 있습니다. 이 인덱스는 timeField
컬렉션을 키 필드로 사용하며 metaField
에 부분 필터 표현식이 필요합니다.
time series 컬렉션에는 선택 사항인 expireAfterSeconds
필드가 포함됩니다. expireAfterSeconds
를 설정하지 않는 경우 partialFilterExpression
이 있는 TTL 인덱스를 통해 필터와 일치하는 문서의 만료 기간을 설정할 수 있습니다. expireAfterSeconds
를 설정하면 부분 TTL 인덱스를 통해 일치하는 문서에 대해 다른 짧은 만료 기간을 설정할 수 있습니다. metaField
에 대해서만 partialFilterExpression
을 만들 수 있습니다.
중요
컬렉션의 expireAfterSeconds
값이 부분 TTL 색인의 expireAfterSeconds
보다 낮으면 컬렉션은 더 짧은 시간 후에 문서를 삭제하므로 TTL 색인은 효과가 없습니다.
시계열 컬렉션에 1970-01-01T00:00:00.000Z
이전 또는 2038-01-19T03:14:07.000Z
이후에 timeField
타임스탬프가 있는 문서가 포함된 경우 TTL " time to live " 기능을 사용하여 컬렉션에서 문서를 삭제하지 않습니다.
이 날씨 데이터 시계열 컬렉션은 24시간 후에 문서를 삭제합니다.
db.createCollection( "weather24h", { timeseries: { timeField: "timestamp", metaField: "sensor", granularity: "hours" }, expireAfterSeconds: 86400 } )
이 TTL 인덱스는 24시간이 아닌 1시간 후에 MongoDB NYC 본사 기상 센서에서 문서를 삭제합니다.
db.eventlog.createIndex( { "timestamp": 1 }, { partialFilterExpression: { "sensor": { $eq: "40.761873, -73.984287" } } }, { expireAfterSeconds: 3600 } )
비 TTL 단일 필드 인덱스를 TTL 인덱스로 변환하기
MongoDB 5.1부터 기존 단일 필드 인덱스에 expireAfterSeconds
옵션을 추가할 수 있습니다. TTL이 아닌 단일 필드 인덱스를 TTL 인덱스로 변경하려면 collMod
데이터베이스 명령을 사용합니다.
db.runCommand({ "collMod": <collName>, "index": { "keyPattern": <keyPattern>, "expireAfterSeconds": <number> } })
다음 예에서는 패턴이 { "lastModifiedDate": 1 }
인 비 TTL 단일 필드 인덱스를 TTL 인덱스로 변환합니다.
db.runCommand({ "collMod": "tickets", "index": { "keyPattern": { "lastModifiedDate": 1 }, "expireAfterSeconds": 100 } })
TTL 인덱스의 값을변경합니다.expireAfterSeconds
TTL 인덱스의 expireAfterSeconds
값을 변경하려면 collMod
데이터베이스 명령을 사용합니다.
db.runCommand({ "collMod": <collName>, "index": { "keyPattern": <keyPattern>, "expireAfterSeconds": <number> } })
다음 예에서는 tickets
컬렉션에서 { "lastModifiedDate": 1 }
패턴을 사용하여 색인의 expireAfterSeconds
값을 변경합니다.
db.runCommand({ "collMod": "tickets", "index": { "keyPattern": { "lastModifiedDate": 1 }, "expireAfterSeconds": 100 } })
중요
TTL 인덱스의 expireAfterSeconds
매개변수를 업데이트하기 전에 다음을 고려하세요.
expireAfterSeconds
매개변수를 변경해도 전체 인덱스 재구축이 트리거되지 않습니다. 그러나expireAfterSeconds
값을 줄이면 많은 문서를 즉시 삭제할 수 있으므로 삭제 작업 증가로 인해 성능 문제가 발생할 수 있습니다.권장되는 방법은 TTL 인덱스를 업데이트하기 전에 문서를 소량으로 나누어 수동으로 삭제하는 것입니다. 이는 클러스터에 미치는 영향을 제어하는 데 도움이 됩니다.
많은 문서를 삭제하면 스토리지 파일이 조각화되어 성능에 영향을 미칠 수 있습니다. 컬렉션에 대해 압축 명령을 실행하거나 초기 동기화를 수행하여 공간을 회수하고 스토리지를 최적화해야 할 수도 있습니다.
행동
데이터 만료
TTL 인덱스는 인덱스된 필드 값 이후 지정된 시간(초)이 지나면 문서를 만료합니다. 만료 임계값은 인덱싱된 필드 값에 지정된 시간(초)을 더한 값입니다.
필드가 배열이고 인덱스에 여러 날짜 값이 있는 경우 MongoDB는 만료 임계값을 계산하기 위해 배열의 가장 낮은(가장 빠른) 날짜 값을 사용합니다.
시계열 컬렉션의 경우 TTL 인덱스는 내부의 모든 문서가 만료되면 데이터 버킷도 제거합니다. 이는 버킷의 타임스탬프 상한에 expireAfterSeconds
값을 더한 것과 같습니다. 예를 들어 버킷이 2023-03-27T18:29:59Z
까지 데이터를 포함하고 expireAfterSeconds
가 300인 경우 TTL 색인은 2023-03-27T18:34:59Z
이후에 버킷을 만료합니다.
문서 의 인덱스 필드 에 하나 이상의 날짜 값이 포함되어 있지 않으면 문서 가 만료되지 않습니다.
문서에 색인된 필드가 포함되어 있지 않으면 문서는 만료되지 않습니다.
삭제 작업
mongod
의 백그라운드 스레드는 인덱스의 값을 읽고 컬렉션에서 만료된 문서를 제거합니다.
TTL 스레드에서 수행한 진행 중 삭제 작업이 db.currentOp()
출력에 나타납니다. TTL 스레드가 문서를 삭제하면 metrics.ttl.deletedDocuments
서버 상태 지표가 증가합니다.
MongoDB 6.1부터 도입됨:
효율성을 높이기 위해 MongoDB는 여러 문서를 일괄 삭제할 수 있습니다.
explain
2} 명령 결과에는BATCHED_DELETE
문서 일괄 삭제를 위한 새로운 단계가 포함되어 있습니다.
시계열 컬렉션에 1970-01-01T00:00:00.000Z
이전 또는 2038-01-19T03:14:07.000Z
이후에 timeField
타임스탬프가 있는 문서가 포함된 경우 TTL " time to live " 기능을 사용하여 컬렉션에서 문서를 삭제하지 않습니다.
삭제 프로세스
TTL 백그라운드 삭제 프로세스는 각 TTL 인덱스에서 만료된 문서를 확인합니다. 각 TTL 인덱스에 대해 백그라운드 프로세스는 다음 조건 중 하나가 충족될 때까지 문서를 삭제합니다.
이 프로세스는 현재 인덱스에서 50000개의 문서를 삭제합니다.
이 프로세스는 현재 인덱스에서 문서를 삭제하는 데 약 1초가 소요됩니다.
만료된 모든 문서는 현재 인덱스에서 삭제됩니다.
그런 다음 프로세스는 다음 인덱스로 이동합니다. 프로세스가 각 TTL 인덱스를 한 번씩 거치면 현재 하위 패스가 완료되며 남아 있는 만료된 문서를 확인하기 위한 새로운 하위 패스가 시작됩니다. TTL 모니터가 모든 TTL 인덱스에서 삭제 가능한 모든 후보 문서를 삭제하면 하나의 패스가 완료됩니다.
또한 프로세스는 현재 삭제 루프를 60초마다 중지하여 한 번의 대규모 삭제에 너무 많은 시간을 소비하지 않도록 합니다. 이 경우 현재 하위 패스가 종료되고 새 하위 패스가 시작됩니다.
패스와 하위 패스는 각각 metrics.ttl.passes
및 metrics.ttl.subPasses
서버 상태 지표에서 추적됩니다.
삭제 작업의 타이밍
MongoDB는 프라이머리 인덱스에서 인덱스 빌드가 완료되는 즉시 만료된 문서나 Time Series 버킷을 제거하기 시작합니다. 인덱스 빌드 프로세스에 대한 자세한 내용은 채워진 컬렉션에 대한 인덱스 빌드를 참조하세요.
TTL 인덱스는 만료된 데이터가 만료 즉시 삭제된다는 것을 보장하지 않습니다. 문서가 만료되는 시간과 MongoDB가 데이터베이스에서 문서를 제거하는 시점 사이에는 지연이 있을 수 있습니다.
만료된 문서를 제거하는 백그라운드 작업은 60초마다 실행됩니다. 결과적으로 문서 만료 시점과 백그라운드 작업 실행 시점 사이의 기간 동안 문서가 컬렉션에 남아 있을 수 있습니다. 색인이 완료된 후 0~60초 후에 MongoDB가 문서 삭제를 시작합니다.
제거 작업 기간은 mongod
인스턴스의 워크로드에 따라 달라지므로 만료된 데이터가 백그라운드 작업의 실행 간격인 60초를 초과하는 기간 동안 존재할 수 있습니다.
TTL 작업에 의해 시작된 삭제 작업은 다른 삭제와 마찬가지로 포그라운드에서 실행됩니다.
복제본 세트
복제본 집합 멤버에서 TTL 백그라운드 스레드는 멤버가 기본 상태일 때만 문서를 삭제합니다. TTL 백그라운드 스레드는 멤버가 보조 상태일 때 유휴 상태입니다. 보조 구성원은 기본 구성원의 삭제 작업을 복제합니다.
Support for Queries
TTL 인덱스는 비TTL 인덱스와 동일한 방식으로 쿼리를 지원합니다.
독립형 모드의 mongod
TTL 모니터는 mongod
가 독립형 모드에서 실행되고 system.local.replset
컬렉션에 데이터가 포함된 경우 중지됩니다. 복제본 세트에서 복제본 세트 노드를 가져와 독립형으로 실행하면 TTL 모니터가 비활성화됩니다.
제한 사항
TTL 인덱스는 단일 필드 인덱스입니다. 복합 인덱스는 TTL을 지원하지 않으며
expireAfterSeconds
옵션을 무시합니다._id
필드는 TTL 인덱스를 지원하지 않습니다.MongoDB 7.0부터는 time series 컬렉션의
metaField
에 대한 부분 TTL 인덱스를 만들 수 있습니다. 이전 MongoDB 버전에서는 time series 컬렉션의timeField
에 대해서만 TTL 인덱스를 만들 수 있습니다.기존 인덱스의
expireAfterSeconds
값을 변경하기 위해createIndex()
를 사용할 수 없습니다. 대신collMod
데이터베이스 명령을 사용하세요. 자세한 내용은 TTL 인덱스의expireAfterSeconds
값 변경을 참조하세요.필드에 대해 TTL이 아닌 단일 필드 인덱스가 이미 존재하는 경우 키 사양이 같고 옵션만 다른 인덱스는 만들 수 없으므로 동일한 필드에 TTL 인덱스를 만들 수 없습니다. TTL이 아닌 단일 필드 인덱스를 TTL 인덱스로 변경하려면
collMod
데이터베이스 명령을 사용하세요.