Tips performa untuk Azure Cosmos DB Java SDK v4

BERLAKU UNTUK: API SQL

Penting

Tips performa dalam artikel ini hanya untuk Azure Cosmos DB Java SDK v4. Silakan lihat Catatan rilis Azure Cosmos DB Java SDK v4, repositori Maven, dan panduan pemecahan masalah Azure Cosmos DB Java SDK v4 untuk informasi selengkapnya. Jika saat ini Anda menggunakan versi yang lebih lama dari v4, lihat panduan Migrasi ke Azure Cosmos DB Java SDK v4 untuk bantuan peningkatan ke v4.

Azure Cosmos DB adalah database terdistribusi yang cepat dan fleksibel yang menskalakan secara mulus dengan latensi dan throughput terjamin. Anda tidak perlu membuat perubahan arsitektur besar atau menulis kode kompleks untuk menskalakan database dengan Azure Cosmos DB. Meningkatkan dan menurunkan skala semudah membuat satu panggilan API atau panggilan metode SDK. Namun karena Azure Cosmos DB diakses melalui panggilan jaringan, terdapat pengoptimalan sisi klien yang dapat Anda lakukan untuk mencapai performa puncak saat menggunakan Azure Cosmos DB Java SDK v4.

Jadi, jika Anda bertanya "Bagaimana cara meningkatkan performa database saya?" pertimbangkan opsi berikut:

Jaringan

  • Mode koneksi: Menggunakan mode Langsung

Mode koneksi default Java SDK adalah langsung. Anda dapat mengonfigurasi mode koneksi di penyusun klien menggunakan metode directMode() atau gatewayMode() , seperti yang ditunjukkan di bawah ini. Untuk mengonfigurasi salah satu mode dengan pengaturan default, panggil salah satu metode tanpa argumen. Jika tidak, berikan instans kelas pengaturan konfigurasi sebagai argumen(DirectConnectionConfig untuk directMode() , GatewayConnectionConfig untuk gatewayMode() .). Untuk mempelajari selengkapnya tentang opsi konektivitas yang berbeda, lihat artikel mode konektivitas.

Java V4 SDK

Java SDK V4 (Maven com.azure::azure-cosmos) API Asinkron


/* Direct mode, default settings */
CosmosAsyncClient clientDirectDefault = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .directMode()
        .buildAsyncClient();

/* Direct mode, custom settings */
DirectConnectionConfig directConnectionConfig = DirectConnectionConfig.getDefaultConfig();

// Example config, do not use these settings as defaults
directConnectionConfig.setMaxConnectionsPerEndpoint(120);
directConnectionConfig.setIdleConnectionTimeout(Duration.ofMillis(100));

CosmosAsyncClient clientDirectCustom = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .directMode(directConnectionConfig)
        .buildAsyncClient();

/* Gateway mode, default settings */
CosmosAsyncClient clientGatewayDefault = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .gatewayMode()
        .buildAsyncClient();

/* Gateway mode, custom settings */
GatewayConnectionConfig gatewayConnectionConfig = GatewayConnectionConfig.getDefaultConfig();

// Example config, do not use these settings as defaults
gatewayConnectionConfig.setProxy(new ProxyOptions(ProxyOptions.Type.HTTP, InetSocketAddress.createUnresolved("your.proxy.addr",80)));
gatewayConnectionConfig.setMaxConnectionPoolSize(150);

CosmosAsyncClient clientGatewayCustom = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .gatewayMode(gatewayConnectionConfig)
        .buildAsyncClient();

/* No connection mode, defaults to Direct mode with default settings */
CosmosAsyncClient clientDefault = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .buildAsyncClient();

Metode directMode() memiliki ambil alih tambahan karena alasan berikut. Operasi sarana kontrol seperti database dan kontainer CRUD, selalu menggunakan mode Gateway; saat pengguna telah mengonfigurasi mode Langsung untuk operasi sarana data, operasi sarana kontrol menggunakan pengaturan mode Gateway default. Ini cocok untuk sebagian besar pengguna. Namun, pengguna yang menginginkan mode Langsung untuk operasi sarana data serta kesesuaian parameter mode Gateway sarana kontrol dapat menggunakan ambil alih directMode() berikut:

Java V4 SDK

