Grundlegendes zur Größenbeschränkung für MongoDB BSON-Dokumente


153

Aus MongoDB Der endgültige Leitfaden:

Dokumente, die größer als 4 MB sind (bei Konvertierung in BSON), können nicht in der Datenbank gespeichert werden. Dies ist eine etwas willkürliche Grenze (und kann in Zukunft angehoben werden); Dies dient hauptsächlich dazu, ein schlechtes Schemadesign zu verhindern und eine konsistente Leistung sicherzustellen.

Ich verstehe diese Grenze nicht. Bedeutet dies, dass ein Dokument, das einen Blog-Beitrag mit vielen Kommentaren enthält, die zufällig größer als 4 MB sind, nicht als einzelnes Dokument gespeichert werden kann?

Zählt dies auch die verschachtelten Dokumente?

Was wäre, wenn ich ein Dokument wollte, das die Änderungen an einem Wert überprüft? (Es kann schließlich wachsen und die 4-MB-Grenze überschreiten.)

Hoffe jemand erklärt das richtig.

Ich habe gerade angefangen, über MongoDB zu lesen (erste NOSQL-Datenbank, über die ich lerne).

Danke dir.


5
Ich denke, die Frage sollte klarstellen, dass dies eine Einschränkung der in MongoDB gespeicherten Dokumentgrößen und nicht des BSON-Formats ist.
Alexpopescu

2
Ich habe jedoch gerade versucht, ein großes Dokument zu speichern, das mit Sicherheit 4 MB überschreitet, um die Meldung "BSON :: InvalidDocument: Dokument zu groß: BSON-Dokumente sind auf 4194304 Byte beschränkt" zu erhalten. Wenn dies der Fall ist, ist es dann nicht irreführend in der Warn- / Fehlermeldung?
Nik So

18
Mit dem db.isMaster().maxBsonObjectSize/(1024*1024)+' MB'Befehl in der mongoShell können Sie leicht Ihre maximale BSON-Dokumentgröße ermitteln .
AhmetB - Google

5
Was ist der Zweck von schemaless nosql, wo Sie nicht mehr als 16 MB Datensätze sichern und darauf eine Rohöloperation aufbauen können?
Rizwan Patel

Ich denke, das erste Zitat sagt alles ... Die Grenze ist vorhanden, um ein schlechtes Schemadesign zu verhindern. Wenn Sie beispielsweise einen Beitrag mit vielen Kommentaren haben, möchten Sie eine Blogeintragssammlung und eine Kommentarsammlung oder eine Änderungssammlung. Das Design von mongo / nosql ermöglicht massiv große Dinge als Netzwerke von Dokumenten, aber der Entwickler muss sie in sinnvolle Teile zerlegen. Wenn keine Größenbeschränkung festgelegt ist, treten andere Probleme auf. Ich denke, das 4-MB-Limit war in Ordnung. 16mb, großartig! Aber wenn ich ein 16-MB-Dokument schreibe, ist das ein Hinweis darauf, dass etwas anderes mit dem Design nicht stimmt.
Wimpern

Antworten:


126

Zunächst einmal wird dies tatsächlich in der nächsten Version von 8MBoder 16MB... angesprochen, aber ich denke, um dies ins rechte Licht zu rücken, bringt Eliot von 10gen (der MongoDB entwickelt hat) es am besten auf den Punkt:

EDIT: Die Größe wurde offiziell auf erhöht16MB

In Ihrem Blog-Beispiel sind 4 MB also tatsächlich eine ganze Menge. Zum Beispiel ist der vollständige unkomprimierte Text von "War of the Worlds" nur 364 KB (html): http://www.gutenberg.org/etext/36

Wenn dein Blog-Beitrag so lang ist und so viele Kommentare enthält, werde ich ihn nicht lesen :)

Wenn Sie für Trackbacks 1 MB zugewiesen haben, können Sie leicht mehr als 10.000 (wahrscheinlich näher an 20.000) haben.

Abgesehen von wirklich bizarren Situationen wird es also großartig funktionieren. Und im Ausnahmefall oder bei Spam glaube ich wirklich nicht, dass Sie sowieso ein 20-MB-Objekt möchten. Ich denke, dass es sehr sinnvoll ist, Trackbacks auf etwa 15.000 zu begrenzen, unabhängig von der Leistung. Oder zumindest ein spezielles Gehäuse, falls es jemals passieren sollte.

-Eliot

Ich denke, es wird Ihnen ziemlich schwer fallen, das Limit zu erreichen ... und im Laufe der Zeit müssen Sie sich immer weniger Sorgen machen, wenn Sie ein Upgrade durchführen.

