Saat dalam produksi, aplikasi harus memberikan respons yang tepat waktu kepada pengguna untuk tujuan meningkatkan interaksi pengguna dengan aplikasi Anda. Namun, kadang-kadang, kueri basis data mungkin mulai tertinggal sehingga membutuhkan latensi yang lebih lama untuk respons untuk menjangkau pengguna atau lebih tepatnya operasi throughput dihentikan karena melampaui batas waktu rata-rata yang ditetapkan.
Dalam blog ini kita akan mempelajari bagaimana Anda dapat mengidentifikasi masalah ini di MongoDB, cara untuk memperbaikinya setiap kali masalah itu muncul dan strategi apa yang mungkin dilakukan agar hal ini tidak terjadi lagi.
Lebih sering, apa yang menyebabkan respons kueri yang lambat adalah penurunan kapasitas CPU yang tidak mampu menahan set kerja yang mendasarinya. Set kerja dalam hal ini adalah jumlah data dan indeks yang akan dikenakan instance throughput sehingga aktif pada saat itu. Ini terutama dipertimbangkan dalam perencanaan kapasitas ketika seseorang memperkirakan jumlah data yang terlibat akan meningkat dari waktu ke waktu dan jumlah pengguna yang terlibat dengan platform Anda.
Mengidentifikasi Masalah Kueri Lambat
Ada dua cara Anda dapat mengidentifikasi kueri lambat di MongoDB.
- Menggunakan Profiler
- Menggunakan pembantu db.currentOp()
Menggunakan Profiler MongoDB
Database profiler di MongoDB adalah mekanisme untuk mengumpulkan informasi rinci tentang Perintah Basis Data yang dijalankan terhadap instance mongod yang sedang berjalan yaitu:operasi throughput (Buat, Baca, Perbarui, dan Hapus) dan perintah konfigurasi &administrasi.
Profiler menggunakan koleksi tertutup bernama system.profile tempat ia menulis semua data. Artinya, ketika koleksi sudah penuh dalam hal ukuran, dokumen lama dihapus untuk memberi ruang bagi data baru.
Profiler dinonaktifkan secara default tetapi tergantung pada level pembuatan profil, seseorang dapat mengaktifkannya pada basis data per atau per instans. Tingkat pembuatan profil yang mungkin adalah:
- 0 - profiler tidak aktif sehingga tidak mengumpulkan data apa pun.
- 1 - profiler mengumpulkan data untuk operasi yang memakan waktu lebih lama dari nilai slowms
- 2- profiler mengumpulkan data untuk semua operasi.
Namun, mengaktifkan pembuatan profil menghasilkan dampak kinerja pada database dan penggunaan disk terutama saat tingkat pembuatan profil disetel ke 2 . Seseorang harus mempertimbangkan implikasi kinerja apa pun sebelum mengaktifkan dan mengonfigurasi profiler pada penerapan produksi.
Untuk mengatur pembuatan profil, kita menggunakan helper db.setProfilingLevel() seperti:
db.setProfilingLevel(2)
Contoh dokumen yang akan disimpan dalam koleksi system.profile adalah:
{ "was" : 0, "slowms" : 100, "sampleRate" : 1.0, "ok" : 1 }
Pasangan nilai kunci “ok”:1 menunjukkan bahwa operasi berhasil sedangkan slowms adalah waktu ambang dalam milidetik yang harus dilakukan operasi dan secara default adalah 100ms.
Untuk mengubah nilai ini
db.setProfilingLevel(1, { slowms: 50 })
Untuk melakukan kueri data terhadap koleksi system.profile jalankan:
db.system.profile.find().pretty()
Menggunakan db.currentOp()helper
Fungsi ini mencantumkan kueri yang sedang berjalan dengan informasi yang sangat mendetail seperti berapa lama kueri tersebut telah berjalan. Pada shell mongo yang sedang berjalan, Anda menjalankan komentar misalnya:
db.currentOp({“secs_running”:{$gte:5}})
Di mana secs_running adalah strategi pemfilteran sehingga hanya operasi yang membutuhkan waktu lebih dari 5 detik untuk dilakukan yang akan dikembalikan, mengurangi output. Ini sering digunakan saat kondisi CPU dapat dinilai 100% karena dampak kinerja yang merugikan yang mungkin terjadi pada database. Jadi dengan mengubah nilai, Anda akan mempelajari kueri mana yang membutuhkan waktu lama untuk dieksekusi.
Dokumen yang dikembalikan memiliki yang berikut ini sebagai kunci yang diinginkan:
- kueri :apa yang dimaksud dengan kueri
- aktif : jika kueri masih dalam proses.
- ns :nama koleksi yang digunakan untuk mengeksekusi kueri
- secs_running : durasi kueri sejauh ini dalam hitungan detik
Dengan menyorot kueri mana yang membutuhkan waktu lama, Anda telah mengidentifikasi apa yang membebani CPU.
Menafsirkan Hasil dan Memperbaiki Masalah
Seperti yang telah kami jelaskan di atas, latensi kueri sangat bergantung pada jumlah data yang terlibat, yang jika tidak, akan menyebabkan rencana eksekusi yang tidak efisien. Ini untuk mengatakan, misalnya jika Anda tidak menggunakan indeks dalam koleksi Anda dan ingin memperbarui catatan tertentu, operasi harus melalui semua dokumen daripada memfilter hanya yang cocok dengan spesifikasi kueri. Logikanya, ini akan memakan waktu lebih lama sehingga menyebabkan kueri yang lambat. Anda dapat memeriksa rencana eksekusi yang tidak efisien dengan menjalankan: explain('executionStats') yang memberikan statistik tentang performa kueri. Dari titik ini Anda dapat mempelajari bagaimana kueri menggunakan indeks selain memberikan petunjuk apakah indeks tersebut optimal.
Jika helper yang menjelaskan kembali
{
"queryPlanner" : {
"plannerVersion" : 1,
...
"winningPlan" : {
"stage" : "COLLSCAN",
...
}
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 3,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 10,
"executionStages" : {
"stage" : "COLLSCAN",
...
},
...
},
...
}
queryPlanner.winningPlan.stage:Nilai kunci COLLSCAN menunjukkan bahwa mongod harus memindai seluruh dokumen koleksi untuk mengidentifikasi hasil sehingga menjadi operasi yang mahal sehingga menyebabkan kueri lambat.
executionStats.totalKeysExamineed:0 berarti koleksi tidak menggunakan strategi pengindeksan
Untuk kueri tertentu, jumlah dokumen yang terlibat harus mendekati nol. Jika jumlah dokumen cukup besar ada dua kemungkinan:
- Tidak menggunakan pengindeksan dengan koleksi
- Menggunakan indeks yang tidak optimal.
Untuk membuat indeks untuk koleksi, jalankan perintah:
db.collection.createIndex( { quantity: 1 } )
Di mana kuantitas adalah bidang contoh yang telah Anda pilih agar optimal untuk strategi pengindeksan.
Jika Anda ingin mempelajari lebih lanjut tentang pengindeksan dan strategi pengindeksan yang digunakan, kunjungi blog ini
Kesimpulan
Penurunan kinerja basis data dapat dengan mudah digambarkan dengan memiliki kueri lambat yang merupakan harapan terkecil yang kami inginkan untuk ditemui oleh pengguna platform. Seseorang dapat mengidentifikasi kueri lambat di MongoDB dengan mengaktifkan profiler dan mengonfigurasinya ke beberapa spesifikasinya atau menjalankan db.currentOp() pada instance mongod yang sedang berjalan.
Dengan melihat parameter waktu pada hasil yang dikembalikan, kami dapat mengidentifikasi kueri mana yang tertinggal. Setelah mengidentifikasi kueri ini, kami menggunakan bantuan penjelasan pada kueri ini untuk mendapatkan detail lebih lanjut, misalnya jika kueri menggunakan indeks apa pun.
Tanpa pengindeksan, operasi menjadi mahal karena banyak dokumen perlu dipindai sebelum menerapkan perubahan. Dengan kemunduran ini, CPU akan bekerja terlalu keras sehingga menghasilkan kueri yang lambat dan lonjakan CPU yang meningkat.
Kesalahan utama yang menyebabkan kueri lambat adalah perencanaan eksekusi yang tidak efisien yang dapat dengan mudah diselesaikan dengan menggunakan indeks dengan koleksi yang terlibat.