Java SDK V4 (Maven com.azure::azure-cosmos) API Asinkron


/* Independent customization of Direct mode data plane and Gateway mode control plane */
DirectConnectionConfig directConnectionConfig = DirectConnectionConfig.getDefaultConfig();

// Example config, do not use these settings as defaults
directConnectionConfig.setMaxConnectionsPerEndpoint(120);
directConnectionConfig.setIdleConnectionTimeout(Duration.ofMillis(100));

GatewayConnectionConfig gatewayConnectionConfig = GatewayConnectionConfig.getDefaultConfig();

// Example config, do not use these settings as defaults
gatewayConnectionConfig.setProxy(new ProxyOptions(ProxyOptions.Type.HTTP, InetSocketAddress.createUnresolved("your.proxy.addr",80)));
gatewayConnectionConfig.setMaxConnectionPoolSize(150);

CosmosAsyncClient clientDirectCustom = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .directMode(directConnectionConfig,gatewayConnectionConfig)
        .buildAsyncClient();

  • Kolokasikan klien di wilayah Azure yang sama untuk performa

Jika memungkinkan, letakkan aplikasi apa pun yang memanggil Azure Cosmos DB di wilayah yang sama dengan database Azure Cosmos. Untuk perbandingan perkiraan, panggilan ke Azure Cosmos DB dalam wilayah yang sama selesai dalam 1-2 ms, tetapi latensi antara pantai Barat dan Timur AS >50 ms. Latensi ini dapat bervariasi dari permintaan ke permintaan tergantung pada rute yang diambil oleh permintaan saat melewati dari klien ke batas pusat data Azure. Latensi serendah mungkin dicapai dengan memastikan aplikasi panggilan berada di wilayah Azure yang sama dengan titik akhir Azure Cosmos DB yang tersedia. Untuk daftar wilayah yang tersedia, lihat Wilayah Azure.

Ilustrasi kebijakan koneksi Azure Cosmos DB

Aplikasi yang berinteraksi dengan akun Azure Cosmos DB multiwilayah perlu mengonfigurasi lokasi pilihan untuk memastikan bahwa permintaan menuju ke wilayah yang dikolokasikan.

  • Aktifkan Jaringan yang Dipercepat di Azure VM Anda untuk latensi yang lebih rendah.

Disarankan agar Anda mengikuti instruksi untuk mengaktifkan Jaringan yang Dipercepat di Azure VM Windows Anda (klik untuk instruksi) atau Linux (klik untuk instruksi) untuk memaksimalkan kinerja.

Tanpa jaringan yang dipercepat, IO yang transit antara Azure VM dan sumber daya Azure lainnya mungkin tidak perlu dirutekan melalui host dan tombol virtual yang terletak di antara VM dan kartu jaringannya. Memiliki host dan tombol virtual sebaris di datapath tidak hanya meningkatkan latensi dan jitter di saluran komunikasi, tetapi juga mencuri siklus CPU dari VM. Dengan jaringan yang dipercepat, VM berinteraksi langsung dengan NIC tanpa perantara; detail kebijakan jaringan apa pun yang ditangani oleh host dan tombol virtual sekarang ditangani dalam perangkat keras di NIC; host dan tombol virtual dilewati. 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 yang dipercepat harus didukung pada OS VM dan hanya dapat diaktifkan ketika VM dihentikan dan dibatalkan alokasinya. VM tidak dapat diterapkan dengan Azure Resource Manager.

Silakan lihat instruksi Windows dan Linux untuk lebih jelasnya.

Penggunaan SDK

  • Menginstal SDK terbaru

Azure Cosmos DB SDK terus ditingkatkan untuk memberikan kinerja terbaik. Lihat halaman Azure Cosmos DB SDK untuk menentukan SDK terbaru dan meninjau peningkatan.

  • Gunakan klien database tunggal Azure Cosmos DB selama masa pakai aplikasi Anda

Setiap instans klien Azure Cosmos DB aman untuk utas dan melakukan manajemen koneksi serta penembolokan alamat yang efisien. Untuk memungkinkan manajemen koneksi yang efisien dan performa yang lebih baik oleh klien Azure Cosmos DB, disarankan untuk menggunakan satu instans klien Azure Cosmos DB per AppDomain selama masa pakai aplikasi.

  • Gunakan tingkat konsistensi terendah yang diperlukan untuk aplikasi Anda

