Bagaimana cara mengkonfigurasi driver MongoDB Java MongoOptions untuk penggunaan produksi?

100

Saya telah mencari web untuk mencari praktik terbaik untuk mengkonfigurasi MongoOptions untuk driver Java MongoDB dan saya belum menemukan banyak hal selain API. Pencarian ini dimulai setelah saya menemukan kesalahan "com.mongodb.DBPortPool $ SemaphoresOut: Keluar dari semaphores untuk mendapatkan koneksi db" dan dengan meningkatkan koneksi / pengganda saya dapat memecahkan masalah itu. Saya mencari tautan ke atau praktik terbaik Anda dalam mengonfigurasi opsi ini untuk produksi.

Opsi untuk driver 2.4 meliputi: http://api.mongodb.org/java/2.4/com/mongodb/MongoOptions.html

  • autoConnectRetry
  • koneksiPerHost
  • connectTimeout
  • maxWaitTime
  • socketTimeout
  • threadsAllowedToBlockForConnectionMultiplier

Driver yang lebih baru memiliki lebih banyak opsi dan saya juga tertarik untuk mendengarnya.

Dan Polites
sumber

Jawaban:

160

Diperbarui ke 2.9:

  • autoConnectRetry berarti pengemudi akan secara otomatis mencoba menyambung kembali ke server setelah terputus secara tak terduga. Dalam lingkungan produksi, Anda biasanya menginginkan set ini menjadi true.

  • koneksiPerHost adalah jumlah koneksi fisik yang dapat dibuat oleh satu instance Mongo (tunggal sehingga Anda biasanya memiliki satu per aplikasi) yang dapat dibuat untuk proses mongod / mongos. Pada saat penulisan, driver java akan menetapkan jumlah koneksi ini pada akhirnya meskipun throughput kueri sebenarnya rendah (dalam urutan kata, Anda akan melihat statistik "koneksi" di mongostat naik hingga mencapai angka ini per server aplikasi).

    Dalam banyak kasus, tidak perlu menetapkan ini lebih tinggi dari 100, tetapi pengaturan ini adalah salah satu hal yang "mengujinya dan melihat". Perhatikan bahwa Anda harus memastikan bahwa Anda menetapkan ini cukup rendah sehingga jumlah total koneksi ke server Anda tidak melebihi

    db.serverStatus().connections.available

    Dalam produksi saat ini kami memiliki ini di 40.

  • connectTimeout . Sesuai namanya, jumlah milidetik, pengemudi akan menunggu sebelum upaya koneksi dibatalkan. Tetapkan batas waktu ke waktu yang lama (15-30 detik) kecuali ada kemungkinan realistis dan diharapkan ini akan menghalangi upaya koneksi yang berhasil. Biasanya jika upaya koneksi membutuhkan waktu lebih lama dari beberapa detik, infrastruktur jaringan Anda tidak mampu menghasilkan throughput yang tinggi.

  • maxWaitTime . Jumlah ms utas akan menunggu hingga koneksi tersedia di kumpulan koneksi, dan memunculkan pengecualian jika ini tidak terjadi tepat waktu. Pertahankan default.

  • socketTimeout . Nilai batas waktu soket standar. Setel ke 60 detik (60000).

  • threadsAllowedToBlockForConnectionMultiplier . Pengganda untuk koneksiPerHost yang menunjukkan jumlah utas yang diizinkan untuk menunggu koneksi tersedia jika kumpulan saat ini habis. Ini adalah pengaturan yang akan menyebabkan pengecualian "com.mongodb.DBPortPool $ SemaphoresOut: Keluar dari semaphores untuk mendapatkan koneksi db". Ini akan memunculkan pengecualian ini setelah antrean utas ini melebihi nilai threadsAllowedToBlockForConnectionMultiplier. Misalnya, jika koneksiPerHost adalah 10 dan nilai ini adalah 5 hingga 50 utas dapat memblokir sebelum pengecualian yang disebutkan di atas dilemparkan.

    Jika Anda mengharapkan puncak besar dalam throughput yang dapat menyebabkan antrian besar untuk sementara meningkatkan nilai ini. Kami memilikinya pada 1500 saat ini untuk alasan itu. Jika kueri Anda memuat secara konsisten melebihi server, Anda hanya perlu meningkatkan situasi perangkat keras / penskalaan yang sesuai.

  • readPreference . (DIPERBARUI, 2.8+) Digunakan untuk menentukan preferensi baca default dan menggantikan "slaveOk". Siapkan ReadPreference melalui salah satu metode pabrik kelas. Penjelasan lengkap tentang pengaturan paling umum dapat ditemukan di akhir posting ini

  • w . (DIPERBARUI, 2.6+) Nilai ini menentukan "keamanan" penulisan. Jika nilai ini -1, penulisan tidak akan melaporkan kesalahan apa pun terlepas dari kesalahan jaringan atau database. WriteConcern.NONE adalah WriteConcern yang telah ditentukan sebelumnya yang sesuai untuk ini. Jika w adalah 0 maka kesalahan jaringan akan membuat penulisan gagal tetapi kesalahan mongo tidak akan. Ini biasanya disebut sebagai penulisan "api dan lupakan" dan harus digunakan ketika kinerja lebih penting daripada konsistensi dan daya tahan. Gunakan WriteConcern.NORMAL untuk mode ini.

    Jika Anda menyetel w ke 1 atau lebih tinggi, penulisan dianggap aman. Penulisan aman melakukan penulisan dan menindaklanjutinya dengan permintaan ke server untuk memastikan penulisan berhasil atau mengambil nilai kesalahan jika tidak (dengan kata lain, ia mengirimkan perintah getLastError () setelah Anda menulis). Perhatikan bahwa hingga perintah getLastError () ini selesai, koneksi dicadangkan. Sebagai akibatnya, dan perintah tambahan, throughput akan jauh lebih rendah daripada penulisan dengan w <= 0. Dengan nilai aw tepat 1 MongoDB menjamin penulisan berhasil (atau gagal secara verifikasi) pada instance yang Anda kirimi penulisan.

    Dalam kasus kumpulan replika, Anda dapat menggunakan nilai yang lebih tinggi untuk yang akan memberi tahu MongoDB agar mengirim penulisan ke setidaknya "w" anggota kumpulan replika sebelum kembali (atau lebih tepatnya, tunggu replikasi tulisan Anda ke anggota "w" ). Anda juga dapat menyetel w ke string "mayoritas" yang memberi tahu MongoDB untuk melakukan penulisan ke sebagian besar anggota kumpulan replika (WriteConcern.MAJORITY). Biasanya Anda harus menyetel ini ke 1 kecuali Anda memerlukan kinerja mentah (-1 atau 0) atau penulisan yang direplikasi (> 1). Nilai yang lebih tinggi dari 1 berdampak besar pada throughput tulis.

  • fsync . Opsi ketahanan yang memaksa mongo untuk menyiram ke disk setelah setiap penulisan saat diaktifkan. Saya tidak pernah memiliki masalah ketahanan apa pun terkait dengan backlog tulis jadi kami memiliki ini di false (default) dalam produksi.

  • j * (BARU 2.7+) *. Boolean yang jika disetel ke true akan memaksa MongoDB menunggu grup penjurnalan berhasil berkomitmen sebelum kembali. Jika Anda telah mengaktifkan penjurnalan, Anda dapat mengaktifkan ini untuk daya tahan tambahan. Lihat http://www.mongodb.org/display/DOCS/Journaling untuk melihat apa yang didapat dari penjurnalan bagi Anda (dan mengapa Anda mungkin ingin mengaktifkan tanda ini).

