Quelle base de données pourrait gérer le stockage de milliards / trillions d'enregistrements?

75

Nous envisageons de mettre au point un outil permettant de capturer et d’analyser les données netflow, dont nous rassemblons d’énormes quantités. Chaque jour, nous enregistrons environ 1,4 milliard d’enregistrements de flux qui ressemblent à ceci au format JSON:

{
   "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"
}

Nous aimerions pouvoir effectuer des recherches rapides (moins de 10 secondes) sur le jeu de données, le plus souvent sur des tranches de temps étroites (intervalles de 10 à 30 minutes). Nous souhaitons également indexer la majorité des points de données afin de pouvoir effectuer des recherches sur chacun d’eux rapidement. Nous aimerions également avoir une vue à jour des données lorsque les recherches sont exécutées. Ce serait bien de rester dans le monde de l'open source, mais nous ne sommes pas opposés à la recherche de solutions propriétaires pour ce projet.

L'idée est de conserver environ un mois de données, ce qui représenterait environ 43,2 milliards d'enregistrements. Une estimation approximative selon laquelle chaque enregistrement contiendrait environ 480 octets de données, équivaudrait à environ 18,7 téraoctets de données par mois, et peut-être trois fois plus qu'un index. Nous voudrions éventuellement augmenter la capacité de ce système pour stocker des milliards de disques.

Nous avons (très fondamentalement) évalué dans la mesure du possible les candidats couchbase, cassandra et mongodb pour ce projet, mais chacun propose ses propres défis. Avec couchbase, l'indexation est effectuée à intervalles réguliers et non lors de l'insertion des données; les vues secondaires ne sont donc pas à jour. Les index secondaires de Cassandra ne sont pas très efficaces pour renvoyer les résultats, car ils nécessitent généralement une analyse de l'ensemble du cluster pour obtenir des résultats. semble être beaucoup plus difficile à mettre en œuvre car il est maître / esclave / fragmenté. Parmi les autres candidats que nous prévoyons d’évaluer, on citera elasticsearch, mysql (je ne sais pas si cela est même applicable) et quelques bases de données relationnelles orientées colonnes. Toute suggestion ou expérience du monde réel serait appréciée.

somecallmemike
la source
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter .
Paul White

Réponses:

57

Dans une entreprise pour laquelle je travaille, nous traitons une quantité similaire de données (environ 10 To de données consultables en temps réel). Nous résolvons cela avec Cassandra et je voudrais mentionner quelques idées qui vous permettront de faire une recherche O (1) sur une base de données multi TB. Ceci n'est pas spécifique à la base de données Cassandra, vous pouvez également l'utiliser avec d'autres bases de données.

Théorie

  • Shard vos données. Il n’ya aucun moyen pour un serveur unique de conserver ce volume de données de manière fiable et réaliste.
  • Soyez prêt à faire face aux défaillances matérielles et aux nœuds entiers, dupliquez les données.
  • Commencez à utiliser de nombreux serveurs d'arrière-plan depuis le début.
  • Utilisez de nombreux serveurs de base moins chers que ceux haut de gamme hautes performances.
  • Assurez-vous que les données sont réparties de manière égale entre les fragments.
  • Passez beaucoup de temps à planifier vos requêtes. Dérivez les API des requêtes, puis concevez soigneusement les tables. C'est la tâche la plus importante et la plus longue.
  • Dans Cassandra, vous pouvez concevoir une clé de colonne composée et accéder à cette clé dans O (1). Passez du temps à travailler sur eux. Ceci sera utilisé pour accéder aux enregistrements interrogeables à la place de l'index secondaire.
  • Utilisez des rangées larges. Ils sont utiles pour stocker des événements horodatés.
  • N'effectuez jamais une analyse complète ou une opération supérieure à O (Log N) sur un tel volume. Si vous avez besoin de plus que O (Log N), déchargez ces opérations dans des algorithmes Map-Reduce.

