MongoDB dan kumpulan data yang tidak sesuai dengan RAM tidak peduli seberapa keras Anda mendorong

12

Ini sangat tergantung pada sistem, tetapi kemungkinannya hampir pasti kami akan melewati beberapa tebing sewenang-wenang dan masuk ke Masalah Nyata. Saya ingin tahu seperti apa aturan yang ada untuk rasio RAM-Disk yang baik. Kami sedang merencanakan putaran sistem kami berikutnya, dan perlu membuat beberapa pilihan mengenai RAM, SSD, dan berapa banyak masing-masing node baru akan dapatkan.

Tetapi sekarang untuk beberapa detail kinerja!

Selama alur kerja normal dari satu proyek yang dijalankan, MongoDB dipukul dengan persentase menulis yang sangat tinggi (70-80%). Setelah tahap kedua dari pipa pemrosesan mencapai, itu sangat tinggi dibaca karena perlu untuk menduplikat catatan yang diidentifikasi pada paruh pertama pemrosesan. Ini adalah alur kerja yang dibuat untuk "menjaga set kerja Anda di RAM" dibuat, dan kami merancang sekitar asumsi itu.

Seluruh dataset terus-menerus dipukul dengan kueri acak dari sumber yang diturunkan pengguna akhir; walaupun frekuensinya tidak teratur, ukurannya biasanya cukup kecil (kelompok 10 dokumen). Karena ini menghadap ke pengguna, balasan harus di bawah ambang batas "bosan sekarang" 3 detik. Pola akses ini jauh lebih kecil kemungkinannya berada dalam cache, sehingga akan sangat mungkin untuk menimbulkan hit disk.

Alur kerja pemrosesan sekunder adalah pembacaan yang tinggi dari proses pemrosesan sebelumnya yang mungkin berumur berhari-hari, berminggu-minggu, atau bahkan berbulan-bulan, dan jarang dilakukan tetapi masih perlu zippy. Hingga 100% dari dokumen dalam proses pemrosesan sebelumnya akan diakses. Saya kira tidak ada jumlah pemanasan cache yang dapat membantu hal ini.

Ukuran dokumen jadi sangat bervariasi, tetapi ukuran median sekitar 8K.

Bagian membaca tinggi dari pemrosesan proyek normal sangat menyarankan penggunaan Replika untuk membantu mendistribusikan lalu lintas Baca. Saya telah membaca di tempat lain bahwa 1:10 RAM-GB ke HD-GB adalah aturan praktis yang baik untuk disk yang lambat, Karena kami serius mempertimbangkan untuk menggunakan SSD yang lebih cepat, saya ingin tahu apakah ada aturan yang sama praktis untuk disk cepat.

Saya tahu kami menggunakan Mongo dengan cara di mana cache-semuanya benar-benar tidak akan terbang, itulah sebabnya saya mencari cara untuk merekayasa sistem yang dapat bertahan dari penggunaan seperti itu. The seluruh dataset kemungkinan akan paling TB dalam waktu setengah tahun dan terus berkembang.

sysadmin1138
sumber
Sebuah pertanyaan yang sulit ditanyakan.
gWaldo
Kedengarannya seperti Anda mungkin akan mencapai masalah menulis kunci sebelum Anda dapat mendengarkan IO banyak, jujur. Jika Anda menggedor DB dengan menulis, Anda mungkin akan memegang kunci tulis cukup lama sehingga kueri akan terhenti terlepas dari seberapa cepat IO yang mendasarinya. Sesuatu seperti Fusion IO dapat mengurangi menulis sedikit, tetapi itu hanya membeli beberapa waktu, itu bukan perbaikan nyata.
MrKurt
@ MrKurt Bagian dari apa yang saya coba cari tahu adalah ketika saya harus membuang, di samping seberapa gemuk saya dapat membuat masing-masing node replika. Spesifikasi sementara saya memang melibatkan kartu SSD berbasis PCIe.
sysadmin1138
Ah, mengerti. Anda mungkin mempertimbangkan sharding dari awal, kami melakukan banyak server sharding. Ini memungkinkan Anda menjelajahi kunci tulis dan secara efektif skala menulis ke total inti Anda. Plus, mudah untuk memindahkan pecahan antar server di lain waktu.
MrKurt

Jawaban:

5

Ini akan menjadi banyak poin kecil. Sayangnya, tidak ada jawaban tunggal untuk pertanyaan Anda.

MongoDB memungkinkan kernel OS untuk menangani manajemen memori. Selain melempar RAM sebanyak mungkin pada masalah, hanya ada beberapa hal yang dapat dilakukan untuk 'secara aktif mengelola' Set Kerja Anda.