ReadPreference Kelas ReadPreference memungkinkan Anda untuk mengkonfigurasi kueri instance mongod apa yang dirutekan jika Anda bekerja dengan set replika. Pilihan berikut tersedia:

  • ReadPreference.primary () : Semua pembacaan masuk ke repset utama hanya untuk anggota utama. Gunakan ini jika Anda memerlukan semua kueri untuk mengembalikan data yang konsisten (yang paling baru ditulis). Ini adalah defaultnya.

  • ReadPreference.primaryPreferred () : Semua bacaan masuk ke repset anggota utama jika memungkinkan, tetapi mungkin meminta anggota sekunder jika node utama tidak tersedia. Dengan demikian jika yang utama menjadi tidak tersedia, bacaan akhirnya menjadi konsisten, tetapi hanya jika yang utama tidak tersedia.

  • ReadPreference.secondary () : Semua pembacaan masuk ke anggota repset sekunder dan anggota utama hanya digunakan untuk menulis. Gunakan ini hanya jika Anda dapat hidup dengan pembacaan yang pada akhirnya konsisten. Anggota repset tambahan dapat digunakan untuk meningkatkan kinerja baca meskipun ada batasan jumlah anggota (pemungutan suara) yang dapat dimiliki repset.

  • ReadPreference.secondaryPreferred () : Semua bacaan masuk ke anggota repset sekunder jika ada yang tersedia. Anggota utama digunakan secara eksklusif untuk menulis kecuali semua anggota sekunder menjadi tidak tersedia. Selain fallback ke anggota utama untuk reads, ini sama dengan ReadPreference.secondary ().

  • ReadPreference.nearest () : Membaca pergi ke anggota repset terdekat yang tersedia untuk klien database. Gunakan hanya jika pembacaan yang pada akhirnya konsisten dapat diterima. Anggota terdekat adalah anggota dengan latensi terendah antara klien dan berbagai anggota repset. Karena anggota yang sibuk pada akhirnya akan memiliki latensi yang lebih tinggi, ini juga harus secara otomatis menyeimbangkan beban baca meskipun menurut pengalaman saya sekunder (Lebih disukai) tampaknya melakukannya lebih baik jika latensi anggota relatif konsisten.

