Je tente d’effectuer un test d’importation depuis notre tableau existant. Nous avons environ 25 millions de messages à importer (messages normaux + conversations privées). Pour accélérer le processus, j’ai créé plusieurs copies du script d’importation afin de les exécuter simultanément et de répartir la charge des sujets. Cela a fonctionné sans problème pendant quelques jours, mais avec le temps, j’ai remarqué que la consommation de mémoire de chaque processus augmentait lentement jusqu’à environ 2 Go chacun. Finalement, le serveur a manqué de mémoire et a arrêté la base de données MySQL source vers le 16 millionième message.
J’ai augmenté la mémoire système de 24 Go à 32 Go, mais maintenant, lorsque j’essaie de redémarrer même un seul processus d’importation et de reprendre là où il s’était arrêté, ce processus consomme environ 10 Go de mémoire dès le départ, avant même de commencer l’importation des messages. Auparavant, je pouvais exécuter 8 processus d’importation simultanés ; maintenant, je ne peux en faire fonctionner que 2 dans un pool de mémoire plus large. Pourquoi existe-t-il une telle différence entre la consommation de mémoire lors d’une installation propre et celle lors du redémarrage d’un import après un échec ? Existe-t-il un moyen de réduire cette empreinte mémoire afin de pouvoir accélérer à nouveau le processus d’importation ? Un serveur disposant de 128 Go à 256 Go de mémoire serait prohibitivement coûteux (et inutile une fois l’importation terminée), et se limiter à 2 processus d’importation signifierait que l’importation prendra des semaines à s’achever.
Cela ressemble à une expression rationnelle bloquée dans une boucle ou quelque chose de similaire. Affichez des messages de débogage et sautez la ligne problématique lors de l’importation.
L’utilisation de la mémoire semble se produire entièrement pendant les sections « Chargement des messages existants… » (ou des sujets) du démarrage du script d’importation, et non pendant le traitement réel des messages. D’après ce que je vois, cette section récupère les informations sur les messages et les sujets depuis la base de données, et aucune expression régulière ne devrait être impliquée.
Les variables @posts et @topics semblent être utilisées pour des éléments tels que la méthode “topic_lookup_from_imported_post_id”. Cela semble logique, sauf que lors de la première exécution du script, l’utilisation de la mémoire n’a jamais approché les niveaux que j’observe maintenant, alors que ces méthodes fonctionnent toujours.
Avez-vous regardé les scripts d’importation par lots ? Ils pourraient avoir une empreinte mémoire plus faible.
Cependant, il est vrai que les scripts d’importation maintiennent en mémoire une carte reliant les anciens identifiants d’utilisateurs, de sujets et de publications aux nouveaux, ce qui consomme beaucoup de RAM, surtout si vous souhaitez plusieurs copies.
Vous comprenez bien qu’après avoir exécuté l’importation initiale, vous la relancerez pour importer uniquement les nouvelles données, et cela ira beaucoup plus vite, n’est-ce pas ? Ainsi, après avoir attendu un mois pour effectuer l’importation initiale, la dernière ne prendra pas autant de temps.
Je ne connais aucun script d’importation par lots. Se trouvent-ils quelque part dans le répertoire import_scripts ?
Oui, c’est là que je rencontre des difficultés. Tout se passait relativement bien pendant l’importation initiale avec 8 processus d’importation, jusqu’à ce que le système manque de mémoire. Maintenant, lorsque j’essaie de redémarrer le processus d’importation et de reprendre là où il s’était arrêté, chaque processus utilise environ cinq fois plus de mémoire qu’au moment du premier plantage.
Nous devons parvenir à une importation complète pour disposer d’un test fiable et définir des attentes réalistes quant au moment où cette migration pourra se produire réellement. Pour l’instant, je n’ai toujours pas une compréhension claire de ce à quoi m’attendre en termes de performances. J’ai également remarqué qu’au seuil de 16 millions de messages, la taille de la base de données dépasse déjà de plus de 50 % celle de notre base de données actuelle — ce qui est une surprise. Le temps d’importation prolongé ne rend pas cela impossible, mais il serait certes beaucoup plus pratique que l’attente soit exprimée en jours plutôt qu’en semaines.
Pour les sujets et les messages, il n’est pas vraiment envisageable d’exécuter des importations parallèles, car vous ne pouvez pas importer un message dans un sujet si le sujet et tous les messages précédents ne sont pas déjà importés. Je suppose que vous pourriez avoir des processus parallèles pour les utilisateurs et les sujets, mais pas pour les messages, sauf si vous réécrivez le script pour récupérer tous les messages d’un sujet, ce qui permettrait des importations parallèles ; c’est certainement réalisable, mais ce n’est pas ainsi que fonctionnent les scripts que j’ai utilisés. Mais vous aurez toujours le problème de la conservation en mémoire vive d’une carte d’identifiants anciens vers nouveaux.
Importer 25 millions de messages n’est pas pratique.
C’est exactement ce que je fais. J’ai divisé les sujets de sorte que chaque sujet ne soit géré que par un seul processus. Ce n’est pas une répartition parfaite, mais c’est plusieurs fois plus rapide qu’un processus linéaire unique.
C’est la partie la plus confuse. Je suppose qu’il le fait au fur et à mesure, et c’est pourquoi j’ai vu l’utilisation de la mémoire de chaque processus augmenter sur trois jours. Elles atteignaient environ 2 à 2,5 Go de mémoire chacune avant que la connexion à la base de données ne soit perdue.
Chaque processus ne maintiendrait-il la carte que pour les messages qu’il a importés ? Si c’est le cas, cela pourrait expliquer pourquoi l’utilisation de la mémoire a explosé après le redémarrage de l’importation.
Je pense que oui. Et les autres ne fonctionneront pas correctement car ils n’ont pas ces jours qui ont été importés par d’autres processus. Je ne pense pas que ce que vous faites fonctionnera.
Vous devrez soit examiner les scripts d’importation en lot, soit réécrire base.rb pour suivre les liens vers les identifiants d’importation d’une autre manière.
Il est fort probable que vous passiez plus de semaines à déboguer votre code qu’à attendre. La vitesse du processeur en mode mono-processus est votre meilleure option pour accélérer les choses.
Je n’ai jusqu’ici constaté aucun problème avec cette approche, bien que je puisse imaginer des difficultés avec certaines méthodes exécutées après l’importation des publications. Je vais probablement veiller à ce que tout s’arrête à ce stade, puis exécuter le reste de manière monothread pour garantir un traitement propre.
Cela dit, votre suggestion de gérer différemment les liens d’ID d’importation est probablement une bonne idée dans tous les cas. Conserver une quantité arbitraire de données dans certaines variables pendant toute la durée du script n’est pas très efficace.