Saat Anda membuat CosmosClient, konsistensi default yang digunakan jika tidak diatur secara eksplisit adalah Sesi. Jika konsistensi Sesi tidak diperlukan oleh logika aplikasi Anda, atur Konsistensi ke Eventual. Catatan: disarankan untuk menggunakan setidaknya konsistensi Sesi dalam aplikasi yang menggunakan prosesor Umpan Perubahan Azure Cosmos DB.

  • Gunakan API Asinkron untuk memaksimalkan throughput yang tersedia

Azure Cosmos DB Java SDK v4 menggabungkan dua API, Sinkron dan Asinkron. Secara kasar, API Asinkron mengimplementasikan fungsionalitas SDK, sedangkan API Sinkron adalah pembungkus tipis yang membuat panggilan pemblokiran ke API Asinkron. Ini berbeda dengan Azure Cosmos DB Java SDK v2 Asinkron yang lebih lama yang hanya Asinkron dan untuk Azure Cosmos DB Java SDK v2 Sinkron yang lebih lama yang hanya Sinkron dan memiliki implementasi yang benar-benar terpisah.

Pilihan API ditentukan selama inisialisasi klien; CosmosAsyncClient mendukung API Asinkron, sementara CosmosClient mendukung API Sinkron.

API Asinkron mengimplementasikan IO non-pemblokiran dan merupakan pilihan optimal jika tujuan Anda adalah memaksimalkan throughput saat mengeluarkan permintaan ke Azure Cosmos DB.

Menggunakan API Sinkron dapat menjadi pilihan yang tepat jika Anda menginginkan atau memerlukan API yang memblokir respons untuk setiap permintaan atau jika operasi sinkron adalah paradigma dominan dalam aplikasi Anda. Misalnya, Anda mungkin menginginkan API Sinkron saat Anda menyimpan data ke Azure Cosmos DB dalam aplikasi layanan mikro, asalkan throughput tidak penting.

Ketahuilah bahwa throughput API Sinkron menurun dengan meningkatnya waktu respons permintaan, sedangkan API Asinkron dapat memenuhi kemampuan bandwidth penuh perangkat keras Anda.

Kolokasi geografis dapat memberi Anda throughput yang lebih tinggi dan lebih konsisten saat menggunakan API Sinkron (lihat Kolokasikan klien di wilayah Azure yang sama untuk performa), tetapi masih tidak diharapkan untuk melebihi throughput yang dapat dicapai API Asinkron.

Beberapa pengguna mungkin juga tidak terbiasa dengan Project Reactor, kerangka kerja Reactive Streams yang digunakan untuk mengimplementasikan Azure Cosmos DB Java SDK v4 API Asinkron. Jika ini menjadi perhatian, kami sarankan Anda membaca pengantar Panduan Pola Reaktor kami, lalu lihat Pengantar Pemrograman Reaktif ini untuk membiasakan diri. Jika Anda telah menggunakan Azure Cosmos DB dengan antarmuka Asinkron dan SDK yang Anda gunakan adalah Azure Cosmos DB Java SDK v2 Asinkron, maka Anda mungkin familier dengan ReactiveX/RxJava, tetapi tidak yakin apa yang berubah di Project Reactor. Dalam hal ini, silakan lihat Panduan Reaktor vs. RxJava kami untuk membiasakan diri.

Cuplikan kode berikut menunjukkan cara menginisialisasi klien Azure Cosmos DB Anda untuk API Asinkron atau operasi API Sinkron, masing-masing:

Java V4 SDK

Java SDK V4 (Maven com.azure::azure-cosmos) API Asinkron


CosmosAsyncClient client = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .buildAsyncClient();

  • Menyesuaikan ConnectionPolicy

Secara default, permintaan Cosmos DB mode Langsung dibuat melalui TCP saat menggunakan Azure Cosmos DB Java SDK v4. Mode Langsung internal menggunakan arsitektur khusus untuk mengelola sumber daya jaringan secara dinamis dan mendapatkan performa terbaik.

