it-swarm.com.de

Welche Datenbank könnte die Speicherung von Milliarden / Billionen Datensätzen verwalten?

Wir planen die Entwicklung eines Tools zur Erfassung und Analyse von Netflow-Daten, von denen wir enorme Mengen sammeln. Jeden Tag erfassen wir ungefähr 1,4 Milliarden Flussdatensätze, die im JSON-Format so aussehen würden:

{
   "tcp_flags": "0",
   "src_as": "54321",
   "nexthop": "1.2.3.4",
   "unix_secs": "1352234521",
   "src_mask": "23",
   "tos": "0",
   "prot": "6",
   "input": "105",
   "doctets": "186",
   "engine_type": "0",
   "exaddr": "2.3.4.5",
   "engine_id": "2",
   "srcaddr": "9.8.7.6",
   "dst_as": "12345",
   "unix_nsecs": "752265174",
   "sysuptime": "2943529544",
   "dst_mask": "24",
   "dstport": "80",
   "last": "2943523241",
   "srcport": "52672",
   "dpkts": "4",
   "output": "111",
   "dstaddr": "6.5.4.3",
   "first": "2943517993"
}

Wir möchten in der Lage sein, den Datensatz schnell (weniger als 10 Sekunden) zu durchsuchen, höchstwahrscheinlich über enge Zeitabschnitte (Intervalle von 10 bis 30 Minuten). Wir möchten auch die meisten Datenpunkte indizieren, damit wir sie schnell durchsuchen können. Wir möchten auch eine aktuelle Ansicht der Daten haben, wenn Suchvorgänge ausgeführt werden. Es wäre großartig, in der Open-Source-Welt zu bleiben, aber wir sind nicht dagegen, proprietäre Lösungen für dieses Projekt zu suchen.

Die Idee ist, ungefähr einen Monat Daten zu speichern, was ungefähr 43,2 Milliarden Datensätzen entspricht. Eine grobe Schätzung, dass jeder Datensatz etwa 480 Datenbytes enthalten würde, würde ~ 18,7 Terabyte Daten in einem Monat entsprechen, und möglicherweise dreimal so viel wie bei Indizes. Schließlich möchten wir die Kapazität dieses Systems zum Speichern von Billionen von Datensätzen erweitern.

Wir haben (im Grunde genommen) Couchbase, Cassandra und Mongodb so weit wie möglich als Kandidaten für dieses Projekt bewertet, jedoch schlägt jeder seine eigenen Herausforderungen vor. Bei Couchbase erfolgt die Indizierung in Intervallen und nicht während des Einfügens der Daten, sodass die Ansichten nicht auf dem neuesten Stand sind. Die Sekundärindizes von Cassandra sind nicht sehr effizient bei der Rückgabe von Ergebnissen, da sie normalerweise das Scannen des gesamten Clusters nach Ergebnissen erfordern, und Mongodb sieht jedoch vielversprechend aus scheint weitaus schwieriger zu skalieren zu sein, da es Master/Slave/Sharded ist. Einige andere Kandidaten, die wir evaluieren möchten, sind Elasticsearch, MySQL (nicht sicher, ob dies überhaupt anwendbar ist) und einige spaltenorientierte relationale Datenbanken. Anregungen oder Erfahrungen aus der Praxis sind willkommen.

77
somecallmemike

In einem Unternehmen, für das ich arbeite, haben wir es mit einer ähnlichen Datenmenge zu tun (etwa 10 TB durchsuchbarer Echtzeitdaten). Wir lösen dies mit Cassandra und ich möchte einige Ideen erwähnen, mit denen Sie O(1) in einer Datenbank mit mehreren TBs suchen können) ist nicht spezifisch für Cassandra db, Sie können es aber auch mit anderen db verwenden.

