web-dev-qa-db-fra.com

Meilleur magasin de données pour des milliards de lignes

J'ai besoin de pouvoir stocker de petits bits de données (environ 50 à 75 octets) pour des milliards d'enregistrements (~ 3 milliards/mois pendant un an).

La seule exigence est des insertions et des recherches rapides pour tous les enregistrements avec le même GUID et la possibilité d'accéder au magasin de données à partir de .net.

Je suis un serveur SQL et je pense que SQL Server peut faire cela, mais avec toutes les discussions sur BigTable, CouchDB et d'autres solutions nosql, cela ressemble de plus en plus à une alternative à un RDBS traditionnel peut être préférable en raison des optimisations pour les requêtes distribuées et la mise à l'échelle. J'ai essayé cassandra et les bibliothèques .net ne compilent pas actuellement ou sont toutes sous réserve de modifications (avec cassandra lui-même) .

J'ai examiné de nombreux magasins de données nosql disponibles, mais je ne trouve pas celui qui répond à mes besoins en tant que plate-forme robuste prête à la production.

Si vous deviez stocker 36 milliards de petits enregistrements plats pour qu'ils soient accessibles à partir de .net, que choisiriez-vous et pourquoi?

81
Jody Powlette

Stocker ~ 3,5 To de données et insérer environ 1K/sec 24x7, et également interroger à un taux non spécifié, c'est possible avec SQL Server, mais il y a plus de questions:

  • quelle exigence de disponibilité avez-vous pour cela? 99,999% de disponibilité ou 95% suffisent-ils?
  • quelle exigence de fiabilité vous avez? Manquer un insert vous coûte-t-il 1 M $?
  • quelle condition de récupérabilité vous avez? Si vous perdez un jour de données, est-ce important?
  • quelle exigence de cohérence vous avez? Une écriture doit-elle être garantie pour être visible lors de la prochaine lecture?

Si vous avez besoin de toutes ces exigences que j'ai mises en évidence, la charge que vous proposez coûtera des millions en matériel et en licences sur un système relationnel, n'importe quel système, peu importe les gadgets que vous essayez (partitionnement, partitionnement, etc.). Un système nosql, par sa définition même, ne répondrait pas à toutes ces exigences.

Il est donc évident que vous avez déjà assoupli certaines de ces exigences. Il y a un guide visuel sympa comparant les offres nosql basées sur le paradigme `` choisir 2 sur 3 '' à Guide visuel des systèmes NoSQL :

nosql comparisson

Après la mise à jour du commentaire OP

Avec SQL Server, cette implémentation serait simple:

  • une seule table en cluster (GUID, heure). Oui, va obtenir fragmenté , mais la fragmentation affecte les lectures anticipées et les lectures anticipées ne sont nécessaires que pour les analyses de plage importantes. Étant donné que vous ne recherchez que pour GUID et plage de dates, la fragmentation n'aura pas beaucoup d'importance. Oui, c'est une clé large, donc les pages non-feuilles auront une densité de clé médiocre. Oui, cela conduira à un facteur de remplissage médiocre. Et oui, des fractionnements de page peuvent se produire. Malgré ces problèmes, compte tenu des exigences, il reste le meilleur choix de clé en cluster.
  • partitionnez la table par le temps afin que vous puissiez implémenter la suppression efficace des enregistrements expirés, via un fenêtre coulissante automatique . Augmentez cela avec une reconstruction de partition d'index en ligne du mois dernier pour éliminer le mauvais facteur de remplissage et la fragmentation introduits par le clustering GUID.
  • activer la compression de page. Étant donné que les clés en cluster sont regroupées par GUID en premier, tous les enregistrements d'un GUID seront côte à côte, donnant compression de page a bonne chance de déployer la compression du dictionnaire.
  • vous aurez besoin d'un chemin rapide IO pour le fichier journal. Vous êtes intéressé par un débit élevé, pas sur une faible latence pour qu'un journal puisse suivre 1K insertions/s, donc décapage est un must.