Di Azure Cosmos DB Java SDK v4 Asinkron, mode Langsung adalah pilihan terbaik untuk meningkatkan performa database dengan sebagian besar beban kerja.

  • Ringkasan mode Langsung

Ilustrasi arsitektur mode Langsung

Arsitektur sisi klien yang digunakan dalam mode Langsung memungkinkan pemanfaatan jaringan yang dapat diprediksi dan akses multipleks ke replika Azure Cosmos DB. Diagram di atas menunjukkan bagaimana mode Langsung merutekan permintaan klien ke replika di backend Cosmos DB. Arsitektur mode Langsung mengalokasikan hingga 10 Saluran di sisi klien per replika DB. Saluran adalah koneksi TCP yang didahului oleh buffer permintaan dengan kedalaman 30 permintaan. Saluran milik replika dialokasikan secara dinamis sesuai kebutuhan oleh Titik Akhir Layanan replika. Saat pengguna mengeluarkan permintaan dalam mode Langsung, TransportClient merutekan permintaan ke titik akhir layanan yang tepat berdasarkan kunci partisi. Permintaan Antrean buffer permintaan sebelum Titik Akhir Layanan.

  • Opsi konfigurasi untuk mode Langsung

Jika perilaku mode Langsung non-default diinginkan, buat instans DirectConnectionConfig dan sesuaikan propertinya, kemudian berikan instans properti yang disesuaikan ke metode directMode() di penyusun klien Azure Cosmos DB.

Pengaturan konfigurasi ini mengontrol perilaku arsitektur mode Langsung yang mendasari yang dibahas di atas.

Sebagai langkah pertama, gunakan pengaturan konfigurasi yang disarankan berikut di bawah ini. Opsi DirectConnectionConfig ini adalah pengaturan konfigurasi lanjutan yang dapat memengaruhi performa SDK dengan cara yang tidak terduga; kami menyarankan pengguna untuk tidak memodifikasinya, kecuali mereka merasa sangat nyaman dalam memahami keseimbangan dan itu benar-benar diperlukan. Silakan hubungi tim Azure Cosmos DB jika Anda mengalami masalah pada topik khusus ini.

Opsi konfigurasi Default
idleConnectionTimeout "PT0"
maxConnectionsPerEndpoint "130"
connectTimeout "PT5S"
idleEndpointTimeout "PT1H"
maxRequestsPerConnection "30"
  • Menyesuaikan kueri paralel untuk koleksi yang dipartisi

Azure Cosmos DB Java SDK v4 mendukung kueri paralel, yang memungkinkan Anda membuat kueri koleksi yang dipartisi secara paralel. Untuk informasi selengkapnya, lihat sampel kode yang terkait dengan bekerja dengan Azure Cosmos DB Java SDK v4. Kueri paralel dirancang untuk meningkatkan latensi kueri dan throughput melalui rekan serialnya.

  • Menyesuaikan setMaxDegreeOfParallelism:

Kueri paralel bekerja dengan membuat kueri beberapa partisi secara paralel. Namun, data dari koleksi yang dipartisi individu diambil secara serial sehubungan dengan kueri. Jadi, gunakan setMaxDegreeOfParallelism untuk mengatur jumlah partisi yang memiliki peluang maksimum untuk mencapai kueri yang paling memiliki performa, asalkan semua kondisi sistem lainnya tetap sama. Jika Anda tidak tahu jumlah partisi, Anda dapat menggunakan setMaxDegreeOfParallelism untuk mengatur angka tinggi dan sistem memilih minimum (jumlah partisi, input yang diberikan pengguna) sebagai tingkat paralelisme maksimum.

Perlu diingat bahwa kueri paralel menghasilkan manfaat terbaik jika data didistribusikan secara merata di semua partisi sehubungan dengan kueri. Jika koleksi yang dipartisi dipartisi sedemikian rupa sehingga semua atau sebagian besar data yang dikembalikan oleh kueri terkonsentrasi di beberapa partisi (dalam kasus terburuk satu partisi), maka performa kueri akan terhambat oleh partisi tersebut.

  • Menyesuaikan setMaxBufferedItemCount:

Kueri paralel dirancang untuk mengambil hasil sebelumnya saat batch hasil saat ini sedang diproses oleh klien. Pengambilan sebelumnya membantu dalam peningkatan latensi kueri keseluruhan. setMaxBufferedItemCount membatasi jumlah hasil yang diambil sebelumnya. Mengatur setMaxBufferedItemCount ke jumlah hasil yang diharapkan yang dikembalikan (atau angka yang lebih tinggi), memungkinkan kueri untuk menerima manfaat maksimum dari pengambilan sebelumnya.

Pengambilan sebelumnya bekerja dengan cara yang sama terlepas dari MaxDegreeOfParallelism dan ada satu buffer untuk data dari semua partisi.

  • Meluaskan skala beban kerja klien Anda

Jika Anda menguji pada tingkat throughput tinggi, aplikasi klien dapat menjadi penghambat karena mesin membatasi pemanfaatan 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.

Aturan praktis yang baik adalah tidak melebihi >50% pemanfaatan CPU pada server tertentu untuk menjaga latensi tetap rendah.

  • Menyesuaikan ukuran halaman untuk kueri/umpan baca untuk performa yang lebih baik

Saat melakukan pembacaan massal dokumen dengan menggunakan fungsionalitas umpan baca (misalnya, readItems) atau saat mengeluarkan kueri SQL (queryItems), hasilnya dikembalikan secara tersegmentasi jika set hasilnya terlalu besar. Secara default, hasil dikembalikan dalam gugus 100 item atau 1 MB, batas mana pun yang tercapai lebih dahulu.

Misalkan aplikasi Anda mengeluarkan kueri ke Azure Cosmos DB, dan misalkan aplikasi Anda memerlukan set hasil kueri lengkap untuk menyelesaikan tugasnya. Untuk mengurangi jumlah perjalanan pulang pergi jaringan yang diperlukan untuk mengambil semua hasil yang berlaku, Anda dapat meningkatkan ukuran halaman dengan menyesuaikan bidang header permintaan x-ms-max-item-count.

  • Untuk kueri partisi tunggal, menyesuaikan nilai bidang x-ms-max-item-count menjadi -1 (tidak ada batas ukuran halaman) memaksimalkan latensi dengan meminimalkan jumlah halaman respons kueri: baik set hasil lengkap akan kembali dalam satu halaman atau jika kueri membutuhkan waktu lebih lama dari interval batas waktu, maka set hasil lengkap akan dikembalikan dalam jumlah halaman minimum yang memungkinkan. Ini menghemat kelipatan waktu perjalanan pulang-pergi permintaan.

  • Untuk kueri lintas-partisi, mengatur bidang x-ms-max-item-count ke -1 dan menghapus batas ukuran halaman berisiko membuat SDK kewalahan dengan ukuran halaman yang tidak dapat dikelola. Dalam kasus lintas-partisi, kami sarankan untuk menaikkan batas ukuran halaman hingga beberapa nilai besar tetapi terbatas, mungkin 1000, untuk mengurangi latensi.

Di beberapa aplikasi, Anda mungkin tidak memerlukan set hasil kueri lengkap. Jika Anda hanya perlu menampilkan beberapa hasil, misalnya, jika antarmuka pengguna atau API aplikasi hanya mengembalikan 10 hasil dalam satu waktu, Anda juga dapat mengurangi ukuran halaman menjadi 10 untuk mengurangi throughput yang dikonsumsi untuk pembacaan dan kueri.

Anda juga dapat mengatur argumen ukuran halaman pilihan dari metode byPage, daripada memodifikasi bidang header REST secara langsung. Ingatlah bahwa x-ms-max-item-count atau argumen ukuran halaman pilihan byPage hanya mengatur batas atas ukuran halaman, bukan persyaratan mutlak; jadi karena berbagai alasan Anda mungkin melihat Azure Cosmos DB mengembalikan halaman yang lebih kecil dari ukuran halaman pilihan Anda.

  • Menggunakan Scheduler yang Sesuai (Hindari mencuri perulangan Event utas Netty IO)

Fungsionalitas asinkron Azure Cosmos DB Java SDK didasarkan pada IO non-pemblokiran netty. SDK menggunakan sejumlah tetap utas perulangan event netty IO (sebanyak inti CPU yang dimiliki mesin Anda) untuk menjalankan operasi IO. Flux yang dikembalikan oleh API memancarkan hasil pada salah satu utas netty perulangan event IO bersama. Jadi, penting untuk tidak memblokir utas netty perulangan event IO bersama. Melakukan pekerjaan intensif CPU atau memblokir operasi pada utas netty perulangan event IO dapat menyebabkan kebuntuan atau mengurangi throughput SDK secara signifikan.