Theorie

  • Scherben Sie Ihre Daten. Es gibt keine Möglichkeit, dass ein einzelner Server ein solches Datenvolumen zuverlässig und realistisch hält.
  • Seien Sie bereit für Hardwarefehler und Ausfälle ganzer Knoten, duplizieren Sie die Daten.
  • Verwenden Sie von Anfang an viele Back-End-Server.
  • Verwenden Sie viele billigere Commodity-Server im Vergleich zu High-End-Servern der Spitzenklasse.
  • Stellen Sie sicher, dass die Daten gleichmäßig auf die Shards verteilt sind.
  • Verbringen Sie viel Zeit mit der Planung Ihrer Anfragen. Leiten Sie die API aus den Abfragen ab und entwerfen Sie die Tabellen sorgfältig. Dies ist die wichtigste und langwierigste Aufgabe.
  • In Cassandra können Sie einen zusammengesetzten Spaltenschlüssel entwerfen und in O (1) auf diesen Schlüssel zugreifen. Verbringen Sie Zeit damit, daran zu arbeiten. Dies wird verwendet, um auf durchsuchbare Datensätze anstelle des Sekundärindex zuzugreifen.
  • Verwenden Sie breite Reihen. Sie sind nützlich zum Speichern von Ereignissen mit Zeitstempel.
  • Führen Sie niemals einen vollständigen Scan oder eine Operation mit mehr als O (Log N) auf einem solchen Volume durch. Wenn Sie mehr als O (Log N) benötigen, verlagern Sie solche Vorgänge auf Map-Reduce-Algorithmen.

