Contexte :
J'ai créé une application Web que j'aimerais pouvoir évoluer raisonnablement bien. Je sais que je ne suis pas Google ou Twitter, mais mon application utilise une quantité assez importante de données pour chaque utilisateur et a donc des exigences de données assez élevées. Je veux être prêt à évoluer raisonnablement bien sans avoir à tout ré-architecturer plus tard.
Je me considère comme un développeur de logiciels, pas un expert en bases de données. C'est pourquoi je poste ici. J'espère que quelqu'un avec beaucoup plus d'expertise en base de données pourra me donner des conseils.
Avec un nombre d'utilisateurs relativement important, mais rien de tel que les numéros Facebook, je m'attends à avoir une base de données qui ressemble à ceci:
Une "grande table":
- 250 millions d'enregistrements
- 20 colonnes
- Environ 100 Go de données
- Dispose d'une clé étrangère bigint indexée (20)
- A une colonne varchar (500) indexée string_id
- A une colonne int (11) "value"
4 autres tables:
- 10 millions d'enregistrements chacun
- Environ 2 à 4 Go de données chacun
- chacun de ces tableaux comprend 4 à 8 colonnes
- une colonne est datetime date_created
- une colonne est la colonne varchar (500) string_id
- une ou deux colonnes de chacune de ces tables seront sélectionnées dans une jointure
L'une de ces tables est utilisée pour stocker des moyennes - son schéma est bigint (20) id, varchar (20) string_id, datetime date_created, float average_value
Ce que je veux faire - deux requêtes relativement coûteuses:
Calculez de nouvelles valeurs moyennes:
- À l'aide d'une clé étrangère, sélectionnez jusqu'à plusieurs millions d'enregistrements distincts dans la grande table.
- Calculez une nouvelle moyenne, regroupée par string_id.
- Insérez les résultats dans le tableau des moyennes.
- Telle qu'elle est actuellement construite, cette requête utilise deux jointures.
Créez des enregistrements en lecture seule dénormalisés pour les utilisateurs au service:
- Utilisez une clé étrangère pour sélectionner entre 1 000 et 40 000 enregistrements dans la grande table.
- Joignez-vous à chacune des quatre autres tables de l'enregistrement le plus récent avec la colonne id chaîne.
- Insérez les résultats dans un tableau dénormalisé.
- Ces enregistrements sont destinés au front-end pour afficher des informations aux utilisateurs.
- Telle qu'elle est actuellement construite, cette requête utilise quatre jointures.
Je prévois d'exécuter chacune de ces requêtes coûteuses sur une base de données principale par lots qui transmettra ses résultats à un serveur de base de données frontal en temps réel qui gère les demandes des utilisateurs. Ces requêtes seront exécutées à intervalles réguliers. Je n'ai pas décidé combien de fois. La requête moyenne pourrait être effectuée peut-être une fois par jour. La requête de dénormalisation devra être plus fréquente, peut-être toutes les quelques minutes.
Chacune de ces requêtes s'exécute actuellement en quelques secondes dans MySQL sur une machine très bas de gamme avec un ensemble de données avec 100 000 enregistrements dans la «grande table». Je m'inquiète à la fois de ma capacité à évoluer et des coûts de l'évolutivité.
Questions :
- Cette approche semble-t-elle judicieuse? Y a-t-il quelque chose de mal à l'évidence du point de vue global?
- Un SGBDR est-il le bon outil, ou devrais-je envisager d'autres solutions de "big data" comme quelque chose dans la famille Hadoop? Mon inclination est d'utiliser un SGBDR car les données sont structurées et s'intègrent bien dans le modèle relationnel. À un certain moment cependant, je crois comprendre que je ne pourrai peut-être plus utiliser un SGBDR. Est-ce vrai? Quand ce commutateur serait-il nécessaire?
- Est-ce que ça marchera? Ces requêtes peuvent-elles être exécutées dans un délai raisonnable? Je peux attendre peut-être des heures pour la requête # 1, mais la requête # 2 devrait se terminer en quelques minutes.
- Que dois-je considérer du point de vue matériel? Quels sont les goulots d'étranglement RAM et CPU susceptibles d'être? Je suppose que la conservation des index dans la RAM est importante. Y a-t-il autre chose que je devrais considérer?
- À un moment donné, je devrai probablement partitionner mes données et utiliser plusieurs serveurs. Mon cas d'utilisation semble-t-il être déjà dans cette catégorie, ou vais-je être capable de faire évoluer une seule machine verticalement pendant un certain temps? Est-ce que cela fonctionnera avec 10 fois les données? 100x?