Entraine toi

  • Ne perdez pas de temps à créer des images de système d'exploitation ou à installer des serveurs sur des machines physiques. Utilisez des fournisseurs basés sur le cloud pour un prototypage rapide. J'ai travaillé avec Amazon EC2 et je le recommande vivement pour sa simplicité, sa fiabilité et sa rapidité de prototypage.
  • Les machines Windows ont tendance à être plus lentes au démarrage et à consommer beaucoup plus de ressources en mode veille. Envisagez d'utiliser un système d'exploitation basé sur Unix. Personnellement, j’ai trouvé que le serveur Ubuntu était un système d’exploitation fiable, mais il existe en outre une très bonne communauté chez askubuntu.
  • En ce qui concerne la mise en réseau, les nœuds doivent idéalement être proches les uns des autres pour permettre un commérage rapide et un échange de métadonnées.
  • Ne pas aller dans les cas extrêmes: rangées de colonnes vraiment larges ou familles de colonnes exceptionnellement longues (tables). La meilleure performance est réalisée dans les limites saines - si db soutient que beaucoup de N lignes par la conception, cela ne signifie pas qu'il fonctionne bien.
  • Notre recherche prend environ 3-5 secondes, en grande partie à cause des nœuds intermédiaires entre l'interface utilisateur et la base de données. Déterminez comment rapprocher les demandes de la base de données.
  • Utilisez un équilibreur de charge réseau. Choisissez un établi. Nous utilisons HAProxy, qui est simple mais rapide. Jamais eu de problèmes avec ça.
  • Préférez la simplicité aux solutions complexes.
  • Recherchez des solutions open-source gratuites, à moins que votre budget ne corresponde à celui d'une entreprise. Une fois que vous avez dépassé plusieurs serveurs, les coûts d’infrastructure peuvent monter à la hausse.

Je ne travaille pas pour Amazon et n’ai aucune relation avec les équipes HAProxy et Ubuntu. Ceci est une opinion personnelle plutôt que toute forme de promotion.

oleksii
la source
5
Je suis presque sûr qu'une recherche par O (1) est impossible en dehors de cas extrêmement triviaux / inutiles.
Fitzsimmons
2
Ne vous inquiétez pas, mais dites-le à Google. La recherche O (1) est possible sur une balance PB avec une conception soignée.
oleksii
9
@oleksii Milliards de dollars Les budgets de Google ne constituent pas une comparaison raisonnable.
Mark Storey-Smith
4
Je peux relier les 3 commentaires précédents avecO(1) search <=> unbounded storage space <=> unlimited supply of cash
ypercubeᵀᴹ
3
O (1) La recherche d'un seul enregistrement peut être effectuée avec une table de hachage linéaire. . Cependant, cela ne vous rend pas efficace dans la recherche séquentielle (pour les plages). Pour cela, vous avez besoin d’une variante de la structure BTree, qui est O (log n) pour un seul élément.
ConcernedOfTunbridgeWells
41

Si je devais mettre cela dans SQL Server, je suggérerais un tableau du type:

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 */
);

Il en résulte une estimation totale des besoins en stockage pour la table unique, sans aucun autre index de 5,5 To pour 43,2 enregistrements d'abeilles (vos besoins spécifiés). Cela correspond à 130 octets pour les données elles-mêmes, plus 7 octets par ligne supplémentaire, plus 96 octets par page supplémentaire. SQL Server stocke les données dans des pages de 8 Ko, ce qui permet 59 lignes par page. Cela équivaut à 732 203 390 pages pour un seul mois de données.

SQL Server aime écrire sur le disque en morceaux de 8 pages (64 Ko), ce qui équivaut à 472 lignes par E / S physique. Avec 16 203 enregistrements de flux générés chaque seconde, vous aurez besoin d’un taux d’entrées / sorties minimal de 34 E / S, garanti chaque seconde. Bien que cela ne représente pas en soi une énorme quantité, les autres E / S du système (SQL Server et autres) ne doivent jamais empiéter sur ce débit nécessaire d'IOps. Par conséquent, vous auriez besoin de concevoir un système capable d'au moins un ordre de grandeur supplémentaire, ou de 340 opérations continues. J'aurais tendance à estimer qu'il vous faut 2 entrées de puissance plus durables pour garantir le débit.

Vous remarquerez que je ne stocke pas les adresses IP sous leur forme décimale en pointillé. Cela économise énormément sur le stockage (7 octets par adresse) et rend l'indexation, la récupération, le tri et la comparaison d'adresses IP beaucoup plus efficaces. L'inconvénient est que vous devez convertir les IP décimales avec points en un entier de 8 octets avant de les stocker, puis de nouveau en adresses IP décimales pour affichage. Le code à suivre est trivial, mais votre débit de ligne ajoutera une charge de traitement considérable à chaque ligne de flux traitée. Vous souhaiterez peut-être effectuer ce processus de conversion sur une machine physiquement différente de SQL Server.

Discuter des index dont vous avez besoin est une question totalement distincte puisque vous n’avez répertorié aucune exigence spécifique. La conception de cette table stockera les lignes de flux dans l’ordre physique dans lequel elles ont été reçues par SQL Server. Le tcp_traffic_idchamp est unique pour chaque enregistrement et permet de trier les lignes en fonction de l’ordre dans lequel elles ont été enregistrées. au moment de l'événement de flux).