Trainieren

  • Verbringen Sie keine Zeit damit, Betriebssystem-Images zu erstellen oder Server auf physischen Computern zu installieren. Verwenden Sie Cloud-basierte Anbieter für schnelles Prototyping. Ich habe mit Amazon EC2 gearbeitet und kann es aufgrund seiner Einfachheit, Zuverlässigkeit und Geschwindigkeit des Prototyping sehr empfehlen.
  • Windows-Computer sind während des Startvorgangs tendenziell langsamer und benötigen im Ruhezustand erheblich mehr Ressourcen. Erwägen Sie die Verwendung eines Unix-basierten Betriebssystems. Persönlich fand ich, dass Ubuntu Server ein zuverlässiges Betriebssystem ist, aber außerdem gibt es eine ziemlich gute Community unter askubunt
  • Denken Sie an die Vernetzung. Knoten sollten idealerweise nahe beieinander liegen, um schnelles Klatschen und Metadatenaustausch zu ermöglichen.
  • Gehen Sie nicht in extreme Fälle: wirklich breite Spaltenzeilen oder außergewöhnlich lange Spaltenfamilien (Tabellen). Die beste Leistung wird in den vernünftigen Grenzen erzielt - wenn db so viele [~ # ~] n [~ # ~] Zeilen unterstützt, ist dies nicht der Fall Das heißt, es funktioniert gut.
  • Unsere Suche dauert ca. 3-5 Sekunden, was hauptsächlich auf die Zwischenknoten zwischen der Benutzeroberfläche und der Datenbank zurückzuführen ist. Überlegen Sie, wie Sie Anforderungen näher an die Datenbank bringen können.
  • Verwenden Sie einen Netzwerklastenausgleich. Wählen Sie eine etablierte. Wir verwenden HAProxy, das einfach, aber sehr schnell ist. Hatte nie Probleme damit.
  • Ziehen Sie Einfachheit komplexen Lösungen vor.
  • Suchen Sie nach kostenlosen Open-Source-Lösungen, es sei denn, Sie sind durch das Größenbudget eines Unternehmens abgesichert. Wenn Sie mehr als mehrere Server nutzen, können die Kosten für die Infrastruktur in die Höhe schnellen.

Ich arbeite nicht für Amazon und habe keine Beziehung zu HAProxy- und Ubuntu-Teams. Dies ist eher eine persönliche Meinung als irgendeine Art von Werbung.

59
oleksii

Wenn ich dies in SQL Server einfügen würde, würde ich eine Tabelle vorschlagen wie:

CREATE TABLE tcp_traffic
(
    tcp_traffic_id bigint constraint PK_tcp_traffic primary key clustered IDENTITY(1,1)
    , tcp_flags smallint    /* at most 9 bits in TCP, so use SMALLINT */
    , src_as int        /* Since there are less than 2 billion A.S.'s possible, use INT */
    , netxhop bigint    /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , unix_secs bigint  
    , src_mask int      /* an assumption */
    , tos tinyint       /* values are 0-255, see RFC 791 */
    , prot tinyint      /* values are 0-255, see RFC 790 */
    , input int         /* an assumption */
    , doctets int       /* an assumption */
    , engine_type int   /* an assumption */
    , exaddr bigint     /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , engine_id int     /* an assumption */
    , srcaddr bigint    /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , dst_as int        /* Since there are less than 2 billion A.S.'s possible, use INT */
    , unix_nsecs bigint /* an assumption */
    , sysuptime bigint  /* an assumption */
    , dst_mask int      /* an assumption */
    , dstport smallint  /* ports can be in the range of 0 - 32767 */
    , [last] bigint     /* an assumption */
    , srcport smallint  /* ports can be in the range of 0 - 32767 */
    , dpkts int         /* an assumption */
    , output int        /* an assumption */
    , dstaddr bigint    /* use a big integer for the IP address instead of storing
                            it as dotted-decimal */
    , [first] bigint    /* an assumption */
);

Dies führt zu einem geschätzten Gesamtspeicherbedarf für die einzelne Tabelle ohne weitere Indizes von 5,5 TB für 43,2 Beeellion-Datensätze (Ihre angegebene Anforderung). Dies wird als 130 Byte für die Daten selbst berechnet. plus 7 Bytes pro Overhead-Zeile plus 96 Bytes pro Overhead-Seite. SQL Server speichert Daten auf 8 KB-Seiten und ermöglicht 59 Zeilen pro Seite. Dies entspricht 732.203.390 Seiten für einen einzelnen Datenmonat.

SQL Server schreibt gerne in 8-seitigen Blöcken (64 KB) auf die Festplatte, was 472 Zeilen pro physischer E/A entspricht. Da pro Sekunde 16.203 Flussdatensätze generiert werden, benötigen Sie eine Mindest-E/A-Rate von 34 E/A, die jede Sekunde garantiert wird. Obwohl dies an sich keine große Menge ist, müssen andere E/A im System (SQL Server und andere) niemals gegen diese erforderliche E/A-Rate verstoßen. Daher müssten Sie ein System entwerfen, das mindestens eine Größenordnung mehr IOps oder 340 anhaltende IOps ermöglicht. Ich würde eher schätzen, dass Sie 2 Größenordnungen nachhaltigerer IOps benötigen, um den Durchsatz zu gewährleisten.

Sie werden feststellen, dass ich die IP-Adressen nicht in Punkt-Dezimal-Form speichere. Dies spart viel Speicherplatz (7 Bytes pro Adresse) und macht das Indizieren, Abrufen, Sortieren und Vergleichen von IP-Adressen weitaus effizienter. Der Nachteil hierbei ist, dass Sie die IPs mit gepunkteten Dezimalstellen in 8-Byte-Ganzzahlen konvertieren müssen, bevor Sie sie speichern, und zur Anzeige zurück in IPs mit gepunkteten Dezimalstellen. Der dazu erforderliche Code ist trivial. Durch Ihre Zeilenrate wird jedoch jeder zu verarbeitenden Flusszeile ein erheblicher Verarbeitungsaufwand hinzugefügt. Möglicherweise möchten Sie diesen Konvertierungsprozess auf einem physisch anderen Computer als SQL Server ausführen.

Die Erörterung der von Ihnen benötigten Indizes ist eine völlig separate Angelegenheit, da Sie keine spezifischen Anforderungen aufgeführt haben. Das Design dieser Tabelle speichert Flusszeilen in der physischen Reihenfolge, in der sie von SQL Server empfangen werden, dem tcp_traffic_id Feld ist für jeden Datensatz eindeutig und ermöglicht das Sortieren von Zeilen nach der Reihenfolge, in der sie aufgezeichnet wurden (in diesem Fall höchstwahrscheinlich eins zu eins mit dem Zeitpunkt des Ablaufereignisses).

41
Max Vernon

Ich würde empfehlen HBase . Sie können alle Rohdaten in einer oder mehreren HBase-Tabellen speichern, je nachdem, was Sie abfragen müssen. HBase kann große Datenmengen verarbeiten und führt ein automatisches Sharding durch Regionsaufteilungen durch.

Wenn Sie Zeilenschlüssel gut entwerfen, können Sie außerdem extrem schnelle Abfragen erhalten, sogar O(1). Wenn Sie einen großen Datensatz abrufen, ist dies immer noch langsam da das Abrufen von Daten eine Operation O(n)] ist.

