Ne kadar zorlu olursanız olun, RAM'e sığmayan MongoDB ve veri setleri


12

Bu çok sisteme bağlıdır, ancak bazı keyfi uçurumların ötesine geçip Gerçek Sorun'a girme şansımız neredeyse kesindir. İyi bir RAM / Disk alanı oranı için ne tür kurallar olduğunu merak ediyorum. Bir sonraki sistem turumuzu planlıyoruz ve RAM, SSD'ler ve her yeni düğümden ne kadar alacağına dair bazı seçimler yapmamız gerekiyor.

Ama şimdi bazı performans detayları için!

Tek bir proje çalışmasının normal iş akışı sırasında, MongoDB çok yüksek yazma yüzdesi (% 70-80) ile vurulur. İşleme boru hattının ikinci aşaması isabet ettiğinde, işlemenin ilk yarısında tanımlanan kayıtları tekilleştirmesi gerektiğinden son derece yüksek bir okuma olur. Bu, "çalışma setinizi RAM'de saklayın" için yapılan iş akışıdır ve bu varsayımı etrafında tasarlıyoruz.

Tüm veri kümesine, son kullanıcı kaynaklı kaynaklardan rastgele sorgular gönderilir; sıklık düzensiz olsa da, boyut genellikle oldukça küçüktür (10 belgeden oluşan gruplar). Bu kullanıcı tarafından karşılandığından, yanıtların 3 saniyelik "şimdi sıkılmış" eşiği altında olması gerekir. Bu erişim kalıbının önbellekte olma olasılığı daha düşüktür, bu nedenle disk isabetlerine maruz kalma olasılığı çok yüksektir.

İkincil bir işleme iş akışı, günler, haftalar, hatta aylar öncesine ait olan ve nadiren çalıştırılan ancak yine de hareketli olması gereken önceki işleme çalışmalarının okunmasıdır. Önceki işleme çalışmasındaki belgelerin% 100'üne kadar erişilir. Hiçbir önbellek ısıtması bu konuda yardımcı olamaz, sanırım.

Biten belge boyutları büyük ölçüde değişir, ancak medyan boyutu yaklaşık 8K'dır.

Normal proje işlemenin yüksek oranda okunan kısmı, Okuma trafiğinin dağıtılmasına yardımcı olması için Çoğaltmaların kullanılmasını şiddetle önerir. Başka bir yerde , 1:10 RAM-GB'dan HD-GB'ye kadar yavaş diskler için iyi bir kural olduğunu okudum , Ciddi daha hızlı SSD kullanmayı düşündüğümüz için, benzer bir kural olup olmadığını bilmek istiyorum diskler için başparmak simgesi.

Mongo'yu önbellek-her şeyin gerçekten uçmayacağı bir şekilde kullandığımızı biliyorum, bu yüzden böyle bir kullanımdan kurtulabilecek bir sistemi tasarlamanın yollarını arıyorum. Tüm veri kümesi olasılıkla yarım yıl içinde TB en olacak ve büyümeye devam edecektir.


İyi sorulan zor bir soru.
gWaldo

IO için dürüstçe ayarlayabilmeniz için muhtemelen yazma kilidi problemlerine çarpacağınız anlaşılıyor. DB'yi yazarlarla çekiçlerseniz, temel IO'nun ne kadar hızlı olduğuna bakılmaksızın sorguların duracak kadar uzun yazma kilitleri tutabilirsiniz. Fusion IO gibi bir şey yazma kilidini biraz kesebilir, ancak sadece biraz zaman alır, gerçek bir düzeltme değildir.
MrKurt

@MrKurt Anlamaya çalıştığım şeylerden biri, tek tek çoğaltma düğümlerini nasıl yapabileceğime ek olarak parçalanmam gerektiğinde. Geçici şartımda PCIe tabanlı bir SSD kartı var.
sysadmin1138

Ah, anladım. En baştan kırmayı düşünebilirsiniz, çok sayıda tek sunucu dağıtırız. Yazma kilidinin etrafından dolaşmanızı ve yazmaları toplam çekirdeklerinize etkili bir şekilde ölçeklendirmenizi sağlar. Ayrıca, parçaları daha sonra sunucular arasında taşımak kolaydır.
MrKurt

Yanıtlar:


5

Bu bir sürü küçük nokta olacak. Ancak ne yazık ki sorunuzun tek bir cevabı yok.

MongoDB, işletim sistemi çekirdeğinin bellek yönetimini yönetmesine izin verir. Soruna mümkün olduğunca çok RAM atmanın yanı sıra, Çalışma Setinizi 'aktif olarak yönetmek' için yapılabilecek sadece birkaç şey vardır.