Catatan: Semua hal di atas memiliki versi yang mendukung tag dari metode yang sama yang mengembalikan instance TaggableReadPreference sebagai gantinya. Penjelasan lengkap tentang tag set replika dapat ditemukan di sini: Tag Set Replika

Remon van Vliet
sumber
6
Bukankah berbahaya untuk membiarkan socketTimeout dan connectTimeout sebagai default (tak terbatas)? Jika koneksi macet karena suatu alasan, aplikasi Anda (atau setidaknya utas itu) akan macet selamanya. Bukankah ini seharusnya disetel sebagai sangat tinggi (sekitar 30 detik untuk koneksi, 2 menit untuk soket)?
Idris Mokhtarzada
Idris, sangat benar. Di posting saya, saya salah mengasumsikan MongoOptions memiliki default kami. Layer Mongo ORM kami memiliki ini masing-masing pada 15 detik dan 1 menit dan saat menulis saya berasumsi ini adalah defaultnya. Batas waktu tak terbatas jelas merupakan ide yang buruk. Terima kasih atas perhatiannya, saya memperbaikinya di pos
Remon van Vliet
opsi "slaveOk" sekarang tidak digunakan lagi, jika Anda ingin persamaan ini menjadi benar, lakukan: mongoOptions.readPreference = ReadPreference.secondaryPreferred ();
Gubatron
Jawaban bagus tetapi definisi threadsAllowedToBlockForConnectionMultiplier Anda salah (pengganda kata kunci). Sesuai dokumen: "pengganda untuk koneksiPerHost untuk # utas yang dapat diblokir jika koneksiPerHost adalah 10, dan utasAllowedToBlockForConnectionMultiplier adalah 5, maka 50 utas dapat memblokir lebih dari itu dan pengecualian akan dilemparkan"
Tyler Zale
3
Sepertinya jawaban yang cukup populer. Jika ada yang tertarik dengan saya memperbarui ini untuk mencerminkan perubahan pada driver terbaru beri tahu saya
Remon van Vliet