Da Sie für jedes Feld eine Abfrage durchführen möchten, würde ich empfehlen, für jedes Feld eine eindeutige Tabelle zu erstellen. Beispiel für die src_address-Daten: Haben Sie eine Tabelle, die folgendermaßen aussieht:

1.2.3.4_timestamp1 : { data }
1.2.3.4_timestamp2 : { data }

Wenn Sie also vom 27. März um 00:00 Uhr bis zum 27. März um 00:01 Uhr alle Daten in 1.2.3.4 abfragen möchten, können Sie einen Bereichsscan mit den angegebenen Start- und Stoppzeilen durchführen.

Meiner Meinung nach ist das Zeilenschlüssel-Design der wichtigste Teil der Verwendung von HBase. Wenn Sie es gut entwerfen, können Sie schnelle Abfragen durchführen UND große Datenmengen speichern.

5
Suman

Sagte das :

... wir sind nicht dagegen, proprietäre Lösungen für dieses Projekt zu suchen

Ich schlage vor, IBM Informix-Datenbank + TimeSeries Datenblatt zu berücksichtigen. Im Gegensatz zu dem, was manche Leute sagen, lebt Informix und läuft sehr gut. Die letzte Version wurde letzten Monat veröffentlicht (März/2013, Version 12.10).

TimeSeries ist wie ein "Plugin" (kostenlos), das Situationen wie Ihre bewältigen kann.
Und Sie können es in der Produktion mit der kostenlosen Version der Informix-Datenbank ( Edition Innovator-C ) verwenden. (Natürlich nur zur Bewertung der technischen Teile, da die kostenlose Version viele begrenzte Ressourcen hat)

Hier können Sie ein PDF des Benchmarks überprüfen, was als Referenz verwendet werden kann. Hier zwei Präsentationen mit technischeren Beispielen: Dummies Guide und - andere Tipps

Ich habe keine persönlichen Erfahrungen mit TimeSeries , daher kann ich nicht zustimmen, dass dies "die Lösung" ist, sondern nur ein Vorschlag zur Bewertung.

3
ceinmart

Ich stimme der Empfehlung zu, Informix TimeSeries zu betrachten. Laut IBM-Literatur kann TimeSeries diese Art von Informationen in 1/5 des Speicherplatzes speichern und fünfmal so schnell wie herkömmliche relationale Tabellen ausführen.

Weitere Vorteile wären die virtuelle Tabellenschnittstelle, mit der TimeSeries-Daten für den Endbenutzer wie herkömmliche relationale Tabellen angezeigt werden können (was die Anwendungsentwicklung vereinfacht und gleichzeitig die Vorteile von TimeSeries bietet), einfache HA mit HDR-Knoten, die jetzt TimeSeries-Daten in Version 12.1 unterstützen Integration von TimeSeries-Daten in den Informix Warehouse Accelerator, mit dem komplizierte Data Warehouse-Berichte beschleunigt und eine TimeSeries-Lösung in Informix mithilfe der kostenlosen Informix Developer- oder Innovator-C-Editionen prototypisiert werden kann.

2
Andrew