필드 수준 암호화 에는 성능 및 저장 비용이 따릅니다. 암호화하도록 선택한 모든 필드 :
삽입 및 업데이트 작업에 쓰기를 추가합니다.
MongoDB 는 쿼리 성능을 개선하기 위해 암호화됨 필드의 인덱스 를 유지하므로 추가 저장 가 필요합니다.
이 섹션에서는 컬렉션 암호화가 저장 및 쓰기 (write) 에 영향 을 요약하고, 암호화됨 컬렉션 인덱스를 압축하여 이러한 비용을 최소화하는 방법을 설명합니다. 필드를 암호화하고 쿼리를 위해 구성하려면 암호화된 필드 및 활성화된 쿼리를 참조하세요.
개요
Queryable Encryption은 무작위 암호화를 사용하여 문서의 민감한 필드를 암호화하는 동시에 암호화된 필드를 쿼리할 수 있는 기능을 도입합니다.
Queryable Encryption을 사용하면 지정된 일반 텍스트 값이 항상 다른 암호 텍스트로 암호화되면서 쿼리가 가능해집니다. 이 기능을 활성화하기 위해 Queryable Encryption은 세 가지 데이터 구조를 사용합니다.
두 개의 메타데이터 컬렉션
암호화된 collection에 있는 모든 문서의 필드입니다.
__safeContent__
경고
이러한 데이터 구조를 수정하거나 삭제하지 않는 것이 중요하며, 그렇지 않으면 쿼리 결과가 부정확해질 수 있습니다.
메타데이터 컬렉션
암호화된 collection을 생성하면 MongoDB는 두 개의 메타데이터 컬렉션을 생성합니다.
enxcol_.<collectionName>.esc~로 지칭ESCenxcol_.<collectionName>.ecoc~로 지칭ECOC
예시
" 환자 " 라는 컬렉션을 생성하는 경우 MongoDB는 다음과 같은 메타데이터 컬렉션을 생성합니다.
enxcol_.patients.escenxcol_.patients.ecoc
쿼리 가능한 암호화된 필드가 있는 문서를 삽입하면 MongoDB는 메타데이터 컬렉션을 업데이트하여 쿼리를 가능하게 하는 인덱스를 유지합니다. 해당 필드는 "인덱싱된 필드"가 됩니다. 이로 인해 해당 필드 모두에서 저장 및 쓰기 속도가 저하됩니다.
중요
암호화됨 컬렉션 을 삭제하는 경우 연결된 메타데이터 컬렉션을 즉시 삭제하세요.
enxcol_.<collectionName>.escenxcol_.<collectionName>.ecoc
그렇지 않으면 같은 이름의 컬렉션 을 다시 만들면 메타데이터 컬렉션이 충돌 상태 가 되어 과도한 저장 공간을 소비하고 CRUD 성능이 저하됩니다.
동등성 및 범위 쿼리 영향
동일성 쿼리는 저장 및 쓰기 (write) 작업에 고정된 추가 비용을 수반합니다. 범위 쿼리 비용은 쿼리 가능 필드의 매개변수 에 따라 달라집니다. 이러한 쿼리를 엄격하게 제한하면 성능 영향 이 크게 줄어듭니다.
동일성 쿼리 가능 필드에 대한 쓰기 비용
삽입 작업
문서를 삽입할 때 인덱싱된 각 필드에는 메타데이터 컬렉션에 대한 두 번의 추가 쓰기가 필요합니다.
1개의 쓰기 대상
ESC1개의 쓰기 대상
ECOC
예시
두 개의 인덱스 필드가 있는 문서를 삽입하려면 다음이 필요합니다.
암호화된 collection에 한 번 쓰기.
메타데이터 컬렉션에 네 번 쓰기.
업데이트 작업
문서를 업데이트할 때 인덱싱된 각 필드에는 메타데이터 컬렉션에 대한 두 번의 추가 쓰기가 필요합니다.
1개의 쓰기 대상
ESC1개의 쓰기 대상
ECOC
예시
두 개의 인덱스 필드가 있는 문서를 업데이트하려면 다음이 필요합니다.
암호화된 collection에 한 번 쓰기.
메타데이터 컬렉션에 네 번 쓰기.
삭제 작업
문서를 삭제할 때 인덱싱된 필드에는 추가 쓰기가 필요하지 않습니다.
동일성 쿼리 가능 필드의 저장 비용
메타데이터 압축 전에 ESC 및 ECOC 에는 인덱싱된 모든 필드 의 모든 필드 /값 쌍에 대해 하나의 메타데이터 문서 가 포함됩니다. 문서에서 암호화됨 필드/값 쌍 하나를 인덱싱하려면 1000 1000 에 문서가 ESC 필요하고 1000 에 개의 문서가 ECOC 필요합니다.
참고
모든 필드 를 암호화하는 Queryable Encryption 컬렉션 은 메타데이터 컬렉션을 설명하기 위해 저장 공간을 최대 2~3 배까지 차지할 수 있습니다. 예를 예시 1 GB 컬렉션 의 저장 요구 사항은 2~3 GB 일 수 있습니다.
모범 사례
필요하지 않은 필드는 암호화하지 마세요. 대부분의 데이터는 개인 식별 정보가 포함된 필드와 같이 일부 필드만 암호화됨 하면 됩니다.
사용자가 동일성 쿼리로 충분한 경우 필드 에서 범위 쿼리를 활성화 하지 마세요.
데이터를 모델링 하고 프로토타입을 생성하여 배포서버 를 위한 실제 저장 및 쓰기 (write) 증가를 파악합니다.
메타데이터 컬렉션 압축
문서를 삽입하거나 업데이트 하면 메타데이터 컬렉션이 변경되고 증가합니다. 메타데이터 컬렉션 압축 은 ECOC 을 비우고 ESC 의 크기를 줄입니다.
메타데이터 압축 예약
중요
최악의 경우 메타데이터 압축 을 실행 하면 이전 압축 이후 모든 문서에 삽입된 고유 필드 /값 쌍의 수가 표시됩니다.
메타데이터 압축 을 통해 공개되는 정확한 정보에 대한 자세한 내용은 MongoDB의 Queryable Encryption 기술 문서 '섹션 6: 이론적 분석' 및 '섹션 9: 가이드라인'을 참조하세요.
다음 정보를 추적 하는 것이 가장 좋습니다.
encfields: 문서 당 암호화됨 필드의 수입니다.docinserts: 마지막 압축 이후 삽입된 문서 수입니다.valinserts: 마지막 압축 이후 삽입된 고유 필드 /값 쌍의 수입니다.
ESC 메타데이터 컬렉션 의 크기를 최소 t 문서만큼 줄이려면 다음 수식이 충족될 때 메타데이터 압축 을 실행 합니다.
(encfields · docinserts) - valinserts ≥ t
문서 당 암호화됨 필드 수에 마지막 압축 이후 삽입 수를 곱한 값에서 마지막 압축 이후 모든 문서에 삽입된 고유 필드 /값 쌍의 수를 뺀 값은 다음 값에서 제거 문서 수보다 크거나 같아야 합니다. ESC.
예시
예를 예시 , 6개의 암호화됨 필드가 있는 컬렉션 에서 마지막 압축 이후 삽입된 총 문서와 삽입된 고유 필드 /값 쌍이 다음 조건을 충족하면 ESC 문서의 크기를 최소 1000 개 줄일 수 있습니다.
(6 · docinserts) - valinserts ≥ 1000
예를 예시 , 모든 문서에서 총 200 개의 고유 필드 /값 쌍이 있는 마지막 압축 이후 200 개의 문서가 삽입되었거나 마지막 압축 이후 400 문서가 700 2} 개의 문서가 삽입된 경우 공식이 충족됩니다. 고유 필드/값 쌍.
메타데이터 압축 실행
You must run metadata compaction manually. Use mongosh and run the db.collection.compactStructuredEncryptionData() command:
예시
const eDB = "encryption" const eKV = "__keyVault" const secretDB = "records" const secretCollection = "patients" const localKey = fs.readFileSync("master-key.txt") const localKeyProvider = { key: localKey } const queryableEncryptionOpts = { kmsProviders: { local: localKeyProvider }, keyVaultNamespace: `${eDB}.${eKV}`, } const encryptedClient = Mongo("localhost:27017", queryableEncryptionOpts) const encryptedDB = encryptedClient.getDB(secretDB) const encryptedCollection = encryptedDB.getCollection(secretCollection) encryptedCollection.compactStructuredEncryptionData()
{ "stats": { ... }, "ok": 1, ... }
You can check the size of a metadata collection using mongosh and running the db.collection.totalSize() command.
예시
이 예제에서 암호화된 collection의 이름은 " 환자 " 입니다.
db.enxcol_.patients.esc.totalSize()
1407960328