web-dev-qa-db-fra.com

Hadoop une carte et multiples Réduire

Nous avons un grand jeu de données à analyser avec des fonctions multiples réduire.

Tous réduire Algorithme Travailler sur le même ensemble de données généré par la même fonction carte. Lire le gros jeu de données coûte trop de coûts pour le faire à chaque fois, il serait préférable de lire une seule fois et de passer les données mappées à des fonctions multiples réduire.

Puis-je faire cela avec Hadoop? J'ai cherché les exemples et l'intarweb mais je ne pouvais trouver aucune solution.

36
KARASZI István

Vous attendez-vous que chaque réducteur fonctionne sur exactement les mêmes données mappées? Mais au moins la "clé" devrait être différente puisqu'il décide que le réducteur sera réduit.

Vous pouvez écrire une sortie à plusieurs reprises dans MAPPER et sortie en tant que clé (où $ i est pour la I-theducder, et $ clé est votre clé d'origine). Et vous devez ajouter un "partitionneur" pour vous assurer que ces n enregistrements sont distribués dans des réducteurs, basés sur $ i. Ensuite, utilisez "groupingcomparator" pour regrouper des enregistrements par clé $.

Il est possible de faire cela, mais pas de manière triviale dans un point.

4
Victor

Peut-être qu'une solution simple serait d'écrire un travail qui n'a pas de fonction de réduction. Vous passerez donc toutes les données mappées directement à la sortie du travail. Vous venez de définir le nombre de réducteurs à zéro pour le travail.

Ensuite, vous écririez un travail pour chaque fonction de réduction différente qui fonctionne sur ces données. Cela impliquerait de stocker toutes les données mappées sur les HDF.

Une autre alternative pourrait être de combiner toutes vos fonctions de réduction dans un seul réducteur qui génère plusieurs fichiers, en utilisant une sortie différente pour chaque fonction différente. Plusieurs sorties sont mentionnées dans cet article pour Hadoop 0,19 . Je suis sûr que cette fonctionnalité est cassée dans la nouvelle API Mapreduce publiée avec 0,201, mais vous pouvez toujours l'utiliser dans l'API Mapred plus ancienne.

11
Binary Nerd

Vous pouvez utiliser des touches composites. Disons que vous avez besoin de deux types de réducteurs, "R1" et "R2". Ajouter des identifiants pour ceux-ci comme préfixe sur vos touches O/P dans le mappeur. Donc, dans le mappeur, une clé 'K' devient maintenant 'R1: K' ou 'R2: K'.

Ensuite, dans le réducteur, passez des valeurs aux implémentations de R1 ou R2 sur la base du préfixe.

3
Sameer Joshi

Je suppose que vous voulez exécuter différents réducteurs dans une chaîne. Dans Hadoop, les moyens de multiples réducteurs "exécutent plusieurs instances du même réducteur. Je vous proposerais que vous exécutez un réducteur à la fois, fournissant une fonction de carte triviale pour toutes les personnes sauf le premier. Pour minimiser le temps pour le transfert de données, vous pouvez utiliser la compression.

1
trebuchet

Je n'ai toujours pas votre problème, vous pouvez utiliser la séquence suivante:

base de données -> Carte -> Réduire (utilisez CAT ou NONE Selon les exigences), puis stockez la représentation des données que vous avez extraite. Si vous dites qu'il est suffisamment petit pour s'adapter à la mémoire, le stockez sur le disque ne devrait pas être un problème.

De plus, votre utilisation du paradigme MapReduce pour le problème donné est incorrect, en utilisant une seule fonction de carte et plusieurs " différents " réduire la fonction n'a pas de sens, il montre que vous utilisez juste carte pour passer des données à différentes machines pour faire des choses différentes. Vous n'avez pas besoin de Hadoop ni d'une autre architecture spéciale pour cela.

0
none

Bien sûr, vous pouvez définir plusieurs réducteurs. Pour le travail (Hadoop 0.20) Il suffit d'ajouter:

job.setNumReduceTasks(<number>);

Mais. Votre infrastructure doit soutenir les réducteurs multiples, ce qui signifie que vous devez

  1. avoir plus d'un processeur disponible
  2. régler mapred.tasktracker.reduce.tasks.maximum dans Mapred-Site.xml en conséquence

Et bien sûr, votre travail doit correspondre à certaines spécifications. Sans savoir ce que vous voulez faire exactement, je ne peux que donner des conseils généraux:

  • la clésortie Carte Avoir soit partitionnable par% numréducers OR Vous devez définir votre propre partitionneur: job.setPartitionerClass(...) Par exemple avec un partitionneur aléatoire ...
  • les données doivent être réduites dans le format partitionné ... (références nécessaires?)

Vous obtiendrez plusieurs fichiers de sortie, un pour chaque réducteur. Si vous souhaitez une sortie triée, vous devez ajouter un autre travail de lecture de tous les fichiers (plusieurs tâches de carte cette fois ...) et les écrire triés avec un seul réducteur ...

Jetez un coup d'œil aussi à la classe de combinants, qui est le réducteur local. Cela signifie que vous pouvez agréger (réduire) déjà en mémoire sur des données partielles émises par carte. Très bel exemple est l'exemple de WordCount. La carte émet chaque mot comme clé et son compte comme 1: (mot, 1). Le combinateur reçoit des données partielles de la carte, émet (,) localement. Le réducteur fait exactement la même chose, mais maintenant quelques-mots (combinés) sont déjà> 1. Sauve la bande.

0
Leonidas