Le partitionnement et la compression de page nécessitent chacun un SQL Server Enterprise Edition, ils ne fonctionneront pas sur l'édition Standard et les deux sont très importants pour répondre aux exigences.

En guise de remarque, si les enregistrements proviennent d'une batterie de serveurs Web frontaux, je mettrais Express sur chaque serveur Web et au lieu de INSÉRER sur le serveur principal, je le ferais SEND les informations vers le back-end, en utilisant une connexion/transaction locale sur l'Express co-localisé avec le serveur Web. Cela donne une bien meilleure histoire de disponibilité à la solution.

Voilà donc comment je le ferais dans SQL Server. La bonne nouvelle est que les problèmes que vous rencontrerez sont bien compris et que des solutions sont connues. cela ne signifie pas nécessairement que c'est mieux que ce que vous pourriez réaliser avec Cassandra, BigTable ou Dynamo. Je laisserai quelqu'un de plus compétent en matière de non-sql-ish pour argumenter son cas.

Notez que je n'ai jamais mentionné le modèle de programmation, le support .Net et autres. Je pense honnêtement qu'ils ne sont pas pertinents dans les grands déploiements. Ils font une énorme différence dans le processus de développement, mais une fois déployés, peu importe la rapidité du développement, si la surcharge ORM tue les performances :)

99
Remus Rusanu

Contrairement à la croyance populaire, NoSQL n'est pas une question de performances, ni même d'évolutivité. Il s'agit principalement de minimiser la soi-disant non-concordance d'impédance objet-relationnelle, mais aussi de l'évolutivité horizontale par rapport à l'évolutivité la plus typique verticale d'un SGBDR.

Pour la simple exigence d'inserts rapides et de recherches rapides, presque n'importe quel produit de base de données fera l'affaire. Si vous souhaitez ajouter des données relationnelles ou des jointures, ou si vous avez une logique transactionnelle ou des contraintes complexes à appliquer, vous voulez une base de données relationnelle. Aucun produit NoSQL ne peut comparer.

Si vous avez besoin de données sans schéma, vous souhaitez utiliser une base de données orientée document telle que MongoDB ou CouchDB. Le schéma lâche en est le principal attrait; Personnellement, j'aime MongoDB et je l'utilise dans quelques systèmes de reporting personnalisés. Je trouve cela très utile lorsque les besoins en données sont en constante évolution.

L'autre option principale de NoSQL est les magasins de valeurs-clés distribués tels que BigTable ou Cassandra. Ceux-ci sont particulièrement utiles si vous souhaitez faire évoluer votre base de données sur de nombreuses machines exécutant du matériel de base. Ils fonctionnent également très bien sur les serveurs, bien sûr, mais ne profitent pas du matériel haut de gamme ainsi que de SQL Server ou d'Oracle ou d'une autre base de données conçue pour la mise à l'échelle verticale, et évidemment, ils ne sont pas relationnels et ne sont pas bons pour faire respecter la normalisation ou les contraintes. En outre, comme vous l'avez remarqué, la prise en charge de .NET a tendance à être inégale au mieux.

Tous les produits de bases de données relationnelles prennent en charge le partitionnement d'un type limité. Ils ne sont pas aussi flexibles que BigTable ou d'autres systèmes DKVS, ils ne se partitionnent pas facilement sur des centaines de serveurs, mais cela ne ressemble vraiment pas à ce que vous recherchez. Ils sont assez bons pour gérer le nombre d'enregistrements par milliards, tant que vous indexez et normalisez correctement les données, exécutez la base de données sur un matériel puissant (en particulier des SSD si vous pouvez vous le permettre) et partitionnez sur 2 ou 3 ou 5 disques physiques si nécessaire.

Si vous remplissez les critères ci-dessus, si vous travaillez dans un environnement d'entreprise et que vous avez de l'argent à dépenser pour une optimisation décente du matériel et des bases de données, je m'en tiendrai à SQL Server pour l'instant. Si vous pincez des sous et que vous devez l'exécuter sur du matériel informatique cloud Amazon EC2 bas de gamme, vous voudrez probablement opter pour Cassandra ou Voldemort à la place (en supposant que vous pouvez faire fonctionner l'un ou l'autre) avec .NET).