Der Hauptpunkt des Limits besteht darin, dass Sie nicht den gesamten Arbeitsspeicher Ihres Servers verbrauchen (da Sie das gesamte MBDokument bei der Abfrage in den Arbeitsspeicher laden müssen ).

Das Limit liegt also bei einigen Prozent des normal nutzbaren Arbeitsspeichers auf einem gemeinsamen System ... der von Jahr zu Jahr weiter wachsen wird.

Hinweis zum Speichern von Dateien in MongoDB

Wenn Sie Dokumente (oder Dateien) speichern müssen, die größer sind als 16MBSie, können Sie die GridFS-API verwenden, die die Daten automatisch in Segmente aufteilt und an Sie zurücksendet (wodurch das Problem mit Größenbeschränkungen / RAM vermieden wird).

Anstatt eine Datei in einem einzelnen Dokument zu speichern, unterteilt GridFS die Datei in Teile oder Blöcke und speichert jeden Block als separates Dokument.

GridFS verwendet zwei Sammlungen zum Speichern von Dateien. Eine Sammlung speichert die Dateiblöcke und die andere speichert Dateimetadaten.

Mit dieser Methode können Sie Bilder, Dateien, Videos usw. in der Datenbank speichern, ähnlich wie in einer SQL-Datenbank. Ich habe dies sogar verwendet, um Multi-Gigabyte-Videodateien zu speichern.


2
Das ist großartig, dass Sie genug RAM für Ihre gesamte Datenbank haben ... Normalerweise befindet sich der "Arbeitssatz" im RAM, nicht in der gesamten Datenbank (wie in meinem Fall habe ich mehr als eine x-GB-Datenbank, in der, wenn alles addiert würde, mein RAM überschritten würde). Aber das ist in Ordnung, weil der Arbeitssatz viel, viel kleiner ist.) Wenn es keine Begrenzung gäbe, könnten Sie auch ein 800-MB-Dokument mit einer Abfrage und ein 400-KB-Dokument mit einem anderen in den RAM laden, was das Ausgleichen Ihres RAM ein wenig schwierig macht, und so weiter Das "Limit" liegt also bei einigen% des typischen Server-RAM (daher wächst es mit der Zeit). Mongodb.org/display/DOCS/Checking+Server+Memory+Usage
Justin Jenkins

3
Es ist großartig, dass Sie alles im RAM speichern können, aber berücksichtigen Sie die Effizienz und die Blogpost-Sprache. Sie möchten natürlich, dass ein Beitrag gespeichert wird, wenn er gelesen wird. Aber möchten Sie wirklich, dass 10 Seiten mit Kommentaren für einen Blog-Beitrag gespeichert werden, wenn die meisten Leute nie über die erste Seite hinaus lesen? Sicher, Sie können es tun und wenn Ihre Datenbank klein genug ist, dass alles in den Speicher passt, dann kein Problem. In Bezug auf die reine Effizienz möchten Sie jedoch nicht, dass nutzlose Bits Speicherplatz beanspruchen, wenn Sie dies vermeiden können (und das gilt auch für RDBMS).
AlexGad

50
süßer Jesus, also ist Mongos Argument "16 MB sollten für irgendjemanden ausreichen"? Es ist nicht so, dass es sich in der Vergangenheit jemals als falsch erwiesen hat.
Robert Christ

2
Das scheint mir zu schade. Mongo soll für Big Data nützlich sein, ohne solche Einschränkungen. In meinem Projekt muss ich Tweets aggregieren und gruppieren, die sich auf dasselbe Trendthema beziehen. Dies kann über einen Zeitraum von 20 Stunden zu mehr als 20000 Tweets führen (und es ist durchaus möglich, dass es Trends gibt, die länger als andauern 20 Stunden in meiner Datenbank). Es ist verheerend, so viele Tweets zu haben und ihren Text gleichzeitig zu speichern, und nachdem einige kleine Trends gruppiert wurden, endet dies mit Ausnahme eines großen Trends.
Savvas Parastatidis

7
@savvas warum sollten Sie alle Tweets in einem einzigen Dokument zusammenfassen? Verwenden Sie ein Dokument pro Tweet und fügen Sie das Trendthema als weiteres Feld in das Dokument ein. Setzen Sie einen Index auf dieses Themenfeld und aggregieren Sie es dann mithilfe der Mongo-Pipeline. Es erfordert einige Anpassungen, wie Sie mit nosql arbeiten. Sobald Sie Ihre Methoden angepasst haben und denken, dass es für viele Big-Data-Anwendungsfälle hervorragend funktioniert.
schmidlop

32

Viele in der Community würden keine Begrenzung mit Warnungen bezüglich der Leistung bevorzugen. In diesem Kommentar finden Sie ein gut begründetes Argument: https://jira.mongodb.org/browse/SERVER-431?focusedCommentId=22283&page=com.atlassian.jira.plugin. system.issuetabpanels: comment-tabpanel # comment-22283

