33 votes

Besoin d'un moyen de trier un fichier journal de 100 Go par date

Si, pour une raison étrange, je me retrouve avec un 100 GO de fichier journal qui est non triés (en fait c'est partiellement trié), tandis que les algorithmes que j'essaie d'appliquer nécessitent des données triées. Une ligne dans le fichier journal ressemble

data <date> data data more data

J'ai accès à C# 4.0 et de 4 GO de RAM sur mon poste de travail. J'imagine que l'opération de fusion-tri de certains type serait le mieux, mais à court de mise en œuvre de ces algorithmes de moi - même- je veux vous demander si il y a une sorte de raccourci que j'ai pu prendre.

D'ailleurs l'analyse de la chaîne de date avec DateTime.Parse() est très lent et prend beaucoup de temps PROCESSEUR - Le calage detaux est seulement de 10 MO/sec. Est-il un moyen plus rapide que le suivant?

    public static DateTime Parse(string data)
    {            
        int year, month, day;

        int.TryParse(data.Substring(0, 4), out year);
        int.TryParse(data.Substring(5, 2), out month);
        int.TryParse(data.Substring(8, 2), out day);

        return new DateTime(year, month, day);
    }

J'ai écrit que pour accélérer DateTime.Parse() et cela fonctionne bien, mais il est encore de prendre un seau en charge de cycles.

Notez que le fichier de journal, je suis intéressé en heures, minutes et secondes. Je sais que je peux fournir DateTime.Parse() avec le format, mais qui ne semble pas accélérer beaucoup.

Je suis à la recherche d'un coup de pouce dans la bonne direction, grâce à l'avance.

EDIT: Certaines personnes ont suggéré que j'utilise de comparaison de chaîne afin de comparer des dates. Qui serait à l'œuvre pour la phase de tri sélectif, mais j'ai besoin d'analyser des dates pour les algorithmes. Je n'ai toujours aucune idée de la façon de trier les 100 GO de fichiers sur 4 go de ram libre, sans le faire manuellement.

EDIT 2 : et Bien, grâce à plusieurs suggestions que j'utilise windows tri, j'ai découvert qu'il existe un outil similaire pour Linux. Fondamentalement, vous appeler trier et elle corrige tout pour vous. Pendant que nous parlons, c'est de faire quelque chose, et j'espère que ça va finir bientôt. La commande que j'utilise est

sort -k 2b 2008.log > 2008.sorted.log

-k indique que je veux sur la deuxième ligne, qui est une date-time de la chaîne dans l'habituel YYYY-MM-DD hh:mm:ss.msek format. Je dois avouer que le man-pages sont dépourvues d'expliquer toutes les options, mais j'ai trouvé beaucoup d'exemples en exécutant info coreutils 'sort invocation'.

Je vais faire rapport des résultats et de délais. Cette partie du journal est d'environ 27GB. Je pense tri 2009 et 2010 séparément puis de les fusionner les résultats dans un fichier unique avec le tri -m option.

Edit 3 Ainsi, la vérification de iotop suggère que c'est la lecture en petits morceaux du fichier de données, puis furieusement de faire quelque chose afin de les traiter. Ce processus semble être assez lente. =(

sort n'est pas à l'aide de la mémoire, et d'un seul cœur. Quand il n'lire les données à partir du disque, ce n'est pas de traitement du tout. Suis-je en train de faire quelque chose de mal?

Edit 4 Trois heures, et il est encore en train de faire la même chose. Maintenant j'en suis au stade où je veux essayer de jouer avec les paramètres de la fonction, mais je suis de trois heures investies... je vais abandonner en environ 4 heures, et essayer de le mettre pour la nuit le calcul avec plus intelligente de la mémoire et de l'espace des paramètres...

Edit 5 Avant que je rentre à la maison, j'ai redémarré le processus avec la commande suivante:

sort -k 2b --buffer-size=60% -T ~/temp/ -T "/media/My Passport" 2010.log -o 2010.sorted.log

Il est revenu ce, ce matin:

sort: write failed: /media/My Passport/sortQAUKdT: File too large

Wraawr! J'ai pensé que je voudrais simplement ajouter que beaucoup de lecteurs de disque dur que possible pour accélérer le processus. Apparemment, l'ajout d'un lecteur USB était la pire idée jamais. Pour le moment, je ne peux même pas dire si c'est à propos de FAT/NTFS ou quelque chose comme ça, parce que fdisk me dit que la clé USB est un "mauvais périphérique"... sans blague. Je vais essayer de donner un autre aller plus tard, pour l'instant, nous allons mettre ce projet dans le peut-être l'échec de la pile.

Avis Final Cette fois, il a travaillé, avec la même commande que précédemment, mais sans la problématique disque dur externe. Merci à vous tous pour votre aide!

L'analyse comparative

À l'aide de 2 poste de travail de qualité (au moins 70 mo/sec en lecture/écriture IO) disques durs sur le même contrôleur SATA, il m'a fallu 162 minutes pour trier un 30GO fichier journal. J'ai besoin de trier un autre 52 GO de fichier ce soir, je vais poster comment ça se passe.

18voto

Hans Passant Points 475940

Un code comme celui-ci est complètement lié à la vitesse à laquelle vous pouvez extraire les données du disque. Le fichier ne peut tout simplement jamais tenir dans le cache du système de fichiers, vous attendez donc toujours sur le disque pour fournir les données. Vous vous débrouillez plutôt bien à 10 Mo / s, l'optimisation du code n'aura jamais d'effet perceptible.

Obtenez un disque plus rapide. Défragmentez celle que vous avez comme étape intermédiaire.

15voto

Will Hartung Points 57465

Si une chaîne de tri de travail pour vous, alors il suffit d'utiliser le Windows commande de TRI. Trier le fichier et être fait avec elle. Il va heureusement trier vos 100 GO de fichiers, et c'est simple à utiliser.

Si vous avez besoin de filtrer et de convertir le fichier, plus précisément le champ de date, alors je voudrais simplement écrire un petit programme de conversion qui convertit le champ de données 0 rempli entier (comme le nombre de secondes depuis 1970, ou ce que vous voulez), et réécrit l'enregistrement. Ensuite, vous pouvez pipe (|) pour la sortie de la commande de tri, alors vous avez un fichier trié, c'est plus facilement analysé par votre programme utilitaire.

Je pense que l'erreur que vous faites est tout simplement essayer de faire tout cela en une seule fois. 100 go de données est beaucoup, et cela prend du temps à copier, mais il ne faut pas QUE long. Depuis que vous avez à les trier, vous avez déjà commencé à traiter avec une copie du fichier à un certain point (c'est à dire vous avez besoin d'autant d'espace libre sur votre machine pour gérer à la fois des copies à un certain moment), même avec un système externe de tri de routine comme de fusion de tri.

