Kunci partisi hierarkis di Azure Cosmos DB

BERLAKU UNTUK: NoSQL

Azure Cosmos DB mendistribusikan data Anda di seluruh partisi logis dan fisik berdasarkan kunci partisi Anda untuk mendukung penskalaan horizontal. Dengan menggunakan kunci partisi hierarkis (juga disebut subpartitoning), Anda dapat mengonfigurasi hingga hierarki tiga tingkat untuk kunci partisi Anda untuk lebih mengoptimalkan distribusi data dan untuk tingkat penskalaan yang lebih tinggi.

Jika Anda menggunakan kunci sintetis hari ini atau jika Anda memiliki skenario di mana kunci partisi dapat melebihi 20 GB data, subpartisi dapat membantu. Jika Anda menggunakan fitur ini, awalan kunci partisi logis dapat melebihi 20 GB dan 10.000 unit permintaan per detik (RU/dtk). Kueri berdasarkan awalan dirutekan secara efisien ke subset partisi yang menyimpan data.

Pilih kunci partisi hierarkis Anda

Jika Anda memiliki aplikasi multipenyewa, kami sarankan Anda menggunakan kunci partisi hierarkis. Partisi hierarkis memungkinkan Anda untuk menskalakan di luar batas kunci partisi logis 20 GB. Jika kunci partisi Anda saat ini atau jika kunci partisi tunggal sering mencapai 20 GB, partisi hierarkis adalah pilihan yang bagus untuk beban kerja Anda.

Saat Anda memilih kunci partisi hierarkis, penting untuk mengingat konsep partisi umum berikut:

  • Untuk semua kontainer, setiap tingkat jalur lengkap (dimulai dengan tingkat pertama) kunci partisi hierarkis Anda harus:

    • Memiliki kardinalitas tinggi. Kunci pertama, kedua, dan ketiga (jika berlaku) dari partisi hierarkis semuanya harus memiliki berbagai nilai yang mungkin.
    • Sebarkan konsumsi unit permintaan (RU) dan penyimpanan data secara merata di semua partisi logis. Penyebaran ini memastikan penggunaan RU dan distribusi penyimpanan yang merata di seluruh partisi fisik Anda.
  • Untuk beban kerja besar dan berat baca, kami sarankan Anda memilih kunci partisi hierarkis yang sering muncul dalam kueri Anda. Misalnya, beban kerja yang sering menjalankan kueri untuk memfilter sesi pengguna tertentu dalam aplikasi multipenyewa dapat memperoleh manfaat dari kunci partisi hierarkis TenantId, , UserIddan SessionId, dalam urutan tersebut. Kueri dapat dirutekan secara efisien ke partisi fisik yang relevan saja dengan menyertakan kunci partisi dalam predikat filter. Untuk informasi selengkapnya tentang memilih kunci partisi untuk beban kerja baca-berat, lihat gambaran umum partisi.

Contoh kasus penggunaan

Misalkan Anda memiliki skenario multipenyewa tempat Anda menyimpan informasi peristiwa untuk pengguna di setiap penyewa. Informasi peristiwa mungkin memiliki peristiwa termasuk tetapi tidak terbatas pada peristiwa masuk, clickstream, atau pembayaran.

Dalam skenario dunia nyata, beberapa penyewa dapat tumbuh besar, dengan ribuan pengguna, sementara banyak penyewa lain lebih kecil dan memiliki beberapa pengguna. Pemartisian dengan /TenantId mungkin menyebabkan melebihi batas penyimpanan Azure Cosmos DB 20-GB pada satu partisi logis. Pemartisian dengan /UserId membuat semua kueri pada lintas partisi penyewa. Kedua pendekatan memiliki kelemahan yang signifikan.

Menggunakan kunci partisi sintetis yang menggabungkan TenantId dan UserId menambahkan kompleksitas ke aplikasi. Selain itu, kueri kunci partisi sintetis untuk penyewa masih lintas partisi, kecuali semua pengguna diketahui dan ditentukan sebelumnya.

Dengan kunci partisi hierarkis, Anda dapat mempartisi terlebih dahulu pada TenantId, dan kemudian pada UserId. Jika Anda mengharapkan TenantId kombinasi dan UserId untuk menghasilkan partisi yang melebihi 20 GB, Anda bahkan dapat mempartisi lebih jauh ke tingkat lain, seperti pada SessionId. Kedalaman keseluruhan tidak boleh melebihi tiga tingkat. Ketika partisi fisik melebihi penyimpanan 50 GB, Azure Cosmos DB secara otomatis membagi partisi fisik sehingga kira-kira setengah dari data berada di satu partisi fisik, dan setengahnya ada di partisi fisik lainnya. Secara efektif, subpartisi berarti bahwa satu TenantId nilai dapat melebihi 20 GB data, dan dimungkinkan bagi TenantId data untuk menjangkau beberapa partisi fisik.