Meiner Meinung nach sind die leitenden Entwickler in Bezug auf dieses Problem hartnäckig, weil sie frühzeitig entschieden haben, dass es ein wichtiges "Feature" ist. Sie werden es nicht so schnell ändern, weil ihre Gefühle verletzt sind, dass jemand es in Frage gestellt hat. Ein weiteres Beispiel für Persönlichkeit und Politik, die ein Produkt in Open-Source-Communities beeinträchtigen, ist jedoch kein wirklich lähmendes Problem.


5
Ich stimme Ihnen voll und ganz zu, und es macht auch den Zweck zunichte, jetzt eingebettete Dokumente zu haben, da die meisten eingebetteten Dokumente jetzt leicht die Grenze überschreiten. Vor allem mit einer Reihe von Dokumenten
Sharjeel Ahmed

@ marr75 heißt es jetzt behoben, wurde es behoben?
Mafii

1
Ich meine, das Limit wurde auf 16 MB angehoben, was das "Problem" langfristig nicht behebt. IMO sollte das Limit einfach beseitigt werden.
Marr75

2
6 Jahre alter Faden Nekro. Ich bin von Ihrem speziellen Beispiel für einen schlechten Anwendungsfall / ein schlechtes Design nicht überzeugt. Dieses Beispiel zeigt auch viel besser, warum Sie Eingaben validieren müssen, als eine Beschränkung der Größe eines einzelnen Datenbankdokuments. Das Aufteilen der verschachtelten Dokumente durch die Anwendung als einzelne Dokumente in eine andere Sammlung oder das Starten eines neuen "Fortsetzungs" -Dokuments (Lösungen, die ich mehrmals verwendet habe, um innerhalb dieser Grenze zu arbeiten) hatte nur geringe Auswirkungen auf die Leistung, aber große Auswirkungen auf die Codekomplexität. Der gesamte Punkt von Dokument-DBs ist die Datenlokalität.
marr75

4
Vielen Dank, dass Sie ungefähr die gleiche Berechnung durchgeführt haben wie die mongoDB-Dokumente, um diese Entscheidung zu verteidigen, aber Ihr Experiment mit einem einzigen Anwendungsfall und Gedanken ist alles andere als schlüssig. Ich musste mir komplexe, redundante Designs einfallen lassen, um die Tatsache zu umgehen, dass es eine willkürliche Grenze gibt, die von Mongo getroffen wird (übrigens ohne tief verschachtelte oder doppelte Einträge). Nach Ihrer Logik sollte keine Datenbank mehr als 16 MB enthalten müssen, da beliebiger Text mit weniger Speicherplatz dargestellt werden kann. Das ist offensichtlich dumm.
März 75

31

Um hier eine Klarstellungsantwort für diejenigen zu posten, die hier von Google geleitet werden.

Die Dokumentgröße umfasst alles im Dokument, einschließlich der Unterdokumente, verschachtelten Objekte usw.

Also ein Dokument von:

{
    _id:{},
    na: [1,2,3],
    naa: [
        {w:1,v:2,b:[1,2,3]},
        {w:5,b:2,h:[{d:5,g:7},{}]}
    ]
}

Hat eine maximale Größe von 16meg.

Sbudocuments und verschachtelte Objekte werden alle auf die Größe des Dokuments angerechnet.


Die größtmögliche Einzelstruktur, die in BSON dargestellt werden kann, ist ironischerweise auch die kompakteste. Trotz der Tatsache, dass MongoDB size_tintern (64-Bit-) Array-Indizes verwendet, könnte die Beschränkung der Dokumentgröße von 16 MB bestenfalls ein Dokument darstellen, das ein einzelnes Array selbst enthält, das zwei Millionen NULL-Werte enthält.
Amcgregor

Entschuldigung, Hinzufügen eines zweiten Kommentars, um ein weiteres wichtiges Detail anzusprechen / zu verdeutlichen: Wenn Sie sagen , dass die Dokumentgröße alles im Dokument enthält , enthält dies auch die Schlüssel . ZB {"f": 1}sind zwei Bytes kleiner als {"foo": 1}. Dies kann sich schnell summieren, wenn Sie nicht vorsichtig sind, obwohl die moderne Komprimierung auf der Festplatte hilfreich ist.
Amcgregor

6

