변경 스트림
이 페이지의 내용
변경 스트림을 사용하면 애플리케이션이 oplog 를 수동으로 테일링해야 하는 복잡성과 위험 없이 실시간 데이터 변경 사항에 액세스할 수 있습니다. 애플리케이션은 변경 스트림을 사용하여 단일 컬렉션, 데이터베이스 또는 전체 배포의 모든 데이터 변경 사항을 구독하고 즉시 대응할 수 있습니다. 변경 스트림은 애그리게이션 프레임워크를 사용하기 때문에 애플리케이션에서 특정 변경 사항을 필터링하거나 알림을 마음대로 변환할 수도 있습니다.
MongoDB 5.1부터는 change stream이 최적화되어 더 효율적인 리소스 사용률과 일부 aggregation pipeline 단계의 더 빠른 실행을 제공합니다.
가용성
변경 스트림은 복제본 세트 및 샤드 클러스터에 사용할 수 있습니다:
스토리지 엔진
복제본 세트와 샤드 클러스터는 WiredTiger 스토리지 엔진을 사용해야 합니다. Change Stream은 MongoDB의 미사용 데이터 암호화 기능을 사용하는 배포에서도 사용할 수 있습니다.
복제본 세트 프로토콜 버전.
복제본 세트와 샤드 클러스터는 복제본 세트 프로토콜 버전 1(
pv1
)를 사용해야 합니다.읽기 고려 '대다수' 활성화
MongoDB 4.2부터는
"majority"
읽기 고려 지원 여부와 관계없이 변경 스트림을 사용할 수 있습니다. 읽기 고려majority
지원은 활성화(기본값)하거나 비활성화하여 변경 스트림을 사용할 수 있습니다.MongoDB 4.0 이하 버전에서는
"majority"
읽기 고려 지원을 (기본값으로) 사용하도록 설정한 경우에만 변경 스트림을 사용할 수 있습니다.
연결
변경 스트림에 대한 연결은 +srv
연결 옵션과 함께 DNS 시드 목록을 사용하거나 연결 문자열에 서버를 개별적으로 나열하여 사용할 수 있습니다.
드라이버가 변경 스트림에 대한 연결을 잃거나 연결이 다운되면 클러스터 내 읽기 설정이 일치하는 다른 노드를 통해 변경 스트림에 대한 연결을 다시 설정하려고 시도합니다. 드라이버가 올바른 읽기 설정을 가진 노드를 찾을 수 없으면 예외가 발생합니다.
자세한 내용은 연결 문자열 URI 형식을 참조하세요.
컬렉션, 데이터베이스 또는 배포 보기
다음에 대한 change stream을 열 수 있습니다.
대상 | 설명 |
---|---|
컬렉션 | 단일 컬렉션( 이 페이지의 예제에서는 MongoDB 드라이버를 사용하여 단일 컬렉션에 대해 변경 스트림 커서를 열고 작업합니다. |
데이터베이스 | MongoDB 4.0부터 단일 데이터베이스( MongoDB 드라이버 메서드에 대해서는 드라이버 설명서를 참조하세요. |
배포 | MongoDB 4.0부터는 배포서버(복제본 세트 또는 샤드 클러스터)에 대한 change stream 커서를 열어 MongoDB 드라이버 메서드에 대해서는 드라이버 설명서를 참조하세요. |
참고
Change Stream 예시
이 페이지의 예제에서는 컬렉션에 대한 변경 스트림 커서를 열고 변경 스트림 커서로 작업하는 방법을 설명하기 위해 MongoDB 드라이버를 사용합니다.
Change Stream 성능 고려 사항
데이터베이스에 대해 열려 있는 변경 스트림의 양이 연결 풀 크기를 초과할 경우 알림 지연이 발생할 수 있습니다. 각 변경 스트림은 다음 이벤트를 기다리는 시간 동안 변경 스트림에 대한 연결과 GetMore 작업을 사용합니다. 지연 시간 문제를 방지하려면 풀 크기가 열려 있는 변경 스트림 수보다 큰지 확인해야 합니다. 자세한 내용은 MaxPoolSize 설정을 참조하세요.
Change Stream 열기
변경 스트림을 열려면 다음을 수행합니다.
복제본 세트의 경우 데이터 보유 멤버 중 하나에서 변경 스트림 열기 작업을 실행할 수 있습니다.
샤드 클러스터의 경우
mongos
에서 변경 스트림 열기 작업을 실행해야 합니다.
다음 예시는 컬렉션에 대한 변경 스트림을 열고 커서를 반복하여 변경 스트림 문서를 조회합니다. [1]
➤ 오른쪽 상단의 언어 선택 드롭다운 메뉴를 사용하여 이 페이지에 있는 예제의 언어를 설정하세요.
커서에서 데이터 변경 이벤트를 조회하려면 변경 스트림 커서를 반복합니다. 변경 스트림 이벤트에 대한 자세한 내용은 Change Events를 참조하세요.
변경 스트림 커서 는 다음 중 하나가 발생할 때까지 열린 상태로 유지됩니다.
커서가 명시적으로 닫힙니다.
무효화 이벤트가 발생합니다. 예를 들어 컬렉션 삭제 또는 이름 바꾸기가 있습니다.
MongoDB 배포에 대한 연결이 닫히거나 시간 초과됩니다. 자세한 내용은 Cursor Behaviors를 참조하십시오.
배포가 분할된 클러스터인 경우 분할 제거로 인해 열린 변경 스트림 커서가 닫힐 수 있으며 닫힌 변경 스트림 커서가 완전히 재개되지 않을 수 있습니다.
참고
닫히지 않은 커서의 라이프사이클은 언어에 따라 다릅니다.
[1] | MongoDB 4.0부터 startAtOperationTime 을 지정하여 특정 시점에 커서를 열 수 있습니다. 지정된 시작점이 과거인 경우 oplog의 시간 범위 내에 있어야 합니다. |
Change Stream 출력 수정
➤ 오른쪽 상단의 언어 선택 드롭다운 메뉴를 사용하여 이 페이지에 있는 예제의 언어를 설정하세요.
팁
변경 스트림 이벤트 문서의 _id 필드는 재개 토큰 역할을 합니다. 변경 스트림 이벤트의 _id
필드를 수정하거나 제거하기 위해 파이프라인을 사용하지 마세요.
MongoDB 4.2부터는 변경 스트림 집계 파이프라인이 이벤트의 _id 필드를 수정하는 경우 변경 스트림이 예외를 발생시킵니다.
변경 스트림 응답 문서 형식에 대한 자세한 내용은 Change Events를 참조하세요.
업데이트 작업에 대한 전체 문서 조회
기본적으로 변경 스트림은 업데이트 작업 중에 필드의 델타만 반환합니다. 그러나 업데이트된 문서의 가장 최근 과반수 커밋 버전을 반환하도록 변경 스트림을 구성할 수 있습니다.
➤ 오른쪽 상단의 언어 선택 드롭다운 메뉴를 사용하여 이 페이지에 있는 예제의 언어를 설정하세요.
참고
업데이트 작업 후, 조회 전에 업데이트된 문서를 수정한 대다수 커밋 작업이 하나 이상 있는 경우 반환되는 전체 문서가 업데이트 작업 시점의 문서와 크게 다를 수 있습니다.
그러나 변경 스트림 문서에 포함된 델타는 항상 해당 변경 스트림 이벤트에 적용된 감시 대상 컬렉션 변경 사항을 정확하게 설명합니다.
변경 스트림 응답 문서 형식에 대한 자세한 내용은 Change Events를 참조하세요.
변경 스트림 다시 시작
변경 스트림은 커서를 열 때 재개 토큰을 resumeAfter 또는 startAfter로 지정하여 재개할 수 있습니다.
resumeAfter
변경 스트림의 경우
커서를 여는 시점에 재개(resume) 토큰을 resumeAfter
에 전달하여 특정 이벤트 이후에 변경 스트림을 재개할 수 있습니다.
재개 토큰에 대한 자세한 내용은 재개 토큰을 참조하세요.
중요
타임스탬프가 과거에 있었던 경우, oplog에 토큰 또는 타임스탬프와 관련된 작업을 찾을 수 있는 충분한 기록이 있어야 합니다.
무효화 이벤트(예시: 컬렉션 제거 또는 이름 바꾸기)로 인해 스트림이 닫힌 후에는
resumeAfter
를 사용하여 변경 스트림을 다시 시작할 수 없습니다. 대신 무효화 이벤트 후 startAfter를 사용하여 새 변경 스트림을 시작할 수 있습니다.
startAfter
변경 스트림의 경우
커서를 여는 시점에 재개(resume) 토큰을 startAfter
에 전달하여 특정 이벤트 이후에 새로운 변경 스트림을 시작할 수 있습니다. restartAfter 와 달리 startAfter
는 새로운 변경 스트림을 생성하여 무효화 이벤트 후에 알림을 재개할 수 있습니다.
재개 토큰에 대한 자세한 내용은 재개 토큰을 참조하세요.
중요
타임스탬프가 과거에 있었던 경우, oplog에 토큰 또는 타임스탬프와 관련된 작업을 찾을 수 있는 충분한 기록이 있어야 합니다.
토큰 재개
재개 토큰은 여러 출처에서 사용할 수 있습니다.
MongoDB 4.2부터는 변경 스트림 집계 파이프라인이 이벤트의 _id 필드를 수정하는 경우 변경 스트림이 예외를 발생시킵니다.
팁
MongoDB는 16진수로 인코딩된 재개 토큰을 mongosh
디코딩하는 확장 " 스니펫 " 을 제공합니다.
재개 토큰 을(를) 설치하고 실행할 수 있습니다. 의 mongosh
스니펫:
snippet install resumetoken decodeResumeToken('<RESUME TOKEN>')
시스템에 npm
(이)가 설치되어 있는 경우 명령줄에서 (mongosh
(을)를 사용하지 않고)resumetoken을 실행할 수도 있습니다.
npx mongodb-resumetoken-decoder <RESUME TOKEN>
자세한 내용은 다음을 참조하세요.
변경 이벤트에서 토큰 재개
변경 이벤트 알림은 _id
필드에 재개 토큰을 포함합니다.
{ "_id": { "_data": "82635019A0000000012B042C0100296E5A1004AB1154ACACD849A48C61756D70D3B21F463C6F7065726174696F6E54797065003C696E736572740046646F63756D656E744B65790046645F69640064635019A078BE67426D7CF4D2000004" }, "operationType": "insert", "clusterTime": Timestamp({ "t": 1666193824, "i": 1 }), "collectionUUID": new UUID("ab1154ac-acd8-49a4-8c61-756d70d3b21f"), "wallTime": ISODate("2022-10-19T15:37:04.604Z"), "fullDocument": { "_id": ObjectId("635019a078be67426d7cf4d2"'), "name": "Giovanni Verga" }, "ns": { "db": "test", "coll": "names" }, "documentKey": { "_id": ObjectId("635019a078be67426d7cf4d2") } }
에서 토큰 재개 aggregate
aggregate
명령을 사용하는 경우 $changeStream
애그리게이션 단계에서 cursor.postBatchResumeToken
필드에 재개 토큰을 포함합니다:
{ "cursor": { "firstBatch": [], "postBatchResumeToken": { "_data": "8263515EAC000000022B0429296E1404" }, "id": Long("4309380460777152828"), "ns": "test.names" }, "ok": 1, "$clusterTime": { "clusterTime": Timestamp({ "t": 1666277036, "i": 1 }), "signature": { "hash": Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0), "keyId": Long("0") } }, "operationTime": Timestamp({ "t": 1666277036, "i": 1 }) }
에서 토큰 재개 getMore
getMore
명령은 cursor.postBatchResumeToken
필드에 재개 토큰을 포함합니다.
{ "cursor": { "nextBatch": [], "postBatchResumeToken": { "_data": "8263515979000000022B0429296E1404" }, "id": Long("7049907285270685005"), "ns": "test.names" }, "ok": 1, "$clusterTime": { "clusterTime": Timestamp( { "t": 1666275705, "i": 1 } ), "signature": { "hash": Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0), "keyId": Long("0") } }, "operationTime": Timestamp({ "t": 1666275705, "i": 1 }) }
사용 사례
변경 스트림은 데이터 변경이 지속되면 다운스트림 시스템에 알려주므로 비즈니스 시스템에 의존하는 아키텍처에 도움이 될 수 있습니다. 예를 들어, 변경 스트림은 개발자가 추출, 변환 및 로드(ETL) 서비스, 플랫폼 간 동기화, 협업 기능 및 알림 서비스를 구현할 때 시간을 절약할 수 있습니다.
액세스 제어
특정 컬렉션에 대한 변경 스트림을 열려면 애플리케이션에 해당 컬렉션에 대해
changeStream
및find
조치를 부여할 수 있는 권한이 있어야 합니다.{ resource: { db: <dbname>, collection: <collection> }, actions: [ "find", "changeStream" ] } 단일 데이터베이스에서 변경 스트림을 열려면 애플리케이션에 데이터베이스의 모든 비
system
컬렉션에 대해changeStream
및find
작업을 수행할 수 있는 권한이 있어야 합니다.{ resource: { db: <dbname>, collection: "" }, actions: [ "find", "changeStream" ] } 전체 배포에서 change stream을 열려면 애플리케이션에 배포의 모든 데이터베이스에 대해
system
이 아닌 모든 collection에 대해changeStream
및find
조치를 허용하는 권한이 있어야 합니다.{ resource: { db: "", collection: "" }, actions: [ "find", "changeStream" ] }
이벤트 알림
변경 스트림은 복제본 집합에 있는 대부분의 데이터 보유 멤버에 지속된 데이터 변경 내용에 대해서만 알립니다. 이렇게 하면 오류 시나리오에서 지속적인 대다수 커밋 변경 사항에 대해서만 알림이 트리거됩니다.
예를 들어 프라이머리에 대해 열린 change stream 커서가 있는 3-노드 복제본 세트가 있다고 가정해 봅시다. 클라이언트가 삽입 연산을 실행하는 경우 change stream은 해당 삽입이 대부분의 데이터 보유 노드에 지속된 경우에만 애플리케이션에 데이터 변경을 알립니다.
작업이 트랜잭션과 연결된 경우, 변경 이벤트 문서에 txnNumber
및 lsid
가 포함됩니다.
데이터 정렬
변경 스트림은 명시적인 데이터 정렬이 제공되지 않는 한 simple
이진 비교를 사용합니다.
스트림 및 고아 문서 변경
MongoDB 5.3부터는 범위 마이그레이션 중에 고아 문서에 대한 업데이트에 대한 변경 스트림 이벤트가 생성되지 않습니다.
전후 이미지를 포함하는 문서의 Change Streams
MongoDB 6.0부터는 변경 스트림 이벤트를 사용하여 문서의 변경 전후 버전(문서의 전후 이미지)을 출력할 수 있습니다.
사전 이미지는 문서가 교체, 업데이트 또는 삭제되기 전의 문서입니다. 삽입된 문서에는 사전 이미지가 없습니다.
사후 이미지는 문서가 삽입, 교체, 업데이트된 후의 문서입니다. 삭제된 문서에 대한 사후 이미지가 없습니다.
db.createCollection()
,create
또는collMod
을(를) 사용하는 컬렉션에 대해changeStreamPreAndPostImages
을(를) 활성화하세요.
이미지가 다음과 같은 경우 change stream 이벤트에 사전 및 사후 이미지를 사용할 수 없습니다.
문서 업데이트 또는 삭제 작업 시 collection에서 활성화되지 않았습니다.
expireAfterSeconds
에서 전후 이미지 보존 시간 설정 이후에 제거됩니다.다음 예시에서는 전체 클러스터에서
expireAfterSeconds
를100
초로 설정합니다.use admin db.runCommand( { setClusterParameter: { changeStreamOptions: { preAndPostImages: { expireAfterSeconds: 100 } } } } ) 다음 예제에서는
expireAfterSeconds
등 현재changeStreamOptions
설정을 반환합니다.db.adminCommand( { getClusterParameter: "changeStreamOptions" } ) expireAfterSeconds
를off
로 설정하면 기본 보존 정책이 사용되며, 해당 change stream 이벤트가 oplog에서 제거될 때까지 사전 및 사후 이미지가 보존됩니다.change stream 이벤트가 oplog에서 제거되면
expireAfterSeconds
사전 및 사후 이미지 보존 시간에 관계없이 해당 사전 및 사후 이미지도 삭제됩니다.
추가 고려 사항
전후 이미지를 활성화하면 저장 공간이 소모되고 처리 시간이 늘어납니다. 필요한 경우에만 전후 이미지를 활성화하세요.
변경 스트림 이벤트 크기를 16메가바이트 미만으로 제한합니다. 이벤트 크기를 제한하려면 다음을 수행하면 됩니다.
문서 크기를 8메가바이트로 제한합니다.
updateDescription
과 같은 다른 change stream 이벤트 필드가 크지 않은 경우 change stream 출력에서 사전 및 사후 이미지를 동시에 요청할 수 있습니다.updateDescription
과 같은 다른 change stream 이벤트 필드가 크지 않은 경우 최대 16메가바이트 문서에 대해 change stream 출력에서 사후 이미지만 요청합니다.다음과 같은 경우 최대 16메가바이트의 문서에 대해 change stream 출력에서 사전 이미지만 요청합니다.
문서 업데이트가 문서 구조나 내용의 작은 부분에만 영향을 미칩니다. 그리고
replace
변경 이벤트를 발생시키지 않습니다.replace
이벤트에는 항상 후이미지가 포함됩니다.
사전 이미지를 요청하려면
db.collection.watch()
에서fullDocumentBeforeChange
를required
또는whenAvailable
로 설정합니다. 사후 이미지를 요청하려면 동일한 방법으로fullDocument
를 설정합니다.사전 이미지가
config.system.preimages
컬렉션에 기록됩니다.config.system.preimages
collection은 커질 수 있습니다. collection 크기를 제한하려면 앞서 표시된 대로 사전 이미지에 대해expireAfterSeconds
시간을 설정할 수 있습니다.사전 이미지는 백그라운드 프로세스가 비동기적으로 제거합니다.
중요
이전 버전과 호환되지 않는 기능
MongoDB 6.0부터는 change stream에 문서 사전 및 사후 이미지를 사용하는 경우 이전 MongoDB 버전으로 다운그레이드하기 전에 collMod
명령을 사용하여 각 collection에 대해 changeStreamPreAndPostImages를 비활성화해야 합니다.
팁
다음도 참조하세요.
변경 스트림 이벤트 및 출력에 대해서는 변경 이벤트를 참조하세요.
컬렉션에서 변경 사항을 확인하려면
db.collection.watch()
를 참조하세요.변경 스트림 출력에 대한 전체 예시는 전후 이미지를 포함하는 문서의 Change Streams를 참조하세요.
변경 스트림 출력에 대한 전체 예시는 전후 이미지를 포함하는 문서의 Change Streams를 참조하세요.