Misalnya, kode berikut menjalankan pekerjaan intensif cpu pada utas netty IO perulangan event:

Java SDK V4 (Maven com.azure::azure-cosmos) API Asinkron


Mono<CosmosItemResponse<CustomPOJO>> createItemPub = asyncContainer.createItem(item);
createItemPub.subscribe(
        itemResponse -> {
            //this is executed on eventloop IO netty thread.
            //the eventloop thread is shared and is meant to return back quickly.
            //
            // DON'T do this on eventloop IO netty thread.
            veryCpuIntensiveWork();
        });


Setelah hasil diterima, jika Anda ingin melakukan pekerjaan intensif CPU pada hasil, Anda harus menghindari melakukannya pada utas netty IO perulangan event. Sebagai gantinya, Anda dapat memberikan Scheduler Anda sendiri untuk memberikan utas Anda sendiri untuk menjalankan pekerjaan, seperti yang ditunjukkan di bawah ini (memerlukanimport reactor.core.scheduler.Schedulers).

Java SDK V4 (Maven com.azure::azure-cosmos) API Asinkron


Mono<CosmosItemResponse<CustomPOJO>> createItemPub = asyncContainer.createItem(item);
createItemPub
        .subscribeOn(Schedulers.elastic())
        .subscribe(
                itemResponse -> {
                    //this is executed on eventloop IO netty thread.
                    //the eventloop thread is shared and is meant to return back quickly.
                    //
                    // DON'T do this on eventloop IO netty thread.
                    veryCpuIntensiveWork();
                });

Berdasarkan jenis pekerjaan Anda, Anda harus menggunakan Reactor Scheduler yang ada yang sesuai untuk pekerjaan Anda. Baca di sini Schedulers.

Untuk informasi selengkapnya tentang Azure Cosmos DB Java SDK v4, silakan lihat direktori Cosmos DB dari Azure SDK untuk monorepo Java di GitHub.

  • Mengoptimalkan pengaturan pengelogan di aplikasi Anda

Untuk berbagai alasan, Anda mungkin ingin atau perlu menambahkan pengelogan di utas yang menghasilkan throughput permintaan tinggi. Jika tujuan Anda adalah untuk sepenuhnya memenuhi throughput yang disediakan kontainer dengan permintaan yang dibuat oleh utas ini, pengoptimalan pengelogan dapat sangat meningkatkan performa.

  • Mengonfigurasi pencatat asinkron

Latensi pencatat sinkron tentu menjadi faktor dalam perhitungan latensi keseluruhan dari utas pembuat permintaan Anda. Pencatat asinkron seperti log4j2 disarankan untuk memisahkan overhead pengelogan dari utas aplikasi yang memiliki performa tinggi Anda.

  • Menonaktifkan pengelogan netty

Pengelogan pustaka netty cerewet dan perlu dimatikan (menekan masuk konfigurasi mungkin tidak cukup) untuk menghindari biaya CPU tambahan. Jika Anda tidak dalam mode penelusuran kesalahan, nonaktifkan pengelogan netty sama sekali. Jadi jika Anda menggunakan log4j untuk menghapus biaya CPU tambahan yang timbul oleh org.apache.log4j.Category.callAppenders() dari netty, tambahkan baris berikut ke basis kode Anda:

org.apache.log4j.Logger.getLogger("io.netty").setLevel(org.apache.log4j.Level.OFF);
  • Batas Sumber Daya file Terbuka OS

Beberapa sistem Linux (seperti Red Hat) memiliki batas atas jumlah file yang terbuka dan juga jumlah koneksi. Jalankan yang berikut untuk melihat batas saat ini:

ulimit -a

Jumlah file yang terbuka (nofile) harus cukup besar agar memiliki cukup ruang untuk ukuran kumpulan koneksi yang Anda konfigurasikan dan file terbuka lainnya oleh OS. Ini dapat dimodifikasi untuk memungkinkan ukuran kumpulan koneksi yang lebih besar.