Satu hal yang dapat Anda lakukan untuk mengoptimalkan penulisan adalah dengan terlebih dahulu meminta kueri untuk catatan itu (baca), sehingga ada dalam memori yang berfungsi. Ini akan menghindari masalah kinerja yang terkait dengan Global Lock di seluruh proses (yang seharusnya menjadi per-db di v2.2)

Tidak ada aturan yang keras dan cepat untuk rasio RAM vs SSD, tetapi saya berpikir bahwa IOPS mentah SSD harus memungkinkan Anda untuk pergi dengan rasio yang jauh lebih rendah. Dari atas kepala saya, 1: 3 mungkin adalah yang terendah yang Anda inginkan. Tetapi mengingat biaya yang lebih tinggi dan kapasitas yang lebih rendah, Anda mungkin perlu menjaga rasio itu tetap rendah.

Mengenai 'fase Menulis vs Membaca', apakah saya membaca dengan benar bahwa begitu sebuah catatan ditulis, jarang diperbarui ("terangkat")? Jika itu masalahnya, mungkin ada gunanya menampung dua kelompok; cluster tulis normal, dan cluster yang dioptimalkan untuk data "berumur" yang belum dimodifikasi dalam [periode waktu X] . Saya pasti akan mengaktifkan slave-read di cluster ini. (Secara pribadi, saya akan mengaturnya dengan memasukkan nilai yang dimodifikasi tanggal dalam dokumen objek db Anda.)

Jika Anda memiliki kemampuan untuk memuat-tes sebelum masuk ke Prod, dapat memantau keluar dari itu. MongoDB ditulis dengan asumsi bahwa itu akan sering digunakan di VM (sistem referensi mereka di EC2), jadi jangan takut untuk membuang ke VM.

gWaldo
sumber
Selama pemrosesan rintisan dokumen awal dibuat dan kemudian terus diperbarui oleh berbagai sub-tahap di bagian pertama pemrosesan. Kami telah mempertimbangkan kemungkinan melakukan beberapa penangan-tangan pada ciptaan awal untuk mengurangi jumlah perluasan yang kami lakukan, tetapi persentase penguncian saat ini kami sangat rendah.
sysadmin1138
Saran untuk membaca catatan sebelum menulis untuk memasukkannya ke dalam RAM bukanlah saran yang baik. Sejak 2.0 (pertengahan 2011) MongoDB telah menghasilkan jika data yang akan diakses tidak dalam RAM sehingga Anda hanya menyebabkan pembacaan tambahan dan perjalanan pulang-pergi ekstra ke server tanpa alasan yang baik jika Anda melakukannya sejak kunci tidak Bagaimanapun juga akan diadakan selama durasi itu.
Asya Kamsky
13

Ini dimaksudkan sebagai tambahan untuk jawaban lain yang diposting di sini, yang membahas banyak elemen yang relevan untuk dipertimbangkan di sini. Namun, ada faktor lain yang sering diabaikan, dalam hal pemanfaatan RAM yang efisien dalam sistem tipe akses acak - readahead.

Anda dapat memeriksa pengaturan saat ini untuk readahead (di Linux) dengan menjalankan blockdev --report(biasanya memerlukan hak akses sudo / root). Ini akan mencetak tabel dengan satu baris untuk setiap perangkat disk. Kolom RA berisi nilai untuk readahead. Nilai itu adalah jumlah sektor 512 byte (kecuali ukuran sektor bukan default - perhatikan bahwa pada saat penulisan posting ini, bahkan disk yang memiliki ukuran lebih besar diperlakukan sebagai sektor 512 byte oleh kernel) yang dibaca pada setiap akses disk.

Anda dapat mengatur pengaturan readahead untuk perangkat disk yang diberikan dengan menjalankan:

blockdev --setra <value> <device name>

Saat menggunakan sistem RAID berbasis perangkat lunak, pastikan untuk mengatur readahead pada setiap perangkat disk serta pada perangkat yang sesuai dengan pengontrol RAID.

Mengapa ini penting? Nah, readahead menggunakan sumber daya yang sama yang coba digunakan MongoDB untuk mengoptimalkan bacaan Anda untuk akses sekuensial - RAM. Ketika Anda melakukan pembacaan berurutan pada disk pemintalan (atau perangkat yang berperilaku seperti disk pemintalan - EBS saya sedang melihat Anda), mengambil data terdekat ke dalam RAM dapat meningkatkan kinerja secara besar-besaran, menghemat pencarian, menghemat pencarian, dan pengaturan readahead tinggi di lingkungan yang tepat dapat memberi Anda beberapa hasil yang mengesankan.