Kueri yang menentukan TenantId, atau keduanya TenantId dan UserId, dirutekan secara efisien hanya ke subset partisi fisik yang berisi data yang relevan. Menentukan jalur kunci partisi penuh atau prefiks yang dipartisi secara efektif menghindari kueri fan-out penuh. Misalnya, jika kontainer memiliki 1.000 partisi fisik, tetapi nilai tertentu TenantId hanya pada 5 partisi fisik, kueri akan dirutekan ke jumlah partisi fisik yang relevan yang lebih kecil.

Gunakan ID item dalam hierarki

Jika kontainer Anda memiliki properti yang memiliki sejumlah besar nilai yang mungkin, properti kemungkinan adalah pilihan kunci partisi yang bagus untuk tingkat terakhir hierarki Anda. Salah satu contoh yang mungkin dari jenis properti ini adalah ID item. ID item properti sistem tersedia pada setiap item dalam kontainer Anda. Menambahkan ID item sebagai tingkat lain menjamin bahwa Anda dapat menskalakan di luar batas kunci partisi logis 20 GB. Anda dapat menskalakan melebihi batas ini untuk tingkat pertama atau untuk tingkat kunci pertama dan kedua.

Misalnya, Anda mungkin memiliki kontainer untuk beban kerja multipenyewa yang dipartisi oleh TenantId dan UserId. Jika memungkinkan untuk kombinasi TenantId tunggal dan UserId melebihi 20 GB, kami sarankan Anda mempartisi dengan menggunakan tiga tingkat kunci, dan di mana kunci tingkat ketiga memiliki kardinalitas tinggi. Contoh skenario ini adalah jika kunci tingkat ketiga adalah GUID yang memiliki kardinalitas tinggi secara alami. Tidak mungkin kombinasi TenantId, , UserIddan GUID melebihi 20 GB, sehingga kombinasi TenantId dan UserId dapat secara efektif menskalakan melebihi 20 GB.

Untuk informasi selengkapnya tentang menggunakan ID item sebagai kunci partisi, lihat gambaran umum partisi.

Mulai

Penting

Bekerja dengan kontainer yang menggunakan kunci partisi hierarkis hanya didukung dalam versi SDK berikut. Anda harus menggunakan SDK yang didukung untuk membuat kontainer baru dengan kunci partisi hierarkis dan untuk melakukan operasi buat, baca, perbarui, dan hapus (CRUD) atau kueri pada data. Jika Anda ingin menggunakan SDK atau konektor yang saat ini tidak didukung, silakan ajukan permintaan di forum komunitas kami.

Temukan versi pratinjau terbaru dari setiap SDK yang didukung:

SDK Versi yang didukung Link manajer paket
.NET SDK v3 >= 3.33.0 https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.33.0/
Java SDK v4 >= 4.42.0 https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/cosmos/azure-cosmos/CHANGELOG.md#4420-2023-03-17/
JavaScript SDK v4 4.0.0 https://www.npmjs.com/package/@azure/cosmos/

Membuat kontainer dengan menggunakan kunci partisi hierarkis

Untuk memulai, buat kontainer baru dengan menggunakan daftar jalur kunci subpartisi yang telah ditentukan hingga tiga tingkat kedalaman.

Anda dapat membuat kontainer baru dengan menggunakan salah satu opsi berikut:

  • Portal Azure
  • SDK
  • Templat Azure Resource Manager
  • Emulator Azure Cosmos DB

Portal Azure

