Erdferkelweibchen mit Jungem. Foto: Scotto Bear , CC BY-SA 2.0Sie schreiben ein Programm für die Datenverarbeitung, es besteht den Test perfekt für eine kleine Datei, aber es stürzt bei einer realen Last ab.
Das Problem ist zu wenig Speicher. Wenn Sie über 16 Gigabyte RAM verfügen, können Sie dort keine 100-Gigabyte-Datei herunterladen. Irgendwann hat das Betriebssystem nicht mehr genügend Arbeitsspeicher, kann kein neues zuordnen und das Programm stürzt ab.
Was zu tun ist?
Nun, Sie können einen Big Data-Cluster bereitstellen, indem Sie einfach folgende Schritte ausführen:
- Suchen Sie einen Cluster von Computern.
- Richten Sie es in einer Woche ein.
- Lernen Sie die neue API kennen und schreiben Sie Ihren Code neu.
Es ist teuer und unangenehm. Zum Glück ist es oft nicht notwendig.
Wir brauchen eine einfache und unkomplizierte Lösung: die Verarbeitung von Daten auf einem Computer mit minimalem Setup und maximaler Nutzung bereits verbundener Bibliotheken. Dies ist fast immer mit Hilfe der einfachsten Methoden möglich, die manchmal als Out-of-Core-Berechnung bezeichnet werden.
In diesem Artikel diskutieren wir:
- Warum brauchen wir überhaupt RAM?
- Der einfachste Weg, Daten zu verarbeiten, die nicht in den Speicher passen, besteht darin, ein wenig Geld auszugeben.
- Drei hauptsächliche Softwaremethoden zur Verarbeitung übermäßiger Datenmengen: Komprimierung, Blockierung und Indizierung.
In zukünftigen Artikeln wird in der Praxis gezeigt, wie diese Methoden mit bestimmten Bibliotheken wie NumPy und Pandas angewendet werden. Aber zuerst die Theorie.
Warum ist RAM überhaupt notwendig?
Bevor wir mit der Diskussion der Lösungen beginnen, klären wir, warum dieses Problem überhaupt besteht. Sie können Daten in den Arbeitsspeicher (RAM), aber auch auf Ihre Festplatte schreiben. Warum benötigen Sie RAM? Eine Disc ist billiger, sie hat normalerweise keine Probleme mit Platzmangel. Warum beschränken Sie sich nicht darauf, von einer Disc zu lesen und zu schreiben?
Theoretisch könnte dies funktionieren. Aber auch moderne schnelle SSDs arbeiten
sehr viel langsamer als RAM:
- Aus SSD lesen: ~ 16.000 Nanosekunden
- Aus dem RAM lesen: ~ 100 Nanosekunden
Für schnelle Berechnungen haben wir keine Wahl: Die Daten müssen in den RAM geschrieben werden, sonst verlangsamt sich der Code um das 150-fache.
Die einfachste Lösung: mehr RAM
Die einfachste Lösung für das Problem, dass der Arbeitsspeicher knapp wird, besteht darin, etwas Geld auszugeben. Sie können einen leistungsstarken Computer oder Server kaufen oder eine virtuelle Maschine mit viel Arbeitsspeicher mieten. Im November 2019 bietet eine Schnellsuche und ein sehr kurzer Preisvergleich folgende Möglichkeiten:
- Kaufen Sie Thinkpad M720 Tower mit 6 Kernen und 64 GB RAM für 1074 US-Dollar
- Mieten Sie eine virtuelle Maschine in der Cloud mit 64 Kernen und 432 GB RAM für 3,62 USD / Stunde
Dies sind nur Zahlen nach einer schnellen Suche. Wenn Sie eine gute Recherche durchgeführt haben, werden Sie sicherlich bessere Angebote finden.
Etwas Geld für Hardware auszugeben, um Daten in den Arbeitsspeicher einzupassen, ist oft die billigste Lösung. Schließlich ist unsere Zeit teuer. Aber manchmal ist das nicht genug.
Wenn Sie beispielsweise viele Datenverarbeitungsaufgaben über einen bestimmten Zeitraum ausführen, kann Cloud Computing eine natürliche, aber auch kostenintensive Lösung sein. Bei einem unserer Projekte hätten solche Rechenkosten das gesamte prognostizierte Einkommen aus dem Produkt verbraucht, einschließlich des wichtigsten Einkommens, das für die Zahlung meines Gehalts erforderlich ist.
Wenn der Kauf / die Miete einer großen Menge RAM das Problem nicht löst oder unmöglich ist, besteht der nächste Schritt darin, die Anwendung selbst so zu optimieren, dass weniger Arbeitsspeicher verbraucht wird.Technik Nummer 1. Kompression
Durch die Komprimierung können Sie dieselben Daten in weniger Speicher ablegen. Es gibt zwei Formen der Komprimierung:
- Verlustfrei : Nach der Komprimierung werden genau die gleichen Informationen wie in den Originaldaten gespeichert.
- Verlustbehaftet : Die gespeicherten Daten verlieren einige Details, was sich jedoch im Idealfall nicht wesentlich auf die Berechnungsergebnisse auswirkt.
Aus Gründen der Übersichtlichkeit geht es nicht um ZIP- oder GZIP-Dateien, wenn Daten
auf der Festplatte komprimiert
werden . Um Daten aus einer ZIP-Datei zu verarbeiten, müssen Sie diese normalerweise entpacken und anschließend in den Speicher laden. Das wird also nicht helfen.
Was wir brauchen, ist eine Komprimierung der Darstellung der Daten im Speicher .Angenommen, Ihre Daten speichern nur zwei mögliche Werte und nichts anderes:
"AVAILABLE"
und
"UNAVAILABLE"
. Anstatt Zeichenfolgen mit 10 Byte oder mehr pro Datensatz zu speichern, können Sie diese als Boolesche Werte
True
oder
False
speichern, die mit nur einem Byte codiert sind. Sie können Informationen sogar auf ein Bit komprimieren und so den Speicherverbrauch um das Achtfache reduzieren.
Technik Nr. 2. In Blöcke aufteilen, wobei die Daten jeweils blockweise geladen werden
Fragmentierung ist in Situationen nützlich, in denen Daten nicht gleichzeitig in den Speicher geladen werden müssen. Stattdessen können wir sie in Teile laden und dabei jeweils ein Fragment verarbeiten (oder, wie im nächsten Artikel erläutert, mehrere Teile gleichzeitig).
Angenommen, Sie möchten das größte Wort in einem Buch finden. Sie können alle Daten auf einmal in den Speicher laden:
largest_word = "" for word in book.get_text().split(): if len(word) > len(largest_word): largest_word = word
Wenn das Buch jedoch nicht in den Speicher passt, können Sie es Seite für Seite laden:
largest_word = "" for page in book.iterpages(): for word in page.get_text().split(): if len(word) > len(largest_word): largest_word = word
Dies reduziert den Speicherverbrauch erheblich, da jeweils nur eine Seite eines Buches geladen wird. In diesem Fall ist das Ergebnis die gleiche Antwort.
Technik Nr. 3. Indizieren, wenn nur eine Teilmenge von Daten erforderlich ist
Die Indizierung ist nützlich, wenn Sie nur eine Teilmenge der Daten verwenden möchten und unterschiedliche Teilmengen zu unterschiedlichen Zeiten laden möchten.
Im Prinzip können Sie in einer solchen Situation das erforderliche Teil herausfiltern und das unnötige verwerfen. Das Filtern ist jedoch langsam und nicht optimal, da Sie zunächst viele zusätzliche Daten in den Speicher laden müssen, bevor Sie sie löschen können.
Wenn Sie anstelle der Fragmentierung nur einen Teil der Daten benötigen, ist es besser, einen Index zu verwenden - eine Datenkomprimierung, die die tatsächliche Position der Daten angibt.Stellen Sie sich vor, Sie möchten nur Fragmente eines Buches lesen, in dem Erdferkel erwähnt wird (ein süßes Säugetier auf dem Foto am Anfang des Artikels). Wenn Sie alle Seiten der Reihe nach überprüfen, wird das gesamte Buch auf der Suche nach Erdferkeln in Teilen Seite für Seite geladen - und dies wird ziemlich viel Zeit in Anspruch nehmen.
Oder Sie öffnen sofort den alphabetischen Index am Ende des Buches - und finden das Wort „Erdferkel“. Es besagt, dass das Wort auf den Seiten 7, 19 und 120-123 erwähnt wird. Jetzt können Sie diese Seiten lesen und nur diese, was viel schneller ist.
Dies ist eine effektive Methode, da der Index viel kleiner als das gesamte Buch ist und es daher viel einfacher ist, nur den Index in den Speicher zu laden, um die relevanten Daten zu finden.
Die einfachste Indizierungsmethode
Die einfachste und gebräuchlichste Methode zum Indizieren ist das Benennen von Dateien in einem Verzeichnis:
mydata/ 2019-Jan.csv 2019-Feb.csv 2019-Mar.csv 2019-Apr.csv ...
Wenn Sie Daten für März 2019 benötigen, laden Sie einfach die Datei
2019-Mar.csv
Sie müssen keine Daten für Februar, Juli oder einen anderen Monat herunterladen.
Weiter: Anwenden dieser Methoden
Das Problem des RAM-Mangels lässt sich am einfachsten mit Geld lösen, wenn man RAM gekauft hat. Wenn dies jedoch nicht möglich oder nicht ausreichend ist, verwenden Sie ohnehin die Komprimierung, Fragmentierung oder Indizierung.
Dieselben Methoden werden in verschiedenen Softwarepaketen und Tools verwendet . Darauf bauen auch leistungsstarke Big-Data-Systeme auf: zum Beispiel die parallele Verarbeitung einzelner Datenfragmente.
In den folgenden Artikeln wird erläutert, wie diese Methoden in bestimmten Bibliotheken und Tools, einschließlich NumPy und Pandas, angewendet werden.