MongoDB berakhir ketika kehabisan memori

11

Saya memiliki konfigurasi berikut:

  • mesin host yang menjalankan tiga kontainer buruh pelabuhan:
    • MongoDB
    • Redis
    • Suatu program yang menggunakan dua wadah sebelumnya untuk menyimpan data

Redis dan MongoDB digunakan untuk menyimpan sejumlah besar data. Saya tahu Redis perlu menyimpan semua datanya dalam RAM dan saya baik-baik saja dengan ini. Sayangnya, yang terjadi adalah mongo mulai mengambil banyak RAM dan segera setelah RAM host penuh (kita berbicara tentang 32GB di sini), baik mongo atau Redis crash.

Saya telah membaca pertanyaan sebelumnya tentang ini:

  1. Batasi Penggunaan MongoDB RAM : tampaknya sebagian besar RAM digunakan oleh cache WiredTiger
  2. Memori batas MongoDB : di sini rupanya masalahnya adalah data log
  3. Batasi penggunaan memori RAM di MongoDB : di sini mereka menyarankan untuk membatasi memori mongo sehingga menggunakan jumlah memori yang lebih kecil untuk cache / log / data
  4. MongoDB menggunakan terlalu banyak memori : di sini mereka mengatakan itu sistem caching WiredTiger yang cenderung menggunakan RAM sebanyak mungkin untuk menyediakan akses yang lebih cepat. Mereka juga menyatakanit's completely okay to limit the WiredTiger cache size, since it handles I/O operations pretty efficiently
  5. Apakah ada opsi untuk membatasi penggunaan memori mongodb? : caching lagi, mereka juga menambahkanMongoDB uses the LRU (Least Recently Used) cache algorithm to determine which "pages" to release, you will find some more information in these two questions
  6. Hubungan indeks MongoDB / RAM : kutipan:MongoDB keeps what it can of the indexes in RAM. They'll be swaped out on an LRU basis. You'll often see documentation that suggests you should keep your "working set" in memory: if the portions of index you're actually accessing fit in memory, you'll be fine.
  7. bagaimana cara melepaskan caching yang digunakan oleh MongoDB? : jawaban yang sama seperti pada 5.

Sekarang apa yang tampaknya saya pahami dari semua jawaban ini adalah:

  1. Untuk akses yang lebih cepat akan lebih baik bagi mongo agar sesuai dengan semua indeks dalam RAM. Namun, dalam kasus saya, saya baik-baik saja dengan indeks sebagian berada pada disk karena saya memiliki SSD yang cukup cepat.
  2. RAM sebagian besar digunakan untuk caching oleh mongo.

Mempertimbangkan hal ini, saya mengharapkan mongo untuk mencoba dan menggunakan ruang RAM sebanyak mungkin tetapi dapat berfungsi juga dengan sedikit ruang RAM dan mengambil sebagian besar hal dari disk. Namun, saya membatasi memori penampung mongo Docker (hingga 8GB misalnya), dengan menggunakan --memorydan --memory-swap, tetapi alih-alih mengambil barang dari disk, mongo langsung macet begitu kehabisan memori.

Bagaimana saya bisa memaksa mongo untuk hanya menggunakan memori yang tersedia dan untuk mengambil dari disk semua yang tidak sesuai dengan memori?

Simone Bronzini
sumber
Ini disebut pembunuh OOM. MongoDB dirancang untuk berjalan pada perangkat keras komoditas. Saya tidak pernah menjalankannya pada sumber daya yang terbatas secara artifisial. Jika Anda hanya memiliki database kecil, MongoDB bukanlah pilihan yang ideal. Jika Anda memiliki database besar (tiga angka Juta hingga miliar entri) membatasi sumber daya adalah pilihan yang buruk. Sesuai masalah Anda: Anda tidak dapat memiliki kue dan memakannya. Memilih.
Markus W Mahlberg
Jika dikonfigurasi dengan benar, MongoDB tidak akan macet saat kehabisan memori. Bisakah Anda mengonfirmasi versi spesifik server MongoDB dan O / S yang Anda gunakan dan juga menjelaskan kerusakan secara lebih rinci? Misalnya, apakah ada pesan di log MongoDB atau dmesgberkorelasi dengan shutdown yang tidak terduga? Kemungkinan yang paling mungkin dengan Docker adalah bahwa proses dalam wadah mendeteksi keseluruhan RAM yang tersedia daripada batas wadah.
Stennie
Sesuai Catatan Produksi MongoDB : jika Anda menjalankan mongoddalam wadah ( lxc,, cgroupsDocker, dll.) Yang tidak memiliki akses ke semua RAM yang tersedia dalam suatu sistem, Anda harus menetapkan storage.wiredTiger.engineConfig.cacheSizeGBnilai kurang dari jumlah RAM yang tersedia di wadah. Jumlah persisnya tergantung pada proses lain yang berjalan di dalam wadah, tetapi biasanya tidak boleh lebih dari nilai default 50% dari RAM dikurangi 1GB.
Stennie

Jawaban:

9

Sesuai MongoDB BOL Di Sini Berubah dalam versi 3.4: Nilai dapat berkisar dari 256MBhingga 10TBdan bisa a float. Selain itu, nilai default juga telah berubah.

Mulai 3.4, cache internal WiredTiger , secara default, akan menggunakan yang lebih besar dari:

50% of RAM minus 1 GB, or
256 MB.

Dengan WiredTiger, MongoDB memanfaatkan WiredTiger internal cache dan filesystem cache.

Melalui filesystem cache, MongoDB secara otomatis menggunakan semua memori bebas yang tidak digunakan oleh WiredTiger cacheatau oleh proses lain.

The storage.wiredTiger.engineConfig.cacheSizeGB membatasi ukuran WiredTigerinternal cache. Sistem operasi akan menggunakan memori bebas yang tersedia untuk cache sistem file, yang memungkinkan file data MongoDB terkompresi tetap berada dalam memori. Selain itu, operating systemakan menggunakan RAM gratis untuk buffer blok sistem file dan cache sistem file.

Untuk mengakomodasi konsumen RAM tambahan , Anda mungkin harus mengurangi WiredTigerukuran cache internal.

Untuk selanjutnya, Mesin Penyimpanan WiredTiger dan Opsi File Konfigurasi Anda

Md Haidar Ali Khan
sumber
4

Sebenarnya, jika Anda melihat lebih dekat, itu bukan mongod yang mati karena "kehabisan memori", itu adalah manajer kernel OOM (kehabisan memori) yang membunuh mongod, karena ia memiliki penggunaan memori terbesar.

Ya, Anda dapat mencoba menyelesaikan masalah dengan parameter konfigurasi monngodb cacheSizeGB , tetapi dalam lingkungan kontainer, lebih baik menggunakan cgroup untuk membatasi sumber daya yang didapat dari salah satu dari tiga kontainer Anda.

JJussi
sumber