Cara paling sederhana untuk membuat kontainer dan menentukan kunci partisi hierarkis adalah dengan menggunakan portal Azure.

  1. Masuk ke portal Azure.

  2. Buka halaman akun Azure Cosmos DB for NoSQL yang sudah ada.

  3. Di menu sebelah kiri, pilih Data Explorer.

    Screenshot that shows the page for a new Azure Cosmos DB for NoSQL account with the Data Explorer menu option highlighted.

  4. Pada Data Explorer, pilih opsi Kontainer Baru.

    Screenshot of the New Container option within Data Explorer.

  5. Di Kontainer Baru, untuk kunci Partisi, masukkan /TenantId. Untuk bidang yang tersisa, masukkan nilai apa pun yang cocok dengan skenario Anda.

    Catatan

    Kami menggunakan /TenantId sebagai contoh di sini. Anda dapat menentukan kunci apa pun untuk tingkat pertama saat menerapkan kunci partisi hierarkis pada kontainer Anda sendiri.

  6. Pilih Tambahkan kunci partisi hierarkis dua kali.

    Screenshot of the button to add a new hierarchical partition key.

  7. Untuk tingkat kedua dan ketiga subpartisi, masukkan /UserId dan /SessionId masing-masing.

    Screenshot of a list of three hierarchical partition keys.

  8. Pilih OK untuk membuat kontainer.

SDK

Saat Anda membuat kontainer baru dengan menggunakan SDK, tentukan daftar jalur kunci subpartisi hingga tiga tingkat kedalaman. Gunakan daftar kunci subpartisi saat Anda mengonfigurasi properti kontainer baru.

// List of partition keys, in hierarchical order. You can have up to three levels of keys.
List<string> subpartitionKeyPaths = new List<string> { 
    "/TenantId",
    "/UserId",
    "/SessionId"
};

// Create a container properties object
ContainerProperties containerProperties = new ContainerProperties(
    id: "<container-name>",
    partitionKeyPaths: subpartitionKeyPaths
);

// Create a container that's subpartitioned by TenantId > UserId > SessionId
Container container = await database.CreateContainerIfNotExistsAsync(containerProperties, throughput: 400);

Templat Azure Resource Manager

Templat Azure Resource Manager untuk kontainer subpartisi hampir identik dengan kontainer standar. Satu-satunya perbedaan utama adalah nilai properties/partitionKey jalur. Untuk informasi selengkapnya tentang membuat templat Azure Resource Manager untuk sumber daya Azure Cosmos DB, lihat referensi template Azure Resource Manager untuk Azure Cosmos DB.

Konfigurasikan partitionKey objek dengan menggunakan nilai dalam tabel berikut untuk membuat kontainer subpartisi:

Jalur Value
paths Daftar kunci partisi hierarkis (maks tiga tingkat kedalaman)
kind MultiHash
version 2

Contoh definisi kunci partisi

Misalnya, asumsikan bahwa Anda memiliki kunci partisi hierarkis yang terdiri dari TenantIdSessionId>UserId>. Objek partitionKey akan dikonfigurasi untuk menyertakan ketiga nilai dalam paths properti, kind nilai MultiHash, dan version nilai 2.

partitionKey: {
  paths: [
    '/TenantId',
    '/UserId',
    '/SessionId'
  ]
  kind: 'MultiHash'
  version: 2
}

Untuk informasi selengkapnya tentang partitionKey objek, lihat spesifikasi ContainerPartitionKey.

Emulator Azure Cosmos DB

Anda dapat menguji fitur subpartisi dengan menggunakan versi terbaru emulator lokal untuk Azure Cosmos DB. Untuk mengaktifkan subparisi pada emulator, mulai emulator dari direktori penginstalan dengan /EnablePreview bendera :

.\CosmosDB.Emulator.exe /EnablePreview

Peringatan

Emulator saat ini tidak mendukung semua fitur kunci partisi hiearkis sebagai portal. Emulator saat ini tidak mendukung:

  • Menggunakan Data Explorer untuk membuat kontainer dengan kunci partisi hierarkis
  • Menggunakan Data Explorer untuk menavigasi ke dan berinteraksi dengan item menggunakan kunci partisi hierarkis

Untuk informasi selengkapnya, lihat Emulator Azure Cosmos DB.

Gunakan SDK untuk bekerja dengan kontainer yang memiliki kunci partisi hierarkis

Ketika Anda memiliki kontainer yang memiliki kunci partisi hierarkis, gunakan versi .NET atau Java SDK yang ditentukan sebelumnya untuk melakukan operasi dan menjalankan kueri pada kontainer tersebut.

Menambahkan item ke kontainer

Ada dua opsi untuk menambahkan item baru ke kontainer dengan kunci partisi hierarki diaktifkan:

  • Ekstraksi otomatis
  • Tentukan jalur secara manual

Ekstraksi otomatis

Jika Anda meneruskan objek dengan set nilai kunci partisi, SDK dapat secara otomatis mengekstrak jalur kunci partisi lengkap.