L'écriture d'un simple reformatter et de la tuyauterie pour le tri permettra d'économiser un couple de voyages à travers le fichier, et économiser de l'espace sur le disque, puisque vous serez inévitablement juste besoin de deux copies.

Je voudrais également ajuster le formateur en tirant uniquement les champs que je suis vraiment intéressé, et de faire toutes les "lourds" de l'analyse à ce point, de sorte que vous vous retrouvez avec est essentiellement un fichier au format que facilement manipulé par vos rapports de routines. De cette façon, vous économiserez temps plus tard, lorsque potentiellement l'exécution de vos rapports, plus d'une fois.

L'utilisation d'un simple CSV ou, mieux encore, une longueur fixe de format de fichier de sortie, si possible.

Assurez-vous que vos informations de date, si vous choisissez d'utiliser un entier, a tous les champs de la même longueur. Sinon le TRI utilité de ne pas les trier correctement (vous vous retrouvez avec 1 10 2 3 1 2 3 10. Vous êtes mieux d'avoir 01 02 03 10.).

Edit --

Nous allons l'aborder à partir d'un autre tact.

La grande question est "avez-vous besoin de toutes ces données". Cela se rapporte à la proposition antérieure au sujet de faire le lourd analyse en premier. Évidemment, plus vous pouvez réduire l'ensemble initial pour le mieux. Par exemple, il suffit de retrait de 10% des données est de 10 go.

Quelque chose que j'aime à penser comme une règle de pouce, surtout lorsqu'il s'agit d'un lot de données: "Si vous avez 1 Million de quelque chose, alors à chaque milliseconde sauvé, est à 20 minutes au large de la ligne de fond."

Normalement, nous ne pensons pas en termes de millisecondes pour notre travail, c'est plus ", le siège du pantalon", "qui se sent le plus rapide". Mais la 1ms == 20min/m est une bonne mesure pour obtenir une compréhension de la façon dont beaucoup de données que vous avez affaire, et combien de temps les choses devraient/pourraient prendre.

Pour votre cas, 100 go de données. Avec un butin de 100 octets par enregistrement, vous prenez 1 Milliards de lignes. 20 000 minutes par milliseconde. -- 5 heures 1/2. gulp (C'est une règle générale, si vous faites le calcul, il n'est pas tout à fait à cela.)

Ainsi, vous pouvez apprécier la volonté de réduire les données brutes, si possible.

C'était une des raisons qui m'reportée à la Windows commande de TRI. C'est un processus de base, mais celui qui est affecté par nuance, et qui peut utiliser certains d'optimisation. Les gens qui ont écrit TRIER eu le temps et la possibilité de le faire "optimale", à de nombreux égards. Si ils ont ou n'ont pas, je ne peux pas dire. Mais son une hypothèse juste qu'ils mettraient plus de temps et d'attention à ce processus, à faire leur TRI en tant que bonne pratique, par rapport à vous qui êtes sous un délai serré.