Buka file limits.conf:

vim /etc/security/limits.conf

Tambahkan/modifikasi baris berikut:

* - nofile 100000
  • Tentukan kunci partisi dalam penulisan titik

Untuk meningkatkan performa penulisan titik, tentukan kunci partisi item di panggilan API penulisan titik, seperti yang ditunjukkan di bawah ini:

Java SDK V4 (Maven com.azure::azure-cosmos) API Asinkron

asyncContainer.createItem(item,new PartitionKey(pk),new CosmosItemRequestOptions()).block();

daripada hanya memberikan instans item, seperti yang ditunjukkan di bawah ini:

Java SDK V4 (Maven com.azure::azure-cosmos) API Asinkron

asyncContainer.createItem(item).block();

Yang terakhir ini didukung tetapi akan menambah latensi ke aplikasi Anda; SDK harus memilah item dan mengekstrak kunci partisi.

Kebijakan pengindeksan

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

Kebijakan pengindeksan Azure Cosmos DB memungkinkan Anda menentukan jalur dokumen mana yang akan disertakan atau dikecualikan dari pengindeksan dengan memanfaatkan Jalur Pengindeksan (setIncludedPaths dan setExcludedPaths). Penggunaan jalur pengindeksan dapat menawarkan performa tulis yang lebih baik dan penyimpanan indeks yang lebih rendah untuk skenario di mana pola kueri diketahui sebelumnya karena biaya pengindeksan secara langsung berkorelasi dengan jumlah jalur unik yang diindeks. Misalnya, kode berikut menunjukkan cara menyertakan dan mengecualikan seluruh bagian dokumen (juga dikenal sebagai subtree) dari pengindeksan menggunakan kartu bebas "*".

Java SDK V4 (Maven com.azure::azure-cosmos)


CosmosContainerProperties containerProperties = new CosmosContainerProperties(containerName, "/lastName");

// Custom indexing policy
IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);

// Included paths
List<IncludedPath> includedPaths = new ArrayList<>();
includedPaths.add(new IncludedPath("/*"));
indexingPolicy.setIncludedPaths(includedPaths);

// Excluded paths
List<ExcludedPath> excludedPaths = new ArrayList<>();
excludedPaths.add(new ExcludedPath("/name/*"));
indexingPolicy.setExcludedPaths(excludedPaths);

containerProperties.setIndexingPolicy(indexingPolicy);

ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);

database.createContainerIfNotExists(containerProperties, throughputProperties);
CosmosAsyncContainer containerIfNotExists = database.getContainer(containerName);

Untuk informasi selengkapnya, lihat kebijakan pengindeksan Azure Cosmos DB.

Throughput

  • Ukur dan sesuaikan untuk unit permintaan yang lebih rendah/penggunaan kedua

Azure Cosmos DB menawarkan set operasi database yang kaya termasuk kueri relasional dan hierarkis dengan UDF, prosedur tersimpan, dan pemicu – semuanya 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 memikirkan unit permintaan (RU) sebagai ukuran tunggal untuk sumber daya yang diperlukan untuk melakukan berbagai operasi database dan melayani permintaan aplikasi.

Throughput disediakan berdasarkan jumlah unit permintaan yang diatur untuk setiap kontainer. Konsumsi unit permintaan dievaluasi sebagai tarif per detik. Aplikasi yang melebihi tarif unit permintaan yang disediakan untuk kontainernya akan dibatasi hingga tarifnya turun di bawah tingkat yang disediakan untuk kontainer tersebut. Jika aplikasi Anda memerlukan tingkat throughput yang lebih tinggi, Anda dapat meningkatkan throughput dengan provisi unit permintaan tambahan.

Kompleksitas kueri memengaruhi berapa banyak unit permintaan yang dikonsumsi untuk sebuah operasi. Jumlah predikat, sifat predikat, jumlah UDF, dan ukuran set data sumber semuanya memengaruhi biaya operasi kueri.

Untuk mengukur overhead operasi apa pun (buat, perbarui, atau hapus), periksa header x-ms-request-charge untuk mengukur jumlah unit permintaan yang dikonsumsi oleh operasi ini. Anda juga dapat melihat properti RequestCharge yang setara di ResourceResponse <T> atau FeedResponse<T>.