Max Vernon
la source
4
Je voudrais probablement utiliser binary(4)ou binary(16), respectivement. 4 octets / ligne représente une quantité de stockage importante multipliée par 1 000 000 000 000.
Jon Seigel
2
Et les numéros de port ont une plage de 0 à 65535, vous pouvez donc l’utiliser, SMALLINTmais il doit également y avoir une routine de conversion.
Ypercubeᵀᴹ
7
@ MrTelly je ne suis pas d'accord. Le faire dans SQL Server n’est coûteux que si vous avez besoin de matériel de haute disponibilité ou de basculement important. Pour un magasin de données solide, il est très facile vivre avec, SQL Server est idéal pour cela. Tous les systèmes deviennent très coûteux (et compliqués) si une HA est nécessaire.
samsmith
2
Messagerie Internet uniquement, SQL Server peut définitivement stocker les données. Je ne sais toujours pas si c'est la bonne solution pour résoudre la partie analytique du projet, principalement parce que je ne connais pas suffisamment les autres systèmes envisagés.
Jon Seigel
3
@MrTelly Il y a deux dépenses: a) Stockage sur disque (pour 5-8 To, en fonction de l'espace utilisé par les index) b) RAM (pour prendre en charge les requêtes, la mise en cache des index). Faire cela monolithiquement serait généralement fait avec une grande baie RAID10 ou SAN. Toutefois, notez qu'un partage peut certainement être effectué et qu'il peut vous permettre d'utiliser une logique au niveau de l'application pour répartir la charge de travail sur plusieurs serveurs SQL. Cela pourrait vous permettre d'utiliser des serveurs peu coûteux, avec 0,5 à 2 To chacun, et peut-être même utiliser l'édition gratuite de SQL Server. (Notez que le sharding est un concept générique, il est souvent effectué au niveau de l'application et s'applique à toutes les méthodes de persistance)
samsmith
5

Je recommanderais HBase . Vous pouvez stocker toutes les données brutes dans une ou plusieurs tables HBase, en fonction de ce que vous devez interroger. HBase peut gérer des ensembles de données volumineux et effectue un découpage automatique à travers les divisions de région.

De plus, si vous concevez bien les clés de ligne, vous pouvez obtenir des requêtes extrêmement rapides, même des requêtes O (1). Notez que si vous récupérez un ensemble de données volumineux, le processus sera toujours lent car l'extraction de données est une opération O (n).

Puisque vous voulez interroger chaque champ, je vous recommande de créer une table unique pour chacun d'eux. Exemple pour les données src_address, ayez une table qui ressemble à ceci:

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

Par conséquent, si vous souhaitez interroger toutes les données du 1.2.3.4 à partir du 27 mars à midi le 27 mars à 00h01, vous pouvez effectuer une analyse des plages avec les lignes de début et de fin spécifiées.

IMHO, la conception de la clé de rangée est la partie la plus critique de l'utilisation de HBase. Si vous la concevez bien, vous pourrez faire des requêtes rapides ET stocker de gros volumes de données.

Suman
la source
3

A dit ceci :

... nous ne sommes pas opposés à la recherche de solutions propriétaires pour ce projet

Je suggère d’envisager la base de données IBM Informix + TimeSeries datablade. Contrairement à ce que disent certaines personnes, Informix est en vie et se porte très bien. La dernière version a été publiée le mois dernier (mars / 2013, version 12.10).

TimeSeries est comme un "plugin" (sans frais) capable de gérer des situations comme la vôtre.
Et vous pouvez l'utiliser en production avec la version gratuite de la base de données Informix ( édition Innovator-C ). (bien sûr, uniquement pour évaluer les parties techniques car la version gratuite a beaucoup de ressources limitées)

Ici, vous pouvez consulter un PDF de référence ce qui peut être utilisé comme référence. Voici deux présentations avec des exemples plus techniques: guide des mannequins et autres astuces

Je n'ai pas d'expérience personnelle avec TimeSeries , je ne peux donc pas affirmer que ce sera "la solution", juste une suggestion à évaluer.

ceinmart
la source
2

J'appuie la recommandation sur Informix TimeSeries. La littérature d'IBM affirme que TimeSeries peut stocker ce type d'informations sur 1/5 de l'espace et fonctionner 5 fois plus rapidement que les tables relationnelles traditionnelles.

Parmi les avantages supplémentaires, citons l’interface de table virtuelle qui peut donner l’impression des données TimeSeries à l’utilisateur final comme des tables relationnelles traditionnelles (simplifier le développement d’applications tout en bénéficiant des avantages de TimeSeries), de simples nœuds haute disponibilité avec HDR prenant désormais en charge les données TimeSeries dans la version 12.1 et ultérieure. intégration des données TimeSeries dans Informix Warehouse Accelerator, qui peut être utilisée pour accélérer les rapports complexes d'entrepôts de données et la possibilité de prototyper une solution TimeSeries dans Informix à l'aide des éditions gratuites Informix Developer ou Innovator-C.

Andrew
la source