18
Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/ HUG France #2 - 11 Avril 2012 Aller plus loin que map() et reduce() Ziad BIZRI [email protected] @BigDataEzako

Dépasser map() et reduce()

Embed Size (px)

Citation preview

Page 1: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

HUG France #2 - 11 Avril 2012

Aller plus loin que map() et reduce()

Ziad [email protected]@BigDataEzako

Page 2: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Pourquoi vous devez maîtriser MapReduce?

• Parce que c’est la base technique de tout l’écosystème Hadoop (Hive, Pig, Cascalog)

• Parce que c’est une façon différente de penser le code

• Parce qu’on est des codeurs et qu’on n’a pas peur

Page 3: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Running example

« J’ai des fichiers de logs HTTP et je veux la liste des user agents qui viennent sur mon site »

123.123.123.123 - - [26/Apr/2000:00:23:48 -0400] "GET /pics/wpaper.gif HTTP/1.0" 200 6248 "http://www.jafsoft.com/asctortf/" "Mozilla/4.05 (Macintosh; I; PPC)"

123.123.123.123 - - [26/Apr/2000:00:23:47 -0400] "GET /asctortf/ HTTP/1.0" 200 8130 "http://search.netscape.com/Computers/Data_Formats/Document/Text/RTF" "Mozilla/4.05 (Macintosh; I; PPC)"123.123.123.123 - - [26/Apr/2000:00:23:48 -0400] "GET /pics/5star2000.gif

HTTP/1.0" 200 4005 "http://www.jafsoft.com/asctortf/" "Mozilla/4.05 (Macintosh; I; PPC)"

123.123.123.123 - - [26/Apr/2000:00:23:51 -0400] "GET /cgi-bin/newcount?jafsof3&width=4&font=digital&noshow HTTP/1.0" 200 36 “http://www.jafsoft.com/asctortf/” "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7"

Page 4: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Mapper - simplepublic class UserAgentMapper implements Mapper<LongWritable, Text, Text, IntWritable> {

private IntWritable one = new IntWritable(1);private Text outputKey = new Text();

private static String extractUserAgent(Text logEntry) {}

@Overridepublic void map(LongWritable key, Text logEntry,

OutputCollector<Text, IntWritable> collector, Reporter reporter)throws IOException {

outputKey.set(extractUserAgent(logEntry));collector.collect(outputKey, one);

}

@Overridepublic void configure(JobConf jobconf) {}

@Overridepublic void close() throws IOException {}

}

Page 5: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Les détails du mapper

• configure():

- ouvrir une connexion

- lire un fichier et le garder en mémoire

- lire les paramètres passés dans la JobConf

• close():

- idéal pour fermer une connexion

- trop tard pour émettre des paires <clé, valeur>

• reporter:

- framework pour agréger des statistiques

- contient des méthodes utilitaires

Page 6: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Reducer - simplepublic class UserAgentReducer implements Reducer<Text, IntWritable, Text, IntWritable> {

@Overridepublic void reduce(Text key, Iterator<IntWritable> values,

OutputCollector<Text, IntWritable> collector, Reporter reporter)throws IOException {

int sum = 0;while (values.hasNext()) {

sum += values.next().get();}collector.collect(key, new IntWritable(sum));

}

@Overridepublic void configure(JobConf jobconf) {}

@Overridepublic void close() throws IOException {}

}

Page 7: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Exemple de base

• Problème: beaucoup de paires <useragent, 1> en mémoire

- risque de spooling sur le disque

coût d’exécution substantiel Il faut utiliser un Combiner!

Page 8: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Combiner - simple

En entrée les paramètres de sortie du Mapper

En sortie les paramètres d’entrée du Reducer