Il y a 3rd party de tri des utilitaires pour de grands ensembles de données, qui est probablement à l' (idéalement) fonctionnent mieux dans ce cas. Mais ce ne sont pas disponible pour vous (vous pouvez les obtenir, mais je ne pense pas que vous avez voulu précipiter et obtenir un autre organisme de services publics). Ainsi, le TRI est notre meilleure hypothèse pour l'instant.

Cela dit, la réduction de l'ensemble de données auront plus de poids que n'importe quelle sorte d'utilité.

Comment beaucoup de détails, avez-vous vraiment besoin? Et combien d'informations vous êtes vraiment suivi? Par exemple, si elle l'était, disons, statistiques web, vous pouvez avoir 1000 pages sur votre site. Mais même avec des horaires des numéros pour une année, 365 * 24 * 1000, c'est que de 8,7 M "compartiments" de l'information -- loin de 1B.

Alors, est-il prétraitement que vous pouvez faire qui ne nécessite pas de tri? La synthèse de l'information dans une mouture plus grossière de granularité? Vous pouvez le faire sans tri, simplement à l'aide de la mémoire en fonction de hachage cartes. Même si vous n'avez pas de "mémoire insuffisante" pour traiter tous les 100 go de données en un seul jet, vous avez probablement assez de le faire par morceaux (5 morceaux, 10 morceaux), et d'écrire les résultats intermédiaires.

Vous pouvez aussi avoir beaucoup plus de chance de fractionnement de la donnée. En mensuel, hebdomadaire ou fichier de morceaux. C'est peut-être pas facile à faire parce que les données sont "pour la plupart" triés. Mais, dans ce cas, si c'est par jour, les délinquants (c'est à dire les données qui sont hors de tri) peuvent être regroupés dans le fichier, avec le "out of order" choses " étant juste mixtes sur les barrières de l'périodes de temps (comme autour du jour de transitions, peut-être que vous avez des lignes comme 11:58, 11:59, 00:00, 00:01, 11:58, 00:02). Vous pourriez être en mesure de tirer parti de cette heuristique ainsi.

Le but étant que si vous pouvez un peu de façon déterministe de déterminer le sous-ensemble qui est hors de l'ordre, et de briser le fichier jusqu'à des morceaux de "dans les données de commande et de données de commande", votre tri tâche peut être BEAUCOUP plus petit. Trier les quelques lignes qui sont hors de l'ordre, et puis vous avez un problème de fusion (beaucoup plus simple que d'un problème de tri).

Ce sont des tactiques que vous pouvez prendre l'approche du problème. La synthèse est, évidemment, le meilleur, comme tout ce qui réduit la charge de données mesurables, est probablement en vaut la peine. Bien sûr, tout se résume à ce que vous voulez vraiment à partir des données, les rapports lecteur. C'est également un bon point à propos de "pré-matures-optimisation". Si ils ne sont pas des rapports sur elle, ne pas le traiter :).

13voto

James Westgate Points 6789

Réponse courte - chargez les données dans une base de données relationnelle, par exemple Sql Express, créez un index et utilisez une solution basée sur un curseur, par exemple DataReader, pour lire chaque enregistrement et l'écrire sur le disque.

9voto

Toad Points 7868

Pourquoi n'essayez-vous pas cet outil peu connu de Microsoft appelé logparser . Il vous permet essentiellement de faire une requête SQL sur un fichier CSV (ou tout autre fichier texte formaté).

Vous évite d'avoir à le pomper dans une base de données, à faire votre tri et à le pomper à nouveau

8voto

Tomas Petricek Points 118959

Juste pour répondre à votre question sur le tri d'un long fichier qui ne rentre pas dans le mémoire, vous aurez besoin d'utiliser certaines externe de tri algorithme tels que la Fusion de tri. Le processus est à peu près suivant:

  • La Partition de l'entrée en plusieurs parties qui s'inscrivent dans la mémoire et peuvent être triées à l'aide de la norme en mémoire algorithmes de tri (par exemple, 100 MO ou plus - vous aurez besoin de garder ~4 parties en mémoire à la fois). Trier toutes les pièces et de les écrire sur le disque.

  • Lire en deux parties à partir du disque (ils sont à la fois triées) et de les fusionner, ce qui peut être fait tout en même temps une itération sur les deux entrées. Écrire la fusion de l'ensemble de données à un autre endroit du disque. Notez que vous n'avez pas besoin de lire l' ensemble de la partie dans la mémoire - il suffit de lire/écrire dans les blocs que vous allez.

  • Répétez la fusion de pièces jusqu'à ce que vous n'avez qu'une seule partie (qui sera triée fichier avec toutes les données de l'original de votre jeu de données d'entrée).

Vous avez mentionné que les données sont partiellement trié déjà, donc ce serait une bonne idée de choisir un algorithme pour la mémoire de tri (dans la première phase) qui est efficace dans ce cas. Vous pouvez voir quelques suggestions sur cette question (même si je ne suis pas sûr que la réponse sera la même pour les très grands ensembles de données - et cela dépend de combien partiellement trié l'entrée est).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X