// Create a new item
UserSession item = new UserSession()
{
    id = "f7da01b0-090b-41d2-8416-dacae09fbb4a",
    TenantId = "Microsoft",
    UserId = "8411f20f-be3e-416a-a3e7-dcd5a3c1f28b",
    SessionId = "0000-11-0000-1111"
};

// Pass in the object, and the SDK automatically extracts the full partition key path
ItemResponse<UserSession> createResponse = await container.CreateItemAsync(item);

Tentukan jalur secara manual

Kelas PartitionKeyBuilder dalam SDK dapat membuat nilai untuk jalur kunci partisi hierarkis yang ditentukan sebelumnya. Gunakan kelas ini saat Anda menambahkan item baru ke kontainer yang mengaktifkan subpartisi.

Tip

Dalam skala besar, performa mungkin ditingkatkan jika Anda menentukan jalur kunci partisi lengkap, bahkan jika SDK dapat mengekstrak jalur dari objek.

// Create a new item object
PaymentEvent item = new PaymentEvent()
{
    id = Guid.NewGuid().ToString(),
    TenantId = "Microsoft",
    UserId = "8411f20f-be3e-416a-a3e7-dcd5a3c1f28b",
    SessionId = "0000-11-0000-1111"
};

// Specify the full partition key path when creating the item
PartitionKey partitionKey = new PartitionKeyBuilder()
            .Add(item.TenantId)
            .Add(item.UserId)
            .Add(item.SessionId)
            .Build();

// Create the item in the container
ItemResponse<PaymentEvent> createResponse = await container.CreateItemAsync(item, partitionKey);

Melakukan pencarian kunci/nilai (baca titik) item

Pencarian kunci/nilai (pembacaan titik) dilakukan dengan cara yang mirip dengan kontainer non-subpartisi. Misalnya, asumsikan Anda memiliki kunci partisi hierarkis yang terdiri dari TenantId>>UserIdSessionId. Pengidentifikasi unik untuk item adalah GUID. Ini direpresentasikan sebagai string yang berfungsi sebagai pengidentifikasi transaksi dokumen unik. Untuk melakukan titik yang dibaca pada satu item, teruskan id properti item dan nilai lengkap untuk kunci partisi, termasuk ketiga komponen jalur.

// Store the unique identifier
string id = "f7da01b0-090b-41d2-8416-dacae09fbb4a";

// Build the full partition key path
PartitionKey partitionKey = new PartitionKeyBuilder()
    .Add("Microsoft") //TenantId
    .Add("8411f20f-be3e-416a-a3e7-dcd5a3c1f28b") //UserId
    .Add("0000-11-0000-1111") //SessionId
    .Build();

// Perform a point read
ItemResponse<UserSession> readResponse = await container.ReadItemAsync<UserSession>(
    id,
    partitionKey
);

Menjalankan kueri

Kode SDK yang Anda gunakan untuk menjalankan kueri pada kontainer subpartisi identik dengan menjalankan kueri pada kontainer non-subpartisi.

Saat kueri menentukan semua nilai kunci partisi dalam WHERE filter atau dalam awalan hierarki kunci, SDK secara otomatis merutekan kueri ke partisi fisik yang sesuai. Kueri yang hanya menyediakan "tengah" hierarki adalah kueri lintas partisi.

Misalnya, pertimbangkan kunci partisi hierarkis yang terdiri dari TenantIdSessionId>UserId>. Komponen filter kueri menentukan apakah kueri adalah kueri partisi tunggal, kueri lintas partisi yang ditargetkan, atau kueri fan-out.

Kueri Perutean
SELECT * FROM c WHERE c.TenantId = 'Microsoft' AND c.UserId = '8411f20f-be3e-416a-a3e7-dcd5a3c1f28b' AND c.SessionId = '0000-11-0000-1111' Dirutekan ke partisi logis tunggal dan fisik yang berisi data untuk nilai yang ditentukan dari TenantId, , UserIddan SessionId.
SELECT * FROM c WHERE c.TenantId = 'Microsoft' AND c.UserId = '8411f20f-be3e-416a-a3e7-dcd5a3c1f28b' Dirutekan hanya ke subset logis yang ditargetkan dan partisi fisik yang berisi data untuk nilai TenantId dan UserId yang ditentukan. Kueri ini adalah kueri lintas partisi yang ditargetkan yang mengembalikan data untuk pengguna tertentu di penyewa.
SELECT * FROM c WHERE c.TenantId = 'Microsoft' Dirutekan hanya ke subset logis yang ditargetkan dan partisi fisik yang berisi data untuk nilai TenantId yang ditentukan. Kueri ini adalah kueri lintas partisi yang ditargetkan yang mengembalikan data untuk semua pengguna di penyewa.
SELECT * FROM c WHERE c.UserId = '8411f20f-be3e-416a-a3e7-dcd5a3c1f28b' Dirutekan ke semua partisi fisik, menghasilkan kueri lintas partisi fan-out.
SELECT * FROM c WHERE c.SessionId = '0000-11-0000-1111' Dirutekan ke semua partisi fisik, menghasilkan kueri lintas partisi fan-out.

Kueri partisi tunggal pada kontainer subpartisi

Berikut adalah contoh menjalankan kueri yang menyertakan semua tingkat subpartisi, secara efektif membuat kueri kueri partisi tunggal.

// Define a single-partition query that specifies the full partition key path
QueryDefinition query = new QueryDefinition(
    "SELECT * FROM c WHERE c.TenantId = @tenant-id AND c.UserId = @user-id AND c.SessionId = @session-id")
    .WithParameter("@tenant-id", "Microsoft")
    .WithParameter("@user-id", "8411f20f-be3e-416a-a3e7-dcd5a3c1f28b")
    .WithParameter("@session-id", "0000-11-0000-1111");

// Retrieve an iterator for the result set
using FeedIterator<PaymentEvent> results = container.GetItemQueryIterator<PaymentEvent>(query);

while (results.HasMoreResults)
{
    FeedResponse<UserSession> resultsPage = await resultSet.ReadNextAsync();
    foreach(UserSession result in resultsPage)
    {
        // Process result
    }
}

Kueri multi-partisi yang ditargetkan pada kontainer subpartisi

Berikut adalah contoh kueri yang menyertakan subset tingkat subpartisi, secara efektif menjadikan kueri ini sebagai kueri multi-partisi yang ditargetkan.

// Define a targeted cross-partition query specifying prefix path[s]
QueryDefinition query = new QueryDefinition(
    "SELECT * FROM c WHERE c.TenantId = @tenant-id")
    .WithParameter("@tenant-id", "Microsoft")

// Retrieve an iterator for the result set
using FeedIterator<PaymentEvent> results = container.GetItemQueryIterator<PaymentEvent>(query);

while (results.HasMoreResults)
{
    FeedResponse<UserSession> resultsPage = await resultSet.ReadNextAsync();
    foreach(UserSession result in resultsPage)
    {
        // Process result
    }
}

Batasan dan masalah yang diketahui

  • Bekerja dengan kontainer yang menggunakan kunci partisi hierarkis hanya didukung di .NET v3 SDK, di Java v4 SDK, dan dalam versi pratinjau JavaScript SDK. Anda harus menggunakan SDK yang didukung untuk membuat kontainer baru yang memiliki kunci partisi hierarkis dan untuk melakukan operasi CRUD atau kueri pada data. Dukungan untuk SDK lain, termasuk Python, saat ini tidak tersedia.
  • Ada batasan dengan berbagai konektor Azure Cosmos DB (misalnya, dengan Azure Data Factory).
  • Anda dapat menentukan kunci partisi hierarkis hanya hingga tiga lapisan secara mendalam.
  • Kunci partisi hierarkis saat ini hanya dapat diaktifkan pada kontainer baru. Anda harus mengatur jalur kunci partisi pada saat pembuatan kontainer, dan Anda tidak dapat mengubahnya nanti. Untuk menggunakan partisi hierarkis pada kontainer yang ada, buat kontainer baru dengan kunci partisi hierarkis yang diatur dan pindahkan data dengan menggunakan pekerjaan salinan kontainer.
  • Kunci partisi hierarkis saat ini hanya didukung untuk API untuk akun NoSQL. API untuk MongoDB dan Cassandra saat ini tidak didukung.
  • Kunci partisi hierarkis saat ini tidak didukung dengan fitur Izin. Anda tidak dapat menetapkan izin ke awalan parsial jalur kunci partisi hierarkis. Izin hanya dapat ditetapkan ke seluruh jalur kunci partisi logis. Misalnya, jika Anda telah dipartisi oleh TenantId - >UserId, Anda tidak dapat menetapkan izin yang untuk nilai tertentu dari TenantId. Namun, Anda dapat menetapkan izin untuk kunci partisi jika Anda menentukan nilai untuk TenantId dan ''UserId'''.

Langkah berikutnya