Bagikan melalui


Tips performa untuk Azure Cosmos DB dan .NET

Azure Cosmos DB adalah database terdistribusi yang cepat dan fleksibel yang menskalakan dengan mulus dengan tingkat latensi dan throughput terjamin. Anda tidak perlu membuat perubahan arsitektur besar atau menulis kode kompleks untuk menskalakan database dengan Azure Cosmos DB. Peningkatan atau penurunan skala semudah menjalankan satu panggilan API. Untuk mempelajari lebih lanjut, lihat sediakan throughput kontainer atau sediakan throughput database.

Karena Azure Cosmos DB diakses melalui panggilan jaringan, Anda dapat membuat pengoptimalan sisi klien untuk mencapai kinerja puncak saat menggunakan SQL .NET SDK.

Jika Anda mencoba meningkatkan kinerja database, pertimbangkan opsi yang disajikan di bagian berikut ini.

Rekomendasi hosting

Mengaktifkan pengumpulan sampah sisi server

Pengurangan frekuensi pengumpulan sampah dapat membantu pada beberapa kasus. Dalam .NET, atur gcServer ke true.

Meluaskan skala beban kerja klien Anda

Jika Anda menguji pada tingkat throughput tinggi, atau pada tingkat yang lebih besar dari 50.000 Unit Permintaan per detik (RU/dtk), aplikasi klien dapat menyebabkan kendala dalam beban kerja karena mesin mungkin mencapai batas penggunaan CPU atau jaringan. Jika mencapai titik ini, Anda dapat terus mendorong akun Azure Cosmos DB lebih jauh dengan meluaskan skala aplikasi klien di beberapa server.

Nota

Penggunaan CPU yang tinggi dapat menyebabkan peningkatan latensi dan pengecualian batas waktu permintaan.

Operasi metadata

Jangan verifikasi bahwa database atau kontainer ada dengan memanggil Create...IfNotExistsAsync atau Read...Async di jalur panas atau sebelum melakukan operasi item. Validasi hanya boleh dilakukan pada startup aplikasi saat diperlukan, jika Anda mengharapkannya dihapus (jika tidak, tidak diperlukan). Operasi metadata ini menghasilkan latensi end-to-end ekstra, tidak memiliki SLA, dan memiliki batasan terpisah yang tidak mengalami peningkatan kapasitas seperti operasi data.

Pencatatan dan pelacakan

Beberapa lingkungan mengaktifkan .NET DefaultTraceListener. DefaultTraceListener menimbulkan masalah performa pada lingkungan produksi yang menyebabkan penyempitan CPU dan I/O yang tinggi. Periksa dan pastikan bahwa DefaultTraceListener dinonaktifkan untuk aplikasi Anda dengan menghapusnya dari TraceListeners di lingkungan produksi.

Versi SDK yang lebih besar dari 3.23.0 secara otomatis menghapusnya saat terdeteksi. Dengan versi yang lebih lama, Anda dapat menghapusnya dengan menggunakan perintah berikut:

if (!Debugger.IsAttached)
{
    Type defaultTrace = Type.GetType("Microsoft.Azure.Cosmos.Core.Trace.DefaultTrace,Microsoft.Azure.Cosmos.Direct");
    TraceSource traceSource = (TraceSource)defaultTrace.GetProperty("TraceSource").GetValue(null);
    traceSource.Listeners.Remove("Default");
    // Add your own trace listeners
}

Ketersediaan tinggi

Untuk panduan umum tentang mengonfigurasi ketersediaan tinggi di Azure Cosmos DB, lihat Ketersediaan tinggi di Azure Cosmos DB.

Selain pengaturan dasar yang baik di platform database, ada teknik khusus yang dapat diimplementasikan dalam .NET SDK itu sendiri, yang dapat membantu dalam skenario pemadaman. Dua strategi penting adalah strategi ketersediaan berbasis ambang batas dan pemutus sirkuit tingkat partisi.

Strategi ketersediaan berbasis ambang batas

Strategi ketersediaan berbasis ambang batas dapat meningkatkan latensi ekor dan ketersediaan dengan mengirim permintaan baca paralel ke wilayah sekunder (sebagaimana didefinisikan dalam ApplicationPreferredRegions) dan menerima respons tercepat. Pendekatan ini dapat secara drastis mengurangi efek pemadaman regional atau kondisi latensi tinggi pada performa aplikasi.

Konfigurasi contoh:

Mengonfigurasi ini dapat dilakukan menggunakan CosmosClientBuilder:

CosmosClient client = new CosmosClientBuilder("connection string")
    .WithApplicationPreferredRegions(
        new List<string> { "East US", "East US 2", "West US" } )
    .WithAvailabilityStrategy(
        AvailabilityStrategy.CrossRegionHedgingStrategy(
        threshold: TimeSpan.FromMilliseconds(500),
        thresholdStep: TimeSpan.FromMilliseconds(100)
     ))
    .Build();

Atau dengan mengonfigurasi opsi dan menambahkannya ke CosmosClient:

CosmosClientOptions options = new CosmosClientOptions()
{
    AvailabilityStrategy
     = AvailabilityStrategy.CrossRegionHedgingStrategy(
        threshold: TimeSpan.FromMilliseconds(500),
        thresholdStep: TimeSpan.FromMilliseconds(100)
     )
      ApplicationPreferredRegions = new List<string>() { "East US", "East US 2", "West US"},
};

CosmosClient client = new CosmosClient(
    accountEndpoint: "account endpoint",
    authKeyOrResourceToken: "auth key or resource token",
    clientOptions: options);

Cara kerjanya:

  1. Permintaan awal: Pada saat T1, permintaan baca dibuat ke wilayah utama (misalnya, US Timur). SDK menunggu respons hingga 500 milidetik ( threshold nilai).

  2. Permintaan kedua: Jika tidak ada respons dari wilayah utama dalam 500 milidetik, permintaan paralel dikirim ke wilayah pilihan berikutnya (misalnya, US Timur 2).

  3. Permintaan ketiga: Jika baik wilayah utama maupun sekunder tidak merespons dalam 600 milidetik (500 mdtk + 100 ms, nilainya thresholdStep ), SDK mengirimkan permintaan paralel lain ke wilayah pilihan ketiga (misalnya, AS Barat).

  4. Respons tercepat menang: Wilayah mana pun yang merespons terlebih dahulu, respons tersebut diterima, dan permintaan paralel lainnya diabaikan.

Nota

Jika wilayah pilihan pertama mengembalikan kode status kesalahan nontransient (misalnya, dokumen tidak ditemukan, kesalahan otorisasi, atau konflik), operasi itu sendiri gagal dengan cepat, karena strategi ketersediaan tidak memiliki manfaat dalam skenario ini.

Pemutus sirkuit tingkat partisi

Pemutus arus tingkat partisi (PPCB) adalah fitur di .NET SDK yang meningkatkan ketersediaan dan latensi dengan melacak partisi fisik yang tidak sehat. Saat diaktifkan, ini membantu merutekan permintaan ke wilayah yang lebih sehat, mencegah kegagalan beruntun akibat masalah yang spesifik pada wilayah atau partisi. Fitur ini independen dari failover yang dipicu backend dan dikontrol melalui variabel lingkungan.

Fitur ini dinonaktifkan secara default, tetapi diaktifkan secara otomatis ketika failover tingkat partisi diaktifkan.

Cara kerjanya

  1. Deteksi kegagalan: Ketika kesalahan tertentu seperti 503 Service Unavailable, 408 Request Timeout, atau token pembatalan diamati, SDK menghitung kegagalan berturut-turut untuk partisi.
  2. Memicu terjadinya failover: Setelah batas ambang kegagalan berurutan yang dikonfigurasi tercapai, SDK mengalihkan permintaan untuk rentang kunci partisi tersebut ke wilayah pilihan berikutnya menggunakan GlobalPartitionEndpointManagerCore.TryMarkEndpointUnavailableForPartitionKeyRange.
  3. Pemulihan Latar Belakang: Tugas latar belakang dimulai selama failover untuk mengevaluasi ulang kesehatan partisi yang gagal secara berkala dengan mencoba menyambungkan ke keempat replika. Setelah pulih, SDK menghapus penggantian sementara dan kembali ke wilayah utama.

Perilaku menurut jenis akun

  • Penulisan wilayah tunggal (master tunggal): Hanya permintaan baca yang berpartisipasi dalam logika failover PPCB.
  • Penulisan multi-regional (multi master): Permintaan baca dan tulis menggunakan logika failover PPCB.

Opsi konfigurasi

Gunakan variabel lingkungan berikut untuk mengonfigurasi PPCB:

Variabel lingkungan Description Bawaan
AZURE_COSMOS_CIRCUIT_BREAKER_ENABLED Mengaktifkan atau menonaktifkan fitur PPCB. false
AZURE_COSMOS_PPCB_CONSECUTIVE_FAILURE_COUNT_FOR_READS Kegagalan baca berturut-turut untuk memicu failover. 10
AZURE_COSMOS_PPCB_CONSECUTIVE_FAILURE_COUNT_FOR_WRITES Kegagalan penulisan berturut-turut yang memicu failover. 5
AZURE_COSMOS_PPCB_ALLOWED_PARTITION_UNAVAILABILITY_DURATION_IN_SECONDS Waktu sebelum mengevaluasi kembali kesehatan partisi. 5 detik
AZURE_COSMOS_PPCB_STALE_PARTITION_UNAVAILABILITY_REFRESH_INTERVAL_IN_SECONDS Interval untuk penyegaran latar belakang kesehatan partisi. 60 detik

Nota

SDK saat ini tidak memiliki pemicu failback yang dapat diandalkan untuk operasi pembacaan. Sebaliknya, pemeriksa kesehatan latar belakang secara bertahap mencoba mengaktifkan kembali wilayah asli ketika keempat replika responsif.