Untuk sistem seperti MongoDB di mana akses Anda umumnya akan menjadi akses acak di set data, ini hanya membuang-buang memori yang lebih baik digunakan di tempat lain. Sistem, yang seperti yang disebutkan di tempat lain mengelola memori untuk MongoDB juga, akan mengalokasikan sepotong memori untuk dibaca kembali ketika diminta dan karenanya meninggalkan lebih sedikit RAM untuk MongoDB untuk digunakan secara efektif.

Memilih ukuran readahead yang benar itu rumit dan tergantung pada perangkat keras Anda, konfigurasi, ukuran blok, ukuran garis dan data itu sendiri. Jika Anda pindah ke SSD misalnya, Anda akan menginginkan pengaturan rendah, tetapi seberapa rendah akan tergantung pada data.

Untuk menjelaskan: Anda ingin memastikan bahwa readahead cukup tinggi untuk menarik satu dokumen penuh dan tidak harus kembali ke disk. Mari kita ambil ukuran median 8k yang disebutkan - karena sektor pada disk umumnya 512 byte, dibutuhkan 16 akses disk untuk membaca seluruh dokumen tanpa readahead. Jika Anda memiliki readahead 16 sektor atau lebih, Anda akan membaca seluruh dokumen dengan hanya satu perjalanan ke disk.

Sebenarnya, karena ember indeks MongoDB adalah 8k, Anda tidak akan pernah ingin mengatur readahead di bawah 16, atau akan membutuhkan 2 akses disk untuk dibaca dalam satu ember indeks. Praktik umum yang baik adalah memulai dengan pengaturan Anda saat ini, membagi dua, kemudian menilai kembali penggunaan RAM Anda dan IO dan pindah dari sana.

Adam C
sumber
1
Informasi berharga yang pasti akan berguna setelah kami mendapatkan beberapa perangkat keras di rumah. Terima kasih!
sysadmin1138
3

Anda harus mempertimbangkan untuk menggunakan replika untuk permintaan pengguna akhir dan alur kerja Anda dilakukan pada mesin lain.

Menggunakan 1:10 aturan praktis Anda, Anda sedang mencari sekitar 128GB RAM untuk 1TB penyimpanan disk; Sementara beberapa SSD yang terjangkau saat ini mengklaim mencapai> 60K IOPS, angka dunia nyata mungkin sedikit berbeda, serta apakah Anda menggunakan RAID dengan SSD atau tidak, dan jika ya, maka kartu RAID juga sangat penting. .

Pada saat posting ini, mulai dari 128GB DDR3 ECC ram ke 256GB tampaknya menjadi sekitar $ 2.000 tambahan pada server Intel 1U, dan ini akan memberi Anda rasio 1: 5 dengan data 1TB, yang saya rasa akan menjadi rasio yang lebih baik. Jika Anda membutuhkan beban kerja secepat mungkin, lebih banyak RAM pasti akan membantu, tetapi apakah ini benar-benar mendesak?

Anda perlu melakukan beberapa penyetelan sistem file juga, seperti "noatime, data = writeback, nobarrier" pada ext4, dan Anda mungkin perlu melakukan beberapa pengaturan kernel, juga untuk memeras kinerja terbaik yang Anda bisa dari sistem.

Jika Anda menggunakan RAID, RAID-10 akan menjadi pilihan yang cukup bagus, dan dengan kontroler RAID yang tepat akan menawarkan peningkatan kinerja yang cukup, tetapi dengan membagi dua ruang yang tersedia. Anda juga dapat melihat ke RAID50 jika Anda menginginkan peningkatan kinerja yang layak tanpa mengurangi separuh ruang yang tersedia. Risiko menjalankan RAID adalah bahwa Anda tidak lagi memiliki akses ke TRIM pada drive Anda, yang berarti setiap saat Anda perlu memindahkan data Anda, memecah RAID, TRIM drive dan membuat ulang RAID.

Pada akhirnya, Anda perlu memutuskan seberapa banyak kerumitan yang Anda inginkan, berapa banyak uang yang ingin Anda belanjakan dan seberapa cepat Anda ingin beban kerja Anda diproses. Saya juga akan mengevaluasi apakah MongoDB adalah basis data yang ideal untuk digunakan, karena Anda masih bisa menggunakan Mongo untuk permintaan pengguna akhir yang membutuhkan respons cepat, tetapi menggunakan sesuatu yang lain untuk memproses data Anda, yang tidak perlu siap dalam beberapa detik. , dan itu juga memungkinkan Anda untuk menyebarkan beban kerja Anda di beberapa mesin dengan lebih mudah.

gekkz
sumber