Ich habe noch kein Problem mit dem Limit gesehen, bei dem keine großen Dateien im Dokument selbst gespeichert waren. Es gibt bereits eine Vielzahl von Datenbanken, die beim Speichern / Abrufen großer Dateien sehr effizient sind. Sie werden als Betriebssysteme bezeichnet. Die Datenbank existiert als Schicht über dem Betriebssystem. Wenn Sie aus Leistungsgründen eine NoSQL-Lösung verwenden, warum sollten Sie dem Zugriff auf Ihre Daten zusätzlichen Verarbeitungsaufwand hinzufügen, indem Sie die DB-Schicht zwischen Ihrer Anwendung und Ihren Daten platzieren?

JSON ist ein Textformat. Wenn Sie also über JSON auf Ihre Daten zugreifen, gilt dies insbesondere, wenn Sie über Binärdateien verfügen, da diese in Uuencode, Hexadezimal oder Base 64 codiert werden müssen. Der Konvertierungspfad sieht möglicherweise so aus

Binärdatei <> JSON (codiert) <> BSON (codiert)

Es wäre effizienter, den Pfad (URL) zur Datendatei in Ihrem Dokument einzufügen und die Daten selbst binär zu halten.

Wenn Sie diese Dateien mit unbekannter Länge wirklich in Ihrer Datenbank behalten möchten, sollten Sie sie wahrscheinlich besser in GridFS einfügen und nicht riskieren, Ihre Parallelität zu beenden, wenn auf die großen Dateien zugegriffen wird.


1
"Es gibt bereits eine Vielzahl von Datenbanken, die beim Speichern / Abrufen großer Dateien sehr effizient sind. Sie werden als Betriebssysteme bezeichnet." Siehe blog.mongodb.org/post/183689081/…
redcalx


2

Vielleicht einen Blogeintrag zu speichern -> Kommentare Beziehung in einer nicht-relationalen Datenbank ist nicht wirklich das beste Design.

Sie sollten Kommentare wahrscheinlich sowieso in einer separaten Sammlung für Blog-Beiträge speichern.

[bearbeiten]

Weitere Kommentare finden Sie in den Kommentaren unten.


15
Ich stimme überhaupt nicht zu. Kommentare in Ihren Blogpost-Dokumenten sollten in MongoDB vollkommen in Ordnung sein ... es ist eine sehr häufige Verwendung (ich benutze es mehr als einen Ort in der Produktion und es funktioniert ziemlich gut.)
Justin Jenkins

2
Ich war vielleicht zu streng in meiner Antwort. Es ist nichts Falsches daran, Blog-Beiträge und zugehörige Kommentare in MongoDB oder einer ähnlichen Datenbank zu speichern. Es ist mehr so, dass die Leute dazu neigen, die Fähigkeiten, die dokumentbasierte Datenbanken
bieten,

3
@Mchel: "Blog" ist nicht gut, aber das Speichern von Kommentaren in einer separaten Sammlung ist aus den gleichen Gründen genauso schlecht. Posts mit einem Kommentar-Array ähneln dem kanonischen Beispiel eines Dokuments db.
Matt Briggs

6
@SoPeople: Das Speichern von Kommentaren in einem Beitrag ist wie das kanonische Beispiel für dokumentenorientierte DBs. (wie das Speichern des gesamten Wiki-Textes in einem Dokument) Wenn ich SO schreiben würde, würde es vollständig auf MongoDB laufen. Keiner dieser SO-Einträge wird 4 MB vernünftigerweise überschreiten. Craigslist führt eine riesige DB-Migration ihrer Geschichte nach MongoDB durch. Sie hatten nur ein paar Dokumente, die diese Grenze überschritten, und der Hauptentwickler schlug vor, dass die Dokumente selbst tatsächlich kaputt waren (das Ergebnis einiger Fehler). Auch hier sind 4 Megas mehrere Textromane.
Gates VP

3
@Gates VP, ich stimme der Verwendung einer separaten Volltext-Engine zu. Ich habe über eine Metadatensuche nachgedacht. Was ist, wenn Sie eine Reihe von Buchdokumenten haben und alle 1982 veröffentlichten Bücher finden möchten? Wenn jedes Buch mehr als 100 KB Text enthält, möchten Sie nicht mehrere Megabyte übertragen, um nur die ersten 20 Buchtitel anzuzeigen.
Mikerobi

0

Laut https://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-1

Wenn Sie erwarten, dass ein Blog-Beitrag das 16-MB-Dokumentlimit überschreitet, sollten Sie die Kommentare in eine separate Sammlung extrahieren, auf den Blog-Beitrag aus dem Kommentar verweisen und einen Join auf Anwendungsebene durchführen.

// posts
[
  {
    _id: ObjectID('AAAA'),
    text: 'a post',
    ...
  }
]

// comments
[
  {
    text: 'a comment'
    post: ObjectID('AAAA')
  },
  {
    text: 'another comment'
    post: ObjectID('AAAA')
  }
]
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.