Membandingkan pengoptimalan ketersediaan

  • Strategi ketersediaan berbasis ambang batas:

    • Manfaat: Mengurangi latensi ekor dengan mengirim permintaan baca paralel ke wilayah sekunder, dan meningkatkan ketersediaan dengan mendahului permintaan yang mengakibatkan batas waktu jaringan.
    • Trade-off: Dikenakan biaya Unit Permintaan (RU) tambahan dibandingkan dengan pemutus sirkuit, karena permintaan lintas wilayah paralel tambahan (meskipun hanya selama periode ketika ambang dilanggar).
    • Kasus penggunaan: Paling cocok untuk beban kerja yang berfokus pada pembacaan di mana pengurangan latensi sangat krusial dan beberapa biaya tambahan (baik dari segi biaya RU maupun beban CPU pada klien) dapat diterima. Operasi tulis juga dapat memperoleh manfaat, jika memilih kebijakan coba lagi tulis nonidempotent dan akun memiliki penulisan multi-wilayah.
  • Pemutus sirkuit tingkat partisi:

    • Manfaat: Meningkatkan ketersediaan dan latensi dengan menghindari partisi yang tidak sehat, memastikan permintaan dirutekan ke wilayah yang lebih sehat.
    • Trade-off: Tidak menimbulkan biaya RU tambahan, namun masih memungkinkan beberapa penurunan ketersediaan awal untuk permintaan yang mengakibatkan batas waktu jaringan.
    • Kasus penggunaan: Idealnya untuk beban kerja tulis-berat atau campuran di mana performa yang konsisten sangat penting, terutama ketika berhadapan dengan partisi yang mungkin secara sementara mengalami masalah.

Kedua strategi dapat digunakan bersama-sama untuk meningkatkan ketersediaan baca dan tulis serta mengurangi latensi akhir. Pemutus arus tingkat partisi dapat menangani berbagai skenario kegagalan sementara, termasuk yang dapat mengakibatkan replika berkinerja lambat, tanpa perlu melakukan permintaan paralel. Selain itu, menambahkan strategi ketersediaan berbasis ambang batas semakin meminimalkan latensi ekor dan menghilangkan kehilangan ketersediaan, jika biaya RU tambahan dapat diterima.

Dengan menerapkan strategi ini, pengembang dapat memastikan aplikasi mereka tetap tangguh, mempertahankan performa tinggi, dan memberikan pengalaman pengguna yang lebih baik bahkan selama pemadaman regional atau kondisi latensi tinggi.

Wilayah yang dikecualikan

Fitur wilayah yang dikecualikan memungkinkan kontrol terperinci atas perutean permintaan dengan memungkinkan Anda mengecualikan wilayah tertentu dari lokasi pilihan Anda berdasarkan per permintaan. Fitur ini tersedia di Azure Cosmos DB .NET SDK versi 3.37.0 dan yang lebih tinggi.

Manfaat utama:

  • Menangani pembatasan laju: Saat mengalami respons 429 (Terlalu Banyak Permintaan), secara otomatis merutekan permintaan ke wilayah alternatif dengan throughput yang tersedia
  • Perutean yang ditargetkan: Pastikan permintaan dilayani dari wilayah tertentu dengan mengecualikan semua yang lain
  • Melewati urutan pilihan: Mengambil alih daftar wilayah pilihan default untuk permintaan individual tanpa membuat klien terpisah

Configuration:

Wilayah yang dikecualikan dapat dikonfigurasi pada tingkat permintaan menggunakan ExcludeRegions properti :

CosmosClientOptions clientOptions = new CosmosClientOptions()
{
    ApplicationPreferredRegions = new List<string> {"West US", "Central US", "East US"}
};

CosmosClient client = new CosmosClient(connectionString, clientOptions);

Database db = client.GetDatabase("myDb");
Container container = db.GetContainer("myContainer");

//Request will be served out of the West US region
await container.ReadItemAsync<dynamic>("item", new PartitionKey("pk"));

//By using ExcludeRegions, we are able to bypass the ApplicationPreferredRegions list
// and route a request directly to the East US region
await container.ReadItemAsync<dynamic>(
  "item", 
  new PartitionKey("pk"),
  new ItemRequestOptions()
  {
    ExcludeRegions = new List<string>() { "West US", "Central US" }
  });

Contoh kasus penggunaan - menangani pembatasan laju:

ItemResponse<CosmosItem> item;
item = await container.ReadItemAsync<CosmosItem>("id", partitionKey);

if (item.StatusCode == HttpStatusCode.TooManyRequests)
{
    ItemRequestOptions requestOptions = new ItemRequestOptions()
    {
        ExcludeRegions = new List<string>() { "East US" }
    };

    item = await container.ReadItemAsync<CosmosItem>("id", partitionKey, requestOptions);
}

Fitur ini juga berfungsi dengan permintaan dan operasi lainnya.

QueryRequestOptions queryRequestOptions = new QueryRequestOptions()
{
    ExcludeRegions = new List<string>() { "East US" }
};

using (FeedIterator<CosmosItem> queryFeedIterator = container.GetItemQueryIterator<CosmosItem>(
    queryDefinition, 
    requestOptions: queryRequestOptions))
{
    while(queryFeedIterator.HasMoreResults)
    {
        var item = await queryFeedIterator.ReadNextAsync();
    }
}

Menyempurnakan konsistensi vs ketersediaan

