Actuellement, je suis en train d'expérimenter avec un peu de Haskell serveur web écrit en composant logiciel Enfichable qui charge et met à la disposition du client un grand nombre de données. Et j'ai une très, très dur le temps de prendre le contrôle sur le processus de serveur. À des moments aléatoires les processus utilise beaucoup de CPU pour les secondes, les minutes et devient irresponsive aux demandes des clients. Parfois, l'utilisation de la mémoire pointes (et parfois gouttes) des centaines de méga-octets en quelques secondes.
J'espère que quelqu'un a plus d'expérience avec des longue Haskell processus qui utilisent beaucoup de mémoire et peut me donner quelques conseils pour rendre la chose plus stable. J'ai été le débogage de la chose pendant des jours maintenant et je commence à avoir un peu désespérée ici.
Un petit aperçu de mon installation:
Sur le démarrage du serveur, j'ai lu sur 5 giga-octets de données dans un grand (imbriqué) de Données.La carte-comme la structure en mémoire. Le imbriquée de la carte est de valeur stricte et toutes les valeurs à l'intérieur de la carte sont des types de données avec tous leur domaine complètement ainsi. J'ai mis beaucoup de temps à s'assurer de pas non évaluée thunks sont à gauche. L'importation (selon mon système de charge) prend environ 5 à 30 minutes. La chose étrange est la fluctuation des séries consécutives est plus grand que je m'attends, mais c'est un autre problème.
Le big data structure de vie à l'intérieur d'un 'TVar" qui est partagé par tous les threads de client générée par le composant logiciel Enfichable serveur. Les Clients peuvent demander des parties arbitraires de données à l'aide d'un petit langage de requête. Le montant de la demande de données est généralement de petite taille (jusqu'à 300 ko environ) et ne touche qu'une petite partie de la structure de données. Tous en lecture seule demande sont effectués à l'aide d'un readTVarIO', de sorte qu'ils ne nécessitent aucune STM transactions.
Le serveur est démarré avec les indicateurs suivants: +RTS-N -I0 -qg-qb. Cela démarre le serveur en mode multithread, désactiver le temps d'inactivité et parallèle GC. Cela semble accélérer le processus beaucoup.
Le serveur fonctionne principalement sans aucun problème. Cependant, chaque maintenant et puis une demande d'un client et les pics de l'UC à 100% (ou même plus de 100%) et continue de le faire pour un long moment. Pendant ce temps, le serveur ne répondent pas à la demande plus.
Il y a peu de raisons que je pense que peut entraîner l'utilisation du PROCESSEUR:
La demande prend juste beaucoup de temps car il y a beaucoup de travail à faire. C'est peu probable parce que parfois, il arrive pour les demandes qui ont prouvé être très rapide dans les courses précédentes (avec rapide je veux dire 20-80ms ou presque).
Il y a encore quelques non évaluée thunks qui doivent être calculées avant que les données peuvent être traitées et envoyées au client. C'est d'ailleurs peu probable, avec la même raison que pour le point précédent.
En quelque sorte, la collecte des ordures coups de pied dans et commencer la numérisation de l'ensemble de mon 5GO tas. Je peux imaginer que cela peut prendre beaucoup de temps.
Le problème est que je n'ai aucune idée de comment comprendre ce qui se passe exactement et quoi faire à ce sujet. Parce que le processus d'importation prend beaucoup de temps de profilage des résultats de ne pas me montrer quelque chose d'utile. Il semble y avoir aucun moyen conditionnelle, d'activer et de désactiver le générateur de profils à partir de code.
Personnellement, je soupçonne que le GC est le problème ici. Je suis en utilisant GHC7 qui semble avoir beaucoup d'options pour adapter la façon GC fonctionne.
Ce GC paramètres recommandez-vous lors de l'utilisation de grands tas généralement très stable de données?