public class UserAgentCombiner implements Reducer<Text, IntWritable, Text, IntWritable> {

@Overridepublic void reduce(Text key, Iterator<IntWritable> values,

OutputCollector<Text, IntWritable> collector, Reporter reporter)throws IOException {

int sum = 0;while (values.hasNext()) {

sum += values.next().get();}collector.collect(key, new IntWritable(sum));

}

Page 9: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Besoin plus avancé

« Je cherche tous les user agent uniques par adresse IP »

– Approche 1: deux MapReduce, d’abord les user agent pour chaque utilisateur, puis les résultats uniques

Coûteux en temps d’exécution

– Approche 2: dans le mapper sortir <useragent, ipaddress> puis utiliser un set dans le reducer pour dédupliquer

Le combiner devient plus complexe

Coûteux en RAM au niveau du reducer

Page 10: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

MapCopySortReduce?

Page 11: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Sort

Le tri est « gratuit » dans MapReduce

– Partitioner• détermine l’instance du reducer pour une clé

(fonction de hash)

– Ouput Value Grouping Comparator• groupe les paires pour chaque appel de

Reducer.reduce()

– Output Key Comparator• trie les paires groupées pour l’iterator de

reduce()

Comment en tirer parti?

Page 12: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Optimisations

• Mapper: <user_agent####ip_address, ip_address>

• On groupe les paires <user_agent####*>

• Les groupes sont triés par le Output Key Comparator défaut

• Reducer: compter le nombre de ip_address uniques

• Combiner: réduire le nombre de user_agent####ip_address dupliqués

Page 13: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Mapper - optimisépublic class UserAgentMapper implements Mapper<LongWritable, Text, Text, Text> {

private Text outputKey = new Text();private Text outputValue = new Text();

private static String extractUserAgent(Text logEntry) {}private static String extractIpAddress(Text logEntry) {}

@Overridepublic void map(LongWritable key, Text logEntry,

OutputCollector<Text, Text> collector, Reporter reporter)throws IOException {

String ipaddress = extractIpAddress(logEntry);outputKey.set(extractUserAgent(logEntry) + "####" + ipaddress);outputValue.set(ipaddress);collector.collect(outputKey, outputValue);

}}

Page 14: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Combiner - optimisépublic class UserAgentCombiner implements Reducer<Text, Text, Text, Text> {

@Overridepublic void reduce(Text key, Iterator<Text> values,

OutputCollector<Text, Text> collector,Reporter reporter) throws IOException {

collector.collect(key, values.next());}

}

Page 15: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Sort - optimisé

public class UserAgentPartitioner implements Partitioner<Text, Text> {@Overridepublic int getPartition(Text key, Text value, int numPartitions) {

String keyString = key.toString();int position = keyString.indexOf("####");return keyString.substring(0, position).hashCode() % numPartitions;

}}public class UserAgentGroupingComparator implements RawComparator<Text> {

@Overridepublic int compare(Text o1, Text o2) {

String o1String = o1.toString();String o2String = o2.toString();String key1 = o1String.substring(0, o1String.indexOf("####"));String key2 = o2String.substring(0, o2String.indexOf("####"));return key1.compareTo(key2);

}

@Overridepublic int compare(byte[] o1, int o1Start, int o1Length, byte[] o2, int o2Start,

int o2Length) {return compare(new Text(o1), new Text(o2));

}}

Page 16: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Reducer - optimisépublic class UserAgentReducer implements Reducer<Text, Text, Text, IntWritable> {

@Overridepublic void reduce(Text key, Iterator<Text> values,OutputCollector<Text, IntWritable> collector, Reporter reporter)throws IOException {String lastIp = null;int sum = 0;while (values.hasNext()) {String currentIp = values.next().toString();if (lastIp == null) {lastIp = currentIp;sum += 1;} else if (lastIp.equals(currentIp)) {// Do nothing} else {sum += 1;}}

String keyString = key.toString();collector.collect(new Text(keyString.substring(0, keyString.indexOf("####"))),new IntWritable(sum));}

}

Page 17: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

Questions?

MapperReducer Shuffler

Partitioner CopyReporter Configure Sort

Combiner Join MultipleInputs

Collector

Page 18: Dépasser map() et reduce()

Ce support est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France. - http://creativecommons.org/licenses/by-nc-nd/2.0/fr/

HUG France #2 - 11 Avril 2012

Aller plus loin que map() et reduce()

Merci pour votre attention

Ziad [email protected]@BigDataEzako