16
Aaronaught

Très peu de gens travaillent à la taille de l'ensemble de lignes de plusieurs milliards de dollars, et la plupart du temps que je vois une demande comme celle-ci sur un débordement de pile, les données ne sont pas du tout proches de la taille pour laquelle elles sont signalées.

36 milliards, 3 milliards par mois, soit environ 100 millions par jour, 4,16 millions par heure, ~ 70k lignes par minute, 1,1k lignes par seconde entrant dans le système, de manière soutenue pendant 12 mois, en supposant qu'il n'y ait pas de temps d'arrêt.

Ces chiffres ne sont pas impossibles à long terme, j'ai fait des systèmes plus grands, mais vous voulez vérifier que ce sont vraiment les quantités que vous voulez dire - très peu d'applications ont vraiment cette quantité.

En termes de stockage/récupération et un aspect assez critique que vous n'avez pas mentionné est le vieillissement des données plus anciennes - la suppression n'est pas gratuite.

La technologie normale consiste à examiner le partitionnement, cependant, la recherche/récupération étant GUID basée, cela entraînerait de mauvaises performances, en supposant que vous devez obtenir chaque valeur correspondante sur toute la période de 12 mois. Vous pourrait placer un index clusterisé sur la colonne GUID obtiendra votre clusterd de données associé en lecture/écriture, mais à ces quantités et à la vitesse d'insertion, la fragmentation sera beaucoup trop élevée pour être prise en charge, et elle tomber par terre.

Je suggérerais également que vous aurez besoin d'un budget matériel très décent s'il s'agit d'une application sérieuse avec des vitesses de réponse de type OLTP, c'est-à-dire par quelques suppositions approximatives, en supposant très peu de frais généraux d'indexation sage, environ 2,7 To de données.

Dans le camp SQL Server, la seule chose que vous voudrez peut-être examiner est la nouvelle édition d'entrepôt de données parallèle (madison) qui est davantage conçue pour le découpage des données et l'exécution de requêtes parallèles contre elles pour fournir une vitesse élevée par rapport aux grands datamarts.

12
Andrew

"Je dois pouvoir stocker de petits bits de données (environ 50 à 75 octets) pour des milliards d'enregistrements (~ 3 milliards/mois pendant un an).

La seule exigence est des insertions et des recherches rapides pour tous les enregistrements avec le même GUID et la possibilité d'accéder au magasin de données à partir de .net. "

Je peux vous dire par expérience que cela est possible dans SQL Server, car je l'ai fait au début de 2009 ... et il fonctionne toujours à ce jour et assez rapidement.

La table a été partitionnée en 256 partitions, gardez à l'esprit que c'était la version SQL 2005 ... et nous avons fait exactement ce que vous dites, c'est-à-dire stocker des bits d'informations par GUID et récupérer par GUID rapidement.

Quand je suis parti, nous avions environ 2-3 milliards d'enregistrements, et la récupération des données était encore assez bonne (1-2 secondes si vous obtenez via l'interface utilisateur, ou moins si sur RDBMS) même si la politique de conservation des données était sur le point d'être instanciée.

Donc, pour faire court, j'ai pris le 8ème caractère (c'est-à-dire quelque part au milieu) de la chaîne GUID et SHA1 haché et jeté en tant que petit int (0-255) et stocké dans partition appropriée et utilisé le même appel de fonction lors de la récupération des données.

ping moi si vous avez besoin de plus d'informations ...

2
Goran B.

L'article suivant décrit l'importation et l'utilisation d'une table de lignes 16 milliards dans Microsoft SQL. http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table .

De l'article:

Voici quelques conseils distillés de mon expérience:

  • Plus vous avez de données dans une table avec un index cluster défini, plus il devient lent d'y importer des enregistrements non triés. À un moment donné, cela devient trop lent pour être pratique.
  • Si vous souhaitez exporter votre table dans le plus petit fichier possible, rendez-le au format natif. Cela fonctionne mieux avec les tableaux contenant principalement des colonnes numériques, car ils sont représentés de manière plus compacte dans les champs binaires que les données de caractères. Si toutes vos données sont alphanumériques, vous ne gagnerez pas grand-chose en les exportant au format natif. Ne pas autoriser les valeurs nulles dans les champs numériques peut encore compacter les données. Si vous autorisez un champ à être annulé, la représentation binaire du champ contiendra un préfixe de 1 octet indiquant le nombre d'octets de données qui suivront.
  • Vous ne pouvez pas utiliser BCP pour plus de 2 147 483 647 enregistrements car la variable de compteur BCP est un entier de 4 octets. Je n'ai pu trouver aucune référence à cela sur MSDN ou sur Internet. Si votre table se compose de
    plus de 2 147 483 647 enregistrements, vous devrez l'exporter en morceaux
    ou écrivez votre propre routine d'exportation.
  • La définition d'un index cluster sur une table pré-remplie prend beaucoup d'espace disque. Dans mon test, mon journal a explosé à 10 fois l'original
    taille de la table avant la fin.
  • Lors de l'importation d'un grand nombre d'enregistrements à l'aide de l'instruction BULK INSERT, incluez le paramètre BATCHSIZE et spécifiez le nombre
    enregistrements à valider à la fois. Si vous n'incluez pas ce paramètre,
    tout votre fichier est importé en une seule transaction, ce qui
    nécessite beaucoup d'espace de journal.
  • Le moyen le plus rapide d'obtenir des données dans une table avec un index cluster est de trier les données en premier. Vous pouvez ensuite l'importer en utilisant le BULK
    Instruction INSERT avec le paramètre ORDER.
2
Charles Burns

Amazon Redshift est un excellent service. Elle n'était pas disponible lorsque la question a été initialement publiée en 2010, mais elle est désormais un acteur majeur en 2017. Il s'agit d'une base de données basée sur des colonnes, issue de Postgres, donc les bibliothèques de connecteurs SQL et Postgres standard fonctionneront avec elle.

Il est préférable de l'utiliser à des fins de rapport, en particulier d'agrégation. Les données d'une table unique sont stockées sur différents serveurs dans le cloud d'Amazon, distribuées par sur les touches distantes de table définies, de sorte que vous dépendez de la puissance CPU distribuée.

Ainsi, les SELECT et en particulier les SELECT agrégés sont extrêmement rapides. Le chargement de données volumineuses doit être effectué de préférence avec la commande COPY à partir des fichiers csv Amazon S3. Les inconvénients sont que les suppressions et les mises à jour sont plus lentes que d'habitude, mais c'est pourquoi Redshift n'est pas principalement une base de données transnationale, mais plutôt une plate-forme d'entrepôt de données.

1
Martin Taleski

Il y a un fait inhabituel qui semble ignoré.

"Fondamentalement, après avoir inséré 30 lignes de mil dans une journée, je dois récupérer toutes les lignes avec le même GUID (peut-être 20 lignes) et être raisonnablement sûr que je les récupérerai toutes) "

Ne nécessitant que 20 colonnes, un index non clusterisé sur le GUID fonctionnera très bien. Vous pouvez regrouper sur une autre colonne pour la dispersion des données entre les partitions.

J'ai une question concernant l'insertion des données: comment est-elle insérée?

  • S'agit-il d'un encart en vrac selon un certain horaire (par minute, par heure, etc.)?
  • De quelle source ces données sont-elles extraites (fichiers plats, OLTP, etc.)?

Je pense qu'il faut y répondre pour aider à comprendre un côté de l'équation.

1
Josef Richberg

Vous pouvez essayer d'utiliser Cassandra ou HBase, bien que vous deviez lire comment concevoir les familles de colonnes selon votre cas d'utilisation. Cassandra fournit le sien) langage de requête, mais vous devez utiliser Java de HBase pour accéder directement aux données. Si vous devez utiliser Hbase, je vous recommande d'interroger les données avec Apache Drill de Map-R qui est un Open Source Le langage de requête de Drill est conforme à SQL (les mots clés dans drill ont la même signification qu’ils auraient dans SQL).

0
Yayati Sule