Java SDK V4 (Maven com.azure::azure-cosmos) API Asinkron

CosmosItemResponse<CustomPOJO> response = asyncContainer.createItem(item).block();

response.getRequestCharge();

Biaya permintaan yang dikembalikan dalam header ini adalah sebagian kecil dari throughput tersedia Anda. Misalnya, jika Anda memiliki 2000 RU/dtk tersedia dan jika kueri sebelumnya mengembalikan 1000 dokumen 1 KB, biaya operasinya adalah 1000. Dengan demikian, dalam satu detik server hanya menerima dua permintaan seperti itu sebelum membatasi tarif permintaan selanjutnya. Untuk informasi selengkapnya, lihat Unit permintaan dan kalkulator unit permintaan.

  • Tangani pembatasan tarif/tarif permintaan yang terlalu besar

Saat klien mencoba untuk melebihi throughput yang dicadangkan untuk sebuah akun, tidak ada penurunan kinerja di server dan tidak ada penggunaan kapasitas throughput di luar tingkat yang dicadangkan. Server akan terlebih dahulu mengakhiri permintaan dengan RequestRateTooLarge (kode status HTTP 429) dan mengembalikan header x-ms-retry-after-ms yang menunjukkan jumlah waktu, dalam milidetik, yang pengguna harus menunggu sebelum mencoba kembali permintaan tersebut.

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

SDK secara implisit menangkap respons ini, mematuhi header retry-after yang ditentukan server, dan mencoba kembali permintaan tersebut. Kecuali akun Anda sedang diakses secara bersamaan oleh beberapa klien, percobaan ulang berikutnya akan berhasil.

Jika Anda memiliki lebih dari satu klien yang secara kumulatif beroperasi secara konsisten di atas tarif permintaan, jumlah percobaan ulang default yang saat ini diatur ke 9 secara internal oleh klien mungkin tidak cukup; dalam hal ini, klien melempar CosmosClientException dengan kode status 429 ke aplikasi. Jumlah percobaan ulang default dapat diubah dengan menggunakan setRetryOptions pada instans ConnectionPolicy. Secara default, CosmosClientException dengan kode status 429 dikembalikan setelah waktu tunggu kumulatif 30 detik jika permintaan terus beroperasi di atas tarif permintaan. Hal ini terjadi meskipun jumlah percobaan ulang saat ini kurang dari jumlah percobaan ulang maksimal, baik itu default 9 atau nilai yang ditentukan pengguna.

Meskipun perilaku percobaan ulang otomatis membantu meningkatkan ketahanan dan kegunaan untuk sebagian besar aplikasi, perilaku tersebut mungkin bertentangan saat melakukan tolok ukur performa, terutama saat mengukur latensi. Latensi yang diamati klien akan melonjak jika eksperimen mencapai pembatasan server dan menyebabkan SDK klien mencoba ulang secara diam-diam. Untuk menghindari lonjakan latensi selama eksperimen performa, ukur biaya yang dikembalikan oleh setiap operasi dan pastikan bahwa permintaan beroperasi di bawah tarif permintaan yang dipesan. Untuk informasi selengkapnya, lihat Unit permintaan.

  • Mendesain dokumen yang lebih kecil untuk throughput yang lebih tinggi

Biaya permintaan (biaya pemrosesan permintaan) dari operasi tertentu berkorelasi langsung dengan ukuran dokumen. Operasi pada dokumen besar lebih mahal daripada operasi untuk dokumen kecil. Idealnya, rancang aplikasi dan alur kerja Anda agar ukuran item Anda ~ 1KB, atau urutan atau besaran yang serupa. Untuk aplikasi yang sensitif terhadap latensi, item besar harus dihindari - dokumen multi-MB akan memperlambat aplikasi Anda.

Langkah berikutnya

Untuk mempelajari selengkapnya tentang mendesain aplikasi Anda untuk skala dan performa tinggi, lihat Pemartisian dan penskalaan di Azure Cosmos DB.

Mencoba melakukan perencanaan kapasitas untuk migrasi ke Azure Cosmos DB? Anda dapat menggunakan informasi tentang kluster database yang ada untuk perencanaan kapasitas.