Conception d'architecture API pour des lectures rapides de fichiers texte avec 150 millions d'étiquettes uniques
Supposons un fichier texte avec 150 millions d'enregistrements uniques.
Chaque enregistrement a deux colonnes: (1) chaîne et (2) entier.
La chaîne est une étiquette unique et l'entier est la valeur de l'étiquette.
La seule requête retournera la valeur entière pour une étiquette donnée.
Nous explorons plusieurs architectures pour exposer ce fichier texte en tant qu'API.
Ce fichier texte est régénéré toutes les 72 heures. ~ 90% des données restent les mêmes pendant la régénération, mais cette régénération est contrôlée par un tiers. Nous recevons simplement un nouveau fichier texte toutes les 72 heures.
Nous visons des performances de requête de 100 ms à 500 ms par lecture.
Architecture 1
- Stockez le fichier texte sur le disque. Interrogez le fichier texte. Cache les requêtes en mémoire.
- Avantages: mise en œuvre simple. Facile à mettre à jour les données.
- Points négatifs: Inélégant. Les requêtes de lecture non mises en cache sont lentes.
Architecture 2
- Analysez le fichier texte dans une base de données traditionnelle / NoSQL, chaque ligne étant traitée comme un enregistrement / document de base de données. Exécutez des requêtes sur la base de données.
- Pour: Cela ressemble à une architecture standard.
- Inconvénients: La mise à jour d'enregistrements de base de données de 150 m est lente et semble inutile, d'autant plus que 90% des enregistrements restent les mêmes.
Architecture 3
- Utilisez Redis ou la base de données en mémoire pour stocker le fichier texte de 5 Go. Exécutez des requêtes sur la base de données en mémoire.
- Avantages: requêtes rapides. Facile à mettre à jour les données.
- Inconvénients: cher.
Architecture 4
- Utilisez ElasticSearch pour interroger les enregistrements.
- Avantages: ElasticSearch est conçu pour la recherche.
- Inconvénients: ES peut être excessif pour de telles requêtes simples.
Des questions:
Devrions-nous envisager d'autres architectures, ou y a-t-il des avantages / inconvénients que nous avons négligés?
Ce défi d'ingénierie semble courant: quelle est l'architecture la plus «standard» pour équilibrer les coûts / performances lorsqu'on essaie de produire des lectures rapides contre un magasin de données de 150 millions d'enregistrements qui changent?
Réponses
De manière générale, cela semble être un cas classique pour un flux ETL: obtenir le nouveau fichier, extraire les données, le transformer à votre format et le charger dans votre base de données. Quelques notes:
La chose importante à retenir est que le chargement et l'interrogation sont des opérations différentes et totalement indépendantes. Une question est "comment puis-je charger efficacement un fichier d'enregistrement quotidien de 150 millions dans un magasin de données lorsque 90% des enregistrements sont des doublons", et l'autre est "comment interroger efficacement un magasin clé / valeur d'enregistrements de 150 millions". Répondez à ces deux questions séparément, car elles sont indépendantes.
Pour votre première question, vous craignez que le chargement d'enregistrements identiques à 90% soit un gaspillage. Avez-vous mesuré le temps qu'il faut? La lecture de 150 millions d'enregistrements à partir d'un fichier texte devrait prendre quelques secondes , et un bon magasin de clés / valeurs devrait être en mesure d'optimiser les opérations de mise à jour redondantes. Vous pouvez également comparer le nouveau fichier au précédent pour créer une liste de modifications réelle dans le cadre de votre flux ETL, puis procéder au chargement. Définissez des métriques pour cette solution (temps total de lecture, diff, chargement, interruption de l'opération de requête pendant le chargement, etc.) afin que vous puissiez évaluer votre solution.
Pour la question n ° 2, évitez de mettre en œuvre des solutions personnalisées lorsqu'il existe des options standard. ElasticSearch peut être excessif car vous ne stockez que des entiers à clé, mais il existe de nombreux magasins de clés / valeurs qui vous donneront de bonnes performances pour les lectures, y compris la mise en cache de la mémoire sur disque, la mise en cache MRU ou différentes stratégies de mise en cache en fonction de votre utilisation, peut-être l'opération UPDATE sans opération mentionnée ci-dessus, et plus encore. Encore une fois, comme dans la question n ° 1, définissez des indicateurs de succès. Vous avez dit que le chargement de 5 Go dans la RAM coûte cher. Est-ce que c'est? De combien de RAM dispose votre serveur? Vous envisagez de mettre en cache les requêtes courantes. Est-ce nécessaire? À quelle vitesse les lectures non mises en cache sont-elles effectuées? Mesure! Avez-vous besoin d'une stratégie de mise en cache personnalisée telle que la mise en cache des enregistrements associés ? Examinez votre modèle d'utilisation.
Je ne peux pas vous dire quelle est la meilleure approche. Il y a trop de variables que vous seul connaissez - votre budget et votre modèle d'utilisation, les projets futurs pour le système et le potentiel d'extensibilité, la relation avec une source de données tierce (par exemple, peuvent-ils être convaincus de ne générer que des différences, ou ajouter des horodatages / balises de version pour les enregistrements, etc.). Tout ce que je peux faire, c'est suggérer des modèles de base: séparer les flux d'ingestion des flux de requêtes, utiliser des outils éprouvés et surtout mesurer, mesurer, mesurer.
Vous pouvez envisager l'approche adoptée par le cdb de DJBernstein , qui est:
cdb est un package rapide, fiable et simple pour créer et lire des bases de données constantes. Sa structure de base de données offre plusieurs fonctionnalités:
Recherches rapides: une recherche réussie dans une grande base de données ne nécessite normalement que deux accès au disque. Une recherche infructueuse n'en prend qu'un.
Faible surcharge: une base de données utilise 2 048 octets, plus 24 octets par enregistrement, plus l'espace pour les clés et les données.
Pas de limites aléatoires: cdb peut gérer n'importe quelle base de données jusqu'à 4 gigaoctets. Il n'y a pas d'autres restrictions; les enregistrements n'ont même pas besoin de rentrer dans la mémoire. Les bases de données sont stockées dans un format indépendant de la machine.
Remplacement rapide de la base de données atomique: cdbmake peut réécrire une base de données entière deux ordres de grandeur plus rapidement que les autres paquets de hachage.
Sauvegardes rapides de la base de données: cdbdump imprime le contenu d'une base de données au format compatible cdbmake.
cdb est conçu pour être utilisé dans des applications critiques telles que la messagerie électronique. Le remplacement de la base de données est sûr contre les pannes du système. Les lecteurs n'ont pas à faire de pause pendant une réécriture.
Vous voudrez probablement une implémentation plus moderne, qui n'a pas la limite de 4 Go, comme celle- ci.