Yazmaları optimize etmek için yapabileceğiniz tek şey, ilk önce o kayıt için sorgulama yapmak (bir okuma yapmak), böylece çalışma belleğinde. Bu, işlem genelinde Global Lock (v2.2'de db başına olması beklenen) ile ilgili performans sorunlarını önleyecektir.

RAM ve SSD oranının zor ve hızlı bir kuralı yoktur, ancak SSD'lerin ham IOPS'sinin çok daha düşük bir oranla gitmenize izin vermesi gerektiğini düşünüyorum. Başımın üstünden, 1: 3 muhtemelen gitmek istediğiniz en düşük değerdir. Ancak daha yüksek maliyetler ve daha düşük kapasiteler göz önüne alındığında, bu oranı yine de düşük tutmanız gerekecektir.

'Yazma Okuma Okuma aşamalarına karşı' ile ilgili olarak, bir kayıt yazıldıktan sonra nadiren güncellendiğini ("güncellenmiş") doğru okuyor muyum? Bu durumda, iki kümeye ev sahipliği yapmak faydalı olabilir; normal yazma kümesi ve [X zaman diliminde] değiştirilmemiş "eskimiş" veriler için okuma için optimize edilmiş küme . Kesinlikle bu kümede slave okumayı etkinleştirirdim. (Şahsen, db'nizin nesne belgelerine tarih değiştirilmiş bir değer ekleyerek bunu başarabilirim.)

Prod'a girmeden önce yükleme testi yapabiliyorsanız, cehennemi izleyin. MongoDB, çoğunlukla VM'lere (referans sistemleri EC2'de) dağıtılacağı varsayımıyla yazılmıştır, bu nedenle VM'lere atmaktan korkmayın.


İşleme sırasında bir başlangıç ​​belge saplaması oluşturulur ve ardından işlemenin ilk bölümünde çeşitli alt aşamalarla sürekli olarak güncellenir. Yaptığımız genişletme miktarını azaltmak için ilk oluşturmada el dolgusu yapma olasılığını tartıyoruz, ancak mevcut yazma kilidi yüzdemiz mutlu bir şekilde düşük.
sysadmin1138

Bir kaydı RAM'e almak için yazmadan önce okuma tavsiyesi iyi bir tavsiye değildir. 2.0'dan beri (2011 ortası) MongoDB erişilecek verilere RAM'de değilse veri sağlıyor, bu yüzden eğer kilit gelmediğinden bunu yaparsanız iyi bir sebeple sunucuya fazladan bir okuma ve ekstra bir tur atmaya neden oluyorsunuz. Zaten bu süre boyunca tutulmaz.
Asya Kamsky

13

Bu, burada yayınlanan diğer ilgili unsurların çoğunu tartışan, burada yayınlanan diğer cevaplara bir ek olarak tasarlanmıştır. Bununla birlikte, rastgele erişim tipi bir sistemde etkin RAM kullanımı söz konusu olduğunda, genellikle gözden kaçan başka bir faktör daha vardır.

Geçerli ayarları (Linux'ta) çalıştırarak kontrol edebilirsiniz blockdev --report(genellikle sudo / root ayrıcalıkları gerektirir). Bu, her disk aygıtı için bir satır içeren bir tablo yazdırır. RA sütunu, readahead değerini içerir. Bu değer, her biri okunan 512 bayt sektör sayısıdır (sektör boyutu varsayılan değilse - bu yazının yazıldığı andan itibaren, daha büyük boyutlara sahip disklerin bile çekirdek tarafından 512 bayt sektör olarak kabul edildiğini unutmayın) disk erişimi.

Belirli bir disk aygıtı için okuma kafası ayarını aşağıdakileri çalıştırarak yapabilirsiniz:

blockdev --setra <value> <device name>

Yazılım tabanlı bir RAID sistemi kullanırken, her disk aygıtında ve RAID denetleyicisine karşılık gelen aygıtta okuma başlığını ayarladığınızdan emin olun.

Bu neden önemli? Readahead, MongoDB'nin okumalarınızı sıralı erişim için optimize etmek için kullandığı aynı kaynağı kullanıyor - RAM. Dönen disklerde (veya yine de dönen diskler gibi bir şey yapan cihazlarda - EBS sana bakıyorum) sıralı okumalar yaparken, yakındaki verileri RAM'e getirmek performansı büyük ölçüde artırabilir, sizi aramalardan kurtarabilir ve doğru ortam size etkileyici sonuçlar verebilir.

Erişiminizin genellikle bir veri kümesi boyunca rasgele erişim olacağı MongoDB gibi bir sistem için bu sadece başka yerlerde daha iyi kullanılan belleği boşa harcar. Başka bir yerde bahsedildiği gibi MongoDB için belleği de yöneten sistem, talep edildiğinde okuyucusuna bir bellek ayıracak ve böylece MongoDB'nin etkin bir şekilde kullanması için daha az RAM bırakacaktır.

Doğru okuma kafası boyutunu seçmek zordur ve donanımınıza, yapılandırmanıza, blok boyutuna, şerit boyutuna ve verilerin kendisine bağlıdır. Örneğin SSD'lere geçerseniz, düşük bir ayar isteyeceksiniz, ancak ne kadar düşük verilere bağlı olacaktır.

Açıklamak için: okuyucunun tam tek bir belgeyi çekecek kadar yüksek olduğundan ve diske geri dönmek zorunda olmadığından emin olmak istersiniz. Bahsettiğiniz ortalama 8k büyüklüğüne bakalım - diskteki sektörler genellikle 512 bayt olduğundan, belgenin tamamını okuma kafası olmadan okumak için 16 disk erişimi gerekir. 16 veya daha fazla sektörden oluşan bir sunumunuz olsaydı, belgenin tamamını yalnızca bir disk gezisi ile okurdunuz.

Aslında, MongoDB dizin kovaları 8k olduğundan, yine de readahead'i 16'nın altına ayarlamak istemeyeceksiniz ya da bir dizin grubunda okumak için 2 disk erişimi gerekecektir. Genel olarak iyi bir uygulama mevcut ayarınızla başlamak, yarıya indirmek, sonra RAM kullanımınızı ve IO'nuzu yeniden değerlendirip oradan devam etmektir.


1
Evde bazı donanımlar aldığımızda kesinlikle kullanışlı olacak değerli bilgiler. Teşekkürler!
sysadmin1138

3

Son kullanıcı sorguları için kopyaları kullanmayı ve iş akışınızı diğer makinelerde gerçekleştirmeyi düşünmelisiniz.

1:10 temel kuralınızı kullanarak, 1 TB disk depolama alanı için yaklaşık 128 GB RAM'e bakıyorsunuz; Bugün bazı uygun fiyatlı SSD'ler> 60K IOPS'a ulaştığını iddia etse de, gerçek dünya sayıları biraz farklı olabilir, ayrıca RAID'i SSD'lerinizle kullanıp kullanmadığınız ve olmamanız ve RAID kartı da son derece önemlidir. .

Bu yazı sırasında, 128 GB DDR3 ECC ram'dan 256 GB'a geçmek, 1U Intel sunucusunda yaklaşık 2000 $ ekstra gibi görünüyor ve bu size 1 TB veri ile 1: 5 oranını verecek. daha iyi bir oran. İş yükünüzün olabildiğince hızlı bitirilmesine ihtiyacınız varsa, daha fazla RAM kesinlikle yardımcı olacaktır, ancak gerçekten bu kadar acil mi?

Ext4'te "noatime, data = writeback, nobarrier" gibi bir dosya sistemi ayarlaması yapmanız gerekecek ve çekirdeğinizden çıkarabileceğiniz en yüksek performansı sıkmak için bazı çekirdek ayarları ayarlarını yapmanız gerekebilir. sistemi.

RAID ile gidiyorsanız, RAID-10 oldukça iyi bir seçim olacaktır ve uygun RAID denetleyicisi ile oldukça performans artışı sunacak, ancak kullanılabilir alanınızı yarıya indireceksiniz. Ayrıca, kullanılabilir alanınızı yarıya indirmeden iyi bir performans artışı istiyorsanız RAID50'ye bakabilirsiniz. Bir RAID çalıştırma riski, artık sürücülerinizde TRIM'e erişememenizdir, bu da her seferinde verilerinizi dışarı taşımak, RAID'i kırmak, sürücüleri TRIM yapmak ve RAID'i yeniden oluşturmak zorunda olduğunuz anlamına gelir.

Sonuç olarak, ne kadar karmaşıklık istediğinize, ne kadar para harcamak istediğinize ve iş yükünüzün ne kadar hızlı işlenmesini istediğinize karar vermeniz gerekir. MongoDB'nin kullanmak için ideal veritabanı olup olmadığını da değerlendiririm, çünkü hızlı yanıtlar gerektiren son kullanıcı sorguları için Mongo'yu kullanabilirsiniz, ancak birkaç saniye içinde hazır olması gerekmeyen verilerinizi işlemek için başka bir şey kullanın. Ayrıca, iş yükünüzü birden çok makineye daha kolay bir şekilde yaymanıza olanak tanır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.