Fitur wilayah yang dikecualikan menyediakan mekanisme tambahan untuk menyeimbangkan konsistensi dan trade-off ketersediaan dalam aplikasi Anda. Kemampuan ini sangat berharga dalam skenario dinamis di mana persyaratan dapat bergeser berdasarkan kondisi operasional:

Penanganan pemadaman dinamis: Ketika wilayah utama mengalami pemadaman dan ambang batas pemutus sirkuit tingkat partisi terbukti tidak mencukupi, wilayah yang dikecualikan memungkinkan failover segera tanpa perubahan kode atau mulai ulang aplikasi. Ini memberikan respons yang lebih cepat terhadap masalah regional dibandingkan dengan menunggu aktivasi pemutus sirkuit otomatis.

Preferensi konsistensi kondisional: Aplikasi dapat menerapkan strategi konsistensi yang berbeda berdasarkan status operasional:

  • Status stabil: Prioritaskan bacaan yang konsisten dengan mengecualikan semua wilayah kecuali yang utama, memastikan konsistensi data dengan biaya potensial ketersediaan
  • Skenario pemadaman: Mengutamakan ketersediaan daripada konsistensi yang ketat dengan memungkinkan perutean lintas wilayah, dengan menerima potensi keterlambatan data demi ketersediaan layanan berkelanjutan

Pendekatan ini memungkinkan mekanisme eksternal (seperti manajer lalu lintas atau load balancer) untuk mengatur keputusan failover sementara aplikasi mempertahankan kontrol atas persyaratan konsistensi melalui pola pengecualian wilayah.

Ketika semua wilayah dikecualikan, permintaan akan dirutekan ke wilayah utama/hub. Fitur ini berfungsi dengan semua jenis permintaan termasuk kueri dan sangat berguna untuk mempertahankan instans klien singleton sambil mencapai perilaku perutean yang fleksibel.

Jaringan

Kebijakan koneksi: Gunakan mode koneksi langsung

Mode koneksi default .NET V3 SDK bersifat langsung dengan protokol TCP. Konfigurasikan mode koneksi saat Anda membuat instans CosmosClient di CosmosClientOptions. Untuk mempelajari selengkapnya tentang berbagai opsi konektivitas, lihat artikel mode konektivitas.

CosmosClient client = new CosmosClient(
  "<nosql-account-endpoint>",
  tokenCredential
  new CosmosClientOptions
  {
      ConnectionMode = ConnectionMode.Gateway // ConnectionMode.Direct is the default
  }
);

Kelelahan port sementara

Jika Anda melihat volume koneksi tinggi atau penggunaan port tinggi pada instans, pertama-tama pastikan bahwa instans klien Anda adalah singleton. Dengan kata lain, instans klien harus unik untuk seumur hidup aplikasi.

Ketika menggunakan protokol TCP, klien mengoptimalkan waktu tunda dengan menggunakan koneksi jangka panjang. Ini berbeda dengan protokol HTTPS, yang mengakhiri koneksi setelah inaktif dua menit.

Ketika aksesnya jarang, dan jika jumlah koneksi lebih tinggi dibanding mode Gateway, Anda dapat:

  • Mengonfigurasi properti CosmosClientOptions.PortReuseMode ke PrivatePortPool (berlaku dengan versi kerangka kerja 4.6.1 ke atas dan .NET Core versi 2.0 ke atas). Properti ini memungkinkan SDK untuk menggunakan kumpulan kecil port sementara untuk berbagai titik akhir tujuan Azure Cosmos DB.
  • Konfigurasikan properti CosmosClientOptions.IdleTcpConnectionTimeout lebih besar dari atau sama dengan 10 menit. Nilai yang disarankan adalah dari 20 menit hingga 24 jam.

Untuk performa, kolokasikan klien di wilayah Azure yang sama

Jika memungkinkan, tempatkan aplikasi apa pun yang memerintahkan Azure Cosmos DB di region yang sama dengan database Azure Cosmos DB. Berikut adalah perkiraan perbandingan: panggilan ke Azure Cosmos DB dalam wilayah yang sama selesai dalam 1 milidetik (ms) hingga 2 ms, tetapi latensi antara pantai Barat dan Timur AS lebih dari 50 ms. Latensi ini dapat bervariasi dari permintaan ke permintaan, tergantung pada rute yang diambil oleh permintaan saat melewati klien ke batas pusat data Azure.

Anda bisa mendapatkan latensi serendah mungkin dengan memastikan bahwa aplikasi panggilan terletak di wilayah Azure yang sama dengan titik akhir Azure Cosmos DB yang disediakan. Untuk daftar region yang tersedia, lihat Region Azure.

Diagram yang memperlihatkan klien yang dikolokasi di wilayah yang sama.

Meningkatkan jumlah rangkaian/tugas

Karena panggilan ke Azure Cosmos DB dilakukan melalui jaringan, Anda mungkin perlu variasi tingkat konkurensi permintaan sehingga aplikasi klien menghabiskan waktu tunggu minimal di antara permintaan. Contohnya, jika Anda menggunakan .NET Task Parallel Library, buat ratusan tugas yang dibaca dari atau ditulis ke Azure Cosmos DB.

Mengaktifkan jaringan yang dipercepat untuk mengurangi latensi dan jitter CPU

Disarankan agar Anda mengikuti instruksi untuk mengaktifkan Accelerated Networking di Windows atau Linux Azure VM Anda untuk memaksimalkan performa.

Tanpa networking yang dipercepat, IO yang transit antara Azure VM Anda dan sumber daya Azure lainnya mungkin dirutekan tanpa perlu melalui host dan sakelar virtual yang terletak antara VM dan kartu jaringannya. Memiliki host dan switch virtual terhubung langsung dalam jalur data tidak hanya meningkatkan latensi dan jitter di saluran komunikasi, tetapi juga mengurangi siklus CPU yang tersedia untuk VM. Dengan jaringan yang dipercepat, antarmuka VM berinteraksi langsung dengan NIC tanpa perantara; semua detail kebijakan jaringan yang sebelumnya ditangani oleh host dan sakelar virtual sekarang ditangani dalam perangkat keras di NIC; host dan sakelar virtual di-bypass. Umumnya Anda dapat mengharapkan latensi yang lebih rendah dan throughput yang lebih tinggi, serta latensi yang lebih konsisten dan pemanfaatan CPU yang menurun saat Anda mengaktifkan jaringan yang dipercepat.

Batasan: jaringan dipercepat harus didukung pada OS VM, dan hanya dapat diaktifkan ketika VM dihentikan dan dialokasikan ulang. VM tidak dapat disebarkan dengan Azure Resource Manager. App Service tidak mengaktifkan jaringan yang dipercepat.

Untuk detail selengkapnya, lihat instruksi Windows dan Linux .

Penggunaan SDK

Menginstal SDK terbaru

Azure Cosmos DB SDK terus ditingkatkan untuk memberikan performa terbaik. Untuk menentukan SDK terbaru dan meninjau peningkatan, lihat Azure Cosmos DB SDK.

Gunakan stream API

.NET SDK V3 berisi API stream yang dapat menerima dan mengembalikan data tanpa serialisasi.

Aplikasi tingkat menengah yang tidak mengonsumsi respons langsung dari SDK tetapi menyampaikannya ke tingkat aplikasi lain dapat memperoleh manfaat dari API stream. Untuk contoh penanganan stream, lihat sampel manajemen item.

Menggunakan klien database tunggal Azure Cosmos DB sepanjang siklus hidup aplikasi Anda

Setiap CosmosClient instans aman bagi thread dan melakukan manajemen koneksi serta penyimpanan alamat yang efisien saat bekerja dalam mode langsung. Untuk memungkinkan manajemen koneksi yang efisien dan performa klien SDK yang lebih baik, kami sarankan Anda menggunakan satu instans per AppDomain untuk masa pakai aplikasi untuk setiap akun yang berinteraksi dengan aplikasi Anda.

Untuk aplikasi multipenyewa yang menangani beberapa akun, lihat praktik terbaik terkait.

Saat Anda mengerjakan Azure Functions, instans juga harus mengikuti panduan yang ada dan mempertahankan satu instans.

Hindari memblokir panggilan

Azure Cosmos DB SDK harus dirancang untuk memproses banyak permintaan secara bersamaan. API asinkron memungkinkan kumpulan kecil utas untuk menangani ribuan permintaan bersamaan dengan tidak menunggu pemblokiran panggilan. Alih-alih menunggu tugas sinkron yang sudah berjalan lama untuk diselesaikan, utas dapat bekerja pada permintaan lain.

Masalah performa umum dalam aplikasi yang menggunakan Azure Cosmos DB SDK adalah memblokir panggilan yang bisa asinkron. Banyak panggilan pemblokiran sinkron menyebabkan kelaparan kumpulan utas dan penurunan waktu respons.

Jangan:

  • Blokir eksekusi asinkron dengan memanggil Task.Wait atau Task.Result.
  • Gunakan Task.Run untuk membuat API sinkron menjadi asinkron.
  • Dapatkan kunci di jalur kode umum. Azure Cosmos DB .NET SDK paling berkinerja ketika dirancang untuk menjalankan kode secara paralel.
  • Panggil Task.Run dan segera tunggu. ASP.NET Core sudah menjalankan kode aplikasi pada utas Kumpulan Utas normal, jadi memanggil Task.Run hanya menghasilkan penjadwalan kumpulan utas tambahan yang tidak perlu. Bahkan jika kode terjadwal akan memblokir suatu utas, Task.Run tidak mencegahnya.
  • Jangan gunakan ToList() pada Container.GetItemLinqQueryable<T>(), yang menggunakan pemblokiran panggilan untuk mengkuras kueri secara sinkron. Gunakan ToFeedIterator() untuk mengosongkan kueri secara asinkron.

Lakukan:

  • Panggil API .NET Azure Cosmos DB secara asinkron.
  • Seluruh tumpukan panggilan bersifat asinkron untuk memanfaatkan pola async/await.

Profiler, seperti PerfView, dapat digunakan untuk menemukan utas yang sering ditambahkan ke kumpulan utas. Acara Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start tersebut menunjukkan utas yang ditambahkan ke kumpulan utas.

Menonaktifkan respons konten pada operasi tulis

Untuk beban kerja yang memiliki beban pembuatan yang berat, atur opsi permintaan EnableContentResponseOnWrite menjadi false. Layanan tidak lagi mengembalikan sumber daya yang dibuat atau diperbarui ke SDK. Biasanya, karena aplikasi memiliki objek yang sedang dibuat, layanan tidak perlu mengembalikannya. Nilai header masih dapat diakses, seperti halnya biaya permintaan. Menonaktifkan respons konten dapat membantu meningkatkan performa, karena SDK tidak lagi perlu mengalokasikan memori atau serialisasi isi respons. Ini juga mengurangi penggunaan bandwidth jaringan untuk lebih membantu performa.

ItemRequestOptions requestOptions = new ItemRequestOptions() { EnableContentResponseOnWrite = false };
ItemResponse<Book> itemResponse = await this.container.CreateItemAsync<Book>(book, new PartitionKey(book.pk), requestOptions);
// Resource will be null
itemResponse.Resource

Aktifkan Bulk untuk mengoptimalkan throughput alih-alih latensi

Aktifkan Massal untuk skenario di mana beban kerja memerlukan sejumlah besar throughput, dan latensi tidak sepenting. Untuk informasi selengkapnya tentang cara mengaktifkan fitur Bulk, dan untuk mempelajari skenario mana yang harus digunakan, lihat Pengantar dukungan Bulk.

Meningkatkan System.Net MaxConnections per host saat Anda menggunakan mode Gateway

Permintaan Azure Cosmos DB dibuat melalui HTTPS/REST saat Anda menggunakan mode Gateway. Mereka tunduk pada batas koneksi default per nama host atau alamat IP. Anda mungkin perlu mengatur MaxConnections ke nilai yang lebih tinggi (dari 100 hingga 1.000) sehingga pustaka klien dapat menggunakan beberapa koneksi simultan ke Azure Cosmos DB. Dalam .NET SDK 1.8.0 dan yang lebih baru, nilai default untuk ServicePointManager.DefaultConnectionLimit adalah 50. Untuk mengubah nilai, Anda dapat mengatur Documents.Client.ConnectionPolicy.MaxConnectionLimit ke nilai yang lebih tinggi.

Meningkatkan jumlah rangkaian/tugas

Lihat Menambah jumlah utas/tugas di bagian Jaringan di artikel ini.

Mengelola Dependensi Newtonsoft.Json

Gambaran Umum

Azure Cosmos DB .NET SDK memiliki ketergantungan pada Newtonsoft.Json untuk operasi serialisasi JSON. Dependensi ini tidak dikelola secara otomatis - Anda harus secara eksplisit menambahkan Newtonsoft.Json sebagai dependensi langsung dalam proyek Anda.

SDK mengkompilasi terhadap Newtonsoft.Json 10.x secara internal, yang memiliki kerentanan keamanan yang diketahui. Meskipun SDK secara teknis kompatibel dengan 10.x, dan penggunaan SDK Newtonsoft.Json tidak rentan terhadap masalah keamanan yang dilaporkan, kami masih merekomendasikan penggunaan versi 13.0.3 atau yang lebih tinggi untuk menghindari potensi masalah keamanan atau konflik. Versi 13.x mencakup perubahan yang signifikan, tetapi pola penggunaan SDK tetap kompatibel dengan perubahan ini.

Penting

Dependensi ini diperlukan bahkan saat menggunakan System.Text.Json untuk jenis yang ditentukan pengguna melalui CosmosClientOptions.UseSystemTextJsonSerializerWithOptions, karena operasi internal SDK masih menggunakan Newtonsoft.Json untuk jenis sistem.

Selalu tambahkan versi 13.0.3 atau yang lebih tinggi secara Newtonsoft.Json eksplisit sebagai dependensi langsung saat menggunakan Azure Cosmos DB .NET SDK v3. Jangan gunakan versi 10.x karena kerentanan keamanan yang diketahui.

Untuk Proyek Standar .csproj

<ItemGroup>
  <PackageReference Include="Microsoft.Azure.Cosmos" Version="3.47.0" />
  <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>

Untuk Proyek yang Menggunakan Manajemen Paket Terpusat

Jika proyek Anda menggunakan Directory.Packages.props:

<Project>
  <ItemGroup>
    <PackageVersion Include="Microsoft.Azure.Cosmos" Version="3.47.0" />
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
  </ItemGroup>
</Project>

Pemecahan Masalah Konflik Versi

Hilang referensi Newtonsoft.Json

Jika Anda mengalami kesalahan build seperti:

The Newtonsoft.Json package must be explicitly referenced with version >= 10.0.2. Please add a reference to Newtonsoft.Json or set the 'AzureCosmosDisableNewtonsoftJsonCheck' property to 'true' to bypass this check.

Kesalahan ini sengaja dihasilkan oleh target build Cosmos DB SDK untuk memastikan dependensi dikonfigurasi dengan benar.

Solusi untuk Aplikasi:

Tambahkan referensi eksplisit ke Newtonsoft.Json seperti yang ditunjukkan di bagian Konfigurasi yang Direkomendasikan di atas.

Solusi untuk Pustaka:

Jika Anda membangun pustaka (bukan aplikasi) dan ingin menunda penggunaan dependensi Newtonsoft.Json agar digunakan oleh konsumen pustaka Anda, Anda dapat melewati pemeriksaan ini dengan mengatur properti MSBuild dalam konfigurasi :.csproj

<PropertyGroup>
  <AzureCosmosDisableNewtonsoftJsonCheck>true</AzureCosmosDisableNewtonsoftJsonCheck>
</PropertyGroup>

Peringatan

Hanya gunakan bypass ini saat membangun pustaka di mana pengguna akhir akan menyediakan dependensi Newtonsoft.Json. Untuk aplikasi, selalu tambahkan referensi eksplisit.

Konflik Versi Paket

Jika Anda mengalami kesalahan build seperti:

error NU1109: Detected package downgrade: Newtonsoft.Json from 13.0.4 to centrally defined 13.0.3

Solution:

  1. Identifikasi versi yang diperlukan dengan memeriksa paket mana yang memerlukan versi yang lebih baru:

    dotnet list package --include-transitive | Select-String "Newtonsoft.Json"
    
  2. Perbarui versi paket terpusat Anda agar sesuai atau melebihi versi tertinggi yang diperlukan:

    <PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
    
  3. Bersihkan dan bangun kembali:

    dotnet clean
    dotnet restore
    dotnet build
    

Kompatibilitas Versi

Tabel berikut menunjukkan versi aman minimum yang direkomendasikan dari Newtonsoft.Json untuk setiap versi Cosmos DB SDK. Meskipun SDK secara teknis dapat bekerja dengan 10.x, versi ini tidak boleh digunakan karena kerentanan keamanan.

Versi Cosmos DB SDK Versi Aman Minimum Recommended
3.47.0+ 13.0.3 13.0.4
3.54.0+ 13.0.4 13.0.4

Petunjuk / Saran

Saat menggunakan .NET Aspire 13.0.0 atau yang lebih baru, pastikan Newtonsoft.Json berada di versi 13.0.4 untuk menghindari konflik dengan komponen Azure Aspire.

Praktik Terbaik

  • Selalu tambahkan sebagai dependensi langsung - SDK tidak secara otomatis mengelola dependensi ini untuk Anda
  • Gunakan versi 13.0.3 atau yang lebih tinggi - Jangan pernah menggunakan 10.x meskipun kompatibilitas teknis, karena kerentanan keamanan yang diketahui
  • Diperlukan bahkan dengan System.Text.Json - Anda harus menyertakan Newtonsoft.Json bahkan saat menggunakan UseSystemTextJsonSerializerWithOptions, karena SDK menggunakannya secara internal untuk jenis sistem
  • Sematkan versi secara eksplisit - Jangan mengandalkan resolusi dependensi transitif
  • Peringatan pemantauan - Perlakukan peringatan penurunan paket NuGet (NU1109) sebagai kesalahan dalam alur CI/CD

Operasi Query

Untuk operasi kueri, lihat petunjuk performa untuk kueri.

Kebijakan pengindeksan

Mengecualikan jalur yang tidak digunakan dari pengindeksan untuk penulisan yang lebih cepat

Kebijakan pengindeksan Azure Cosmos DB juga memungkinkan Anda menentukan jalur dokumen mana yang akan disertakan atau dikecualikan dari pengindeksan dengan menggunakan jalur pengindeksan (IndexingPolicy.IncludedPaths dan IndexingPolicy.ExcludedPaths).

Hanya mengindeks jalur yang Anda butuhkan dapat meningkatkan performa tulis, mengurangi biaya RU pada operasi tulis, dan mengurangi penyimpanan indeks ketika pola kueri telah diketahui. Ini karena biaya pengindeksan berkorelasi langsung dengan jumlah jalur unik yang diindeks. Misalnya, kode berikut menunjukkan cara mengecualikan seluruh bagian dokumen (subtree) dari pengindeksan dengan menggunakan * kartubebas:

var containerProperties = new ContainerProperties(id: "excludedPathCollection", partitionKeyPath: "/pk" );
containerProperties.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
containerProperties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/nonIndexedContent/*");
Container container = await this.cosmosDatabase.CreateContainerAsync(containerProperties);

Untuk informasi selengkapnya, lihat kebijakan pengindeksan Azure Cosmos DB.

Daya Tampung

Ukur dan setel untuk penggunaan RU/s lebih rendah

Azure Cosmos DB menawarkan serangkaian operasi database yang kaya. Operasi ini termasuk kueri relasional dan hierarkis dengan fungsi yang ditentukan pengguna (UDF), prosedur tersimpan, dan pemicu, semua beroperasi pada dokumen dalam koleksi database.

Biaya yang terkait dengan masing-masing operasi ini bervariasi berdasarkan CPU, IO, dan memori yang dibutuhkan untuk menyelesaikan operasi. Alih-alih memikirkan dan mengelola sumber daya perangkat keras, Anda dapat menganggap request unit (RU) sebagai ukuran tunggal untuk sumber daya yang diperlukan untuk melakukan berbagai operasi database untuk melayani permintaan.

Throughput disediakan berdasarkan jumlah Unit Permintaan yang ditetapkan untuk setiap kontainer. Konsumsi RU dievaluasi sebagai tingkat unit per detik. Aplikasi yang melebihi tingkat RU yang telah disediakan untuk kontainer mereka akan dibatasi hingga tingkatnya turun di bawah tingkat yang telah disediakan untuk kontainer tersebut. Jika aplikasi Anda memerlukan tingkat throughput yang lebih tinggi, Anda dapat meningkatkan throughput dengan menyediakan lebih banyak RU.

Kompleksitas kueri memengaruhi berapa banyak RU yang digunakan untuk operasi. Jumlah predikat, sifat predikat, jumlah file UDF, dan ukuran set data sumber memengaruhi biaya operasi kueri.

Untuk mengukur overhead operasi apa pun (membuat, memperbarui, atau menghapus), periksa header x-ms-request-charge (atau properti yang setara RequestCharge di ResourceResponse<T> atau FeedResponse<T> di .NET SDK) untuk mengukur jumlah RU yang digunakan oleh operasi:

// Measure the performance (Request Units) of writes
ItemResponse<Book> response = await container.CreateItemAsync<Book>(myBook, new PartitionKey(myBook.PkValue));
Console.WriteLine("Insert of item consumed {0} request units", response.RequestCharge);
// Measure the performance (Request Units) of queries
FeedIterator<Book> queryable = container.GetItemQueryIterator<ToDoActivity>(queryString);
while (queryable.HasMoreResults)
    {
        FeedResponse<Book> queryResponse = await queryable.ExecuteNextAsync<Book>();
        Console.WriteLine("Query batch consumed {0} request units", queryResponse.RequestCharge);
    }

Biaya permintaan yang dikembalikan di header ini adalah sebagian kecil dari throughput yang telah Anda sediakan, yakni 2.000 RU/s. Misalnya, jika kueri sebelumnya mengembalikan 1.000 dokumen 1-KB, biaya operasinya adalah 1.000. Jadi, dalam satu detik, server hanya mengindahkan dua permintaan tersebut sebelum membatasi tarif permintaan selanjutnya. Untuk informasi selengkapnya, lihat Unit Permintaan dan kalkulator Unit Permintaan.

Tangani pembatasan laju/laju permintaan yang terlalu tinggi

Ketika klien mencoba melebihi throughput yang dipesan untuk akun, tidak ada penurunan kinerja di server dan tidak ada penggunaan kapasitas throughput di luar tingkat yang dipesan. Server secara mandiri mengakhiri permintaan dengan RequestRateTooLarge (kode status HTTP 429). Ini mengembalikan header x-ms-retry-after-ms yang menunjukkan jumlah waktu, dalam milidetik, yang harus ditunggu pengguna sebelum mencoba permintaan lagi.

    HTTP Status 429,
    Status Line: RequestRateTooLarge
    x-ms-retry-after-ms :100

SDK-SDK tersebut secara implisit menangani respons ini, mematuhi header coba-lagi yang ditentukan server, dan mengirim ulang permintaan. Kecuali akun Anda diakses secara bersamaan oleh beberapa klien, percobaan berikutnya akan berhasil.

Jika Anda memiliki lebih dari satu klien yang secara kumulatif beroperasi secara konsisten di atas tingkat permintaan, jumlah pengulangan bawaan yang diatur ke 9 mungkin tidak cukup. Dalam hal ini, klien melempar CosmosException dengan kode status 429 ke aplikasi.

Anda dapat mengubah jumlah coba ulang default dengan mengatur RetryOptions pada instans CosmosClientOptions. Secara default, CosmosException dengan kode status 429 dikembalikan setelah waktu tunggu kumulatif 30 detik jika permintaan terus beroperasi di atas tingkat permintaan. Kesalahan ini akan dikembalikan bahkan ketika jumlah coba ulang saat ini kurang dari jumlah coba ulang maksimum, terlepas dari apakah nilai saat ini adalah nilai default sebesar 9 atau nilai yang ditentukan oleh pengguna.

Perilaku coba ulang otomatis membantu meningkatkan ketahanan dan kegunaan untuk sebagian besar aplikasi. Tapi itu mungkin bukan perilaku terbaik untuk melakukan tolok ukur kinerja, terutama ketika Anda mengukur latensi. Latensi yang diamati oleh klien akan melonjak jika eksperimen mencapai batas server dan menyebabkan SDK klien melakukan percobaan ulang tanpa pemberitahuan. Untuk menghindari lonjakan latensi selama eksperimen kinerja, ukur muatan yang dikembalikan oleh setiap operasi, dan pastikan bahwa permintaan beroperasi di bawah tingkat permintaan yang telah dicadangkan.

Untuk informasi selengkapnya, lihat Unit Permintaan.

Untuk throughput yang lebih tinggi, rancang dokumen yang lebih kecil

Biaya permintaan (yaitu, biaya pemrosesan permintaan) dari operasi tertentu berkorelasi langsung dengan ukuran dokumen. Operasi pada dokumen besar lebih mahal daripada operasi pada dokumen kecil.

Langkah selanjutnya