暗号化されたコレクション
項目一覧
フィールドレベルの暗号化にはパフォーマンスとストレージのコストが伴います。 暗号化することを選択したすべてのフィールド:
挿入操作とアップデート操作に書込み (write) を追加します。
MongoDB はクエリのパフォーマンスを向上させるために暗号化されたフィールドのインデックスを維持するため、追加のストレージが必要です。
このセクションでは、コレクションを暗号化することによるストレージと書込みへの影響をまとめ、これらのコストを最小限に抑えるために暗号化されたコレクションインデックスを圧縮する方法について説明します。 フィールドを暗号化し、クエリ用に構成する場合は、「 暗号化されたフィールドと有効なクエリ 」を参照してください。
Overview
Queryable Encryption では、ランダム化された暗号化を使用してドキュメント内の機密フィールドを暗号化する機能が導入されていますが、暗号化されたフィールドには引き続きクエリを実行できます。
Queryable Encryption を使用すると、特定のプレーンテキスト値は常に別の暗号化に暗号化されますが、クエリ可能な状態のままになります。 この機能を有効にするために、Queryable Encryption は 3 つのデータ構造を使用します。
2 つのメタデータ コレクション
暗号化されたコレクション内のすべてのドキュメントのフィールド
__safeContent__
警告
これらのデータ構造を変更または削除しないことが重要です。クエリ結果が不正確になるためです。
メタデータコレクション
暗号化されたコレクションを作成すると、MongoDB は 2 つのメタデータコレクションを作成します。
enxcol_.<collectionName>.esc
と呼ばれるESC
enxcol_.<collectionName>.ecoc
と呼ばれるECOC
例
「可能性」というコレクションを作成すると、MongoDB により次のメタデータ コレクションが作成されます。
enxcol_.patients.esc
enxcol_.patients.ecoc
クエリ可能な暗号化されたフィールドを持つドキュメントを挿入すると、MongoDB はメタデータコレクションを更新して、クエリを有効なインデックスを維持します。 フィールドは「インデックス付きフィールド」になります。 これにより、ストレージとフィールドごとにストレージと書込み速度がコストされます。
重要
暗号化されたコレクションを削除する と、その直後に関連するメタデータのコレクションを削除します。
enxcol_.<collectionName>.esc
enxcol_.<collectionName>.ecoc
それ以外の場合、同じ名前でコレクションを再作成すると、メタデータコレクションが競合状態になり、過剰なストレージ領域が消費され、 CRUDパフォーマンスが低下します。
等価クエリと範囲クエリの影響
等価クエリには、ストレージと書込み操作に固定の追加コストが伴います。 範囲クエリのコストは、クエリ可能なフィールドのパラメーターによって異なります。 これらのクエリを厳密に制限すると、 パフォーマンスへの影響が大幅に軽減されます。
等価クエリ可能なフィールドの書込みコスト
挿入操作
ドキュメントを挿入する場合、インデックス付きフィールドごとにメタデータ コレクションへの追加の書込み (write) が必要です。
への 1 つの書き込み
ESC
への 1 つの書き込み
ECOC
例
2 つのインデックス付きフィールドを持つドキュメントを挿入するには、次のことが必要です。
暗号化されたコレクションへの 1 回の書込み。
メタデータ コレクションへの 4 回の書込み。
アップデート操作
ドキュメントを更新する場合、インデックス付きフィールドごとにメタデータ コレクションへの追加の書込み (write) が必要です。
への 1 つの書き込み
ESC
への 1 つの書き込み
ECOC
例
2 つのインデックス付きフィールドを持つドキュメントを更新するには、次の操作が必要です。
暗号化されたコレクションへの 1 回の書込み。
メタデータ コレクションへの 4 回の書込み。
削除操作
ドキュメントを削除する場合、インデックス フィールドでは追加の書込み (write) は必要ありません。
等価クエリ可能なフィールドのストレージ コスト
メタデータ圧縮の前に、 ESC
とECOC
には、すべてのインデックス付きフィールドの各フィールドと値のペアに対して 1 つのメタデータドキュメントが含まれます。 1000ドキュメント全体で 1 つの暗号化されたフィールドと値のペアのインデックスを作成するには、 ESC
に1000ドキュメントとECOC
に1000ドキュメントが必要です。
注意
すべてのフィールドを暗号化するQueryable Encryptionコレクションは、メタデータコレクションを考慮して、ストレージ領域の最大2 - 3倍を要求します。 例、 1 GBコレクションには、 2 - 3 GBのストレージ要件がある場合があります。
ベストプラクティス
暗号化が必要ないフィールドは暗号化しないでください。 ほとんどのデータでは、個人を特定できる情報を含むフィールドの少数のサブセットのみが暗号化されます。
等価クエリで十分なユーザーは、フィールドで範囲クエリを有効にしないでください。
範囲クエリが有効になっている暗号化フィールドの場合は、フィールド構成、特に最小値、最大値、精度のパラメーターを確認します。 範囲クエリに厳密な境界を設定すると、それらのフィールドのパフォーマンスへの影響が大幅に軽減されます。
データをモデル化してプロトタイプを作成し、配置における実際のストレージと書込みの増加を判断します。
メタデータコレクションの圧縮
ドキュメントを挿入またはアップデートすると、メタデータコレクションが変更され、大きくなります。 メタデータコレクションを圧縮すると、 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による最後の圧縮以降に挿入されていた場合は、 式は満たされます。 一意のフィールドと値のペア。
メタデータ圧縮の実行
メタデータの圧縮は手動で実行する必要があります。 mongosh
を使用し、 db.collection.compactStructuredEncryptionData()
コマンドを実行します。
例
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, ... }
メタデータコレクションのサイズは、 mongosh
とdb.collection.totalSize()
コマンドを実行中して確認できます。
例
この例では、暗号化されたコレクションの名前は「patients」です。
db.enxcol_.patients.esc.totalSize()
1407960328