Evolucion de big data @ mercadolibre.com
-
Upload
gabriel-eisbruch -
Category
Engineering
-
view
600 -
download
2
description
Transcript of Evolucion de big data @ mercadolibre.com
Evolución de BigData
@MercadoLibre
2014
Big Data Hoy
● 154 nodos fisicos● 1.9 PB de espacio disponible● ~ 7 Tb de RAM● ~ 3000 cores
Big Data Hoy - Crecimiento Diario
● ~= 4Tb de datos nuevos x Dia● > 10.000.000.000 Rows nuevas x Dia
Big Data Hoy - En cosas cotidianas
500.000 DVD’s
Big Data Hoy - En cosas cotidianas
1800 Mac Book Pro
Usos de BigData @ MELI
● Mejora de experiencia al Usuario
● Log Mining● Ad Hoc Análisis
Como empezamos ?
Algo de Historia
Algo de Historia
Algo de Historia
● Año 2011● 6 Nodos● 48Tb● 192 Gb de Ram● 72 Cpu’s
Algo de Historia
“Con que datos comenzamos?”
Algo de Historia
Almacenamiento de la Plataforma de Traqueo
PixelOld Storage Filer
Algo de Historia
Almacenamiento de la Plataforma de Traqueo
Pixel
Old Storage Filer
Hadoop Uploader & Compresor
Algo de Historia
public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text();
public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException { String line = value.toString(); StringTokenizer tokenizer = new StringTokenizer(line); while (tokenizer.hasMoreTokens()) { word.set(tokenizer.nextToken()); output.collect(word, one); } } }
public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException { int sum = 0; while (values.hasNext()) { sum += values.next().get(); } output.collect(key, new IntWritable(sum)); } }
public static void main(String[] args) throws Exception { JobConf conf = new JobConf(WordCount.class); conf.setJobName("wordcount");
conf.setOutputKeyClass(Text.class); conf.setOutputValueClass(IntWritable.class);
conf.setMapperClass(Map.class); conf.setCombinerClass(Reduce.class); conf.setReducerClass(Reduce.class);
conf.setInputFormat(TextInputFormat.class); conf.setOutputFormat(TextOutputFormat.class);
FileInputFormat.setInputPaths(conf, new Path(args[0])); FileOutputFormat.setOutputPath(conf, new Path(args[1]));
JobClient.runJob(conf); }
Algo de Historia
Algo de Historia
● Facil de explicar y usar (SQL)● Soporte de UDFS● Particionamiento de la información
simple● JDBC
Algo de Historia
SELECT count(1) FROM tracking WHERE ds>=’2014-09-16 00:00:00’AND ds>=’2014-09-16 23:59:59’AND PAGE_ID=’HOME’
Algo de Historia
Hadoop facil y disponible para todos
“Tenemos un entorno sobre el que hacer procesos batch y discovery. Entonces Manos a la obra.”
Proyectos
Recommendations
Proyectos - Recommendations
Premisa: “Si una serie de usuarios ven productos similares, entonces les interesan las mismas cosas (en un momento
dado)”
Proyectos - Recommendations
Session Categoria Score
1 MLA1051 30
1 MLA1052 45
2 MLA1051 15
2 MLA1052 25
2 MLA1053 18
Proyectos - Recommendations
Categ Origen Categ Recommendada Score
MLA1051 MLA1052 70
MLA1051 MLA1053 18
MLA1052 MLA1051 30
MLA1052 MLA1053 18
....
....
Proyectos - RecommendationsCREATE TEMPORARY FUNCTION category_encode AS 'com.ml.utils.udf.intdecode.CategoryEncode';CREATE TEMPORARY FUNCTION generate_score AS 'com.ml.utils.udf.score.GenerateScore';
INSERT OVERWRITE TABLE rc_user_relationsselect main.user,main.categ, if(main.score>100,100,main.score) from ( select user_hash as user , category_encode(request_data['_categid']) as categ, sum(generate_score(ds,31,3)) as score from tracking
where ds>='${startDate}' and
ds<='${endDate}' and user_id <> "" and user_hash<>"0" and page_id='PAGE_ID_VIP' and request_data['_categid'] <> "" and request_data['_categid'] is not null and request_data['_categid'] RLIKE "^[A-Z]{3}[0-9]+$" group by user_id, category_encode(request_data['_categid']) ) main
INSERT OVERWRITE TABLE rc_categ_recommendations SELECT ur1.categ_id as categ, ur2.categ_id as categ_recommend,
sum(ur1.score) as tot FROM rc_user_relations ur1
JOIN rc_user_relations ur2 on ur1.cust_id=ur2.cust_id WHERE ur2.score>6
AND ur1.categ_id <> ur2.categ_id group by ur1.categ_id, ur2.categ_id
order by categ, categ_recommend, tot desc;
Proyectos - Recommendations
“Buenisimo!!! Podemos calcular recomendaciones, pero… Esta info es Batch, como la mostramos a
nuestros usuarios”
Proyectos - Recommendations
Recommendations Api RedisDB
On-Line
Proyectos - Suggestions
Suggestions
Proyectos - Suggestions
● Calculamos lo más buscado del último año (> 50M de búsquedas distintas)
● Subimos esta data a un storage temporal● Cargamos la data a un cluster de árboles de
prefijos
SWIFT
Proyectos - Suggestions
Proxy MLA
Shard 0
Shard 1
Shard N
Otras fuentes de Datos
Otras fuentes de datos
● Load Balancer access-log● MercadoClics (clics/prints)● Scoring & Fraude● Seguridad
“Hasta aca pudimos resolver problemáticas Batch, el problema surgió cuando se necesito empezar a contar con
la información más rápido”
Real-Time
● Poder contar con la información a medida que se genera (t < 10s)
● Poder tomar acciones de forma instantánea
● Permitir a cualquier proyecto consumir los datos
● Poder trabajar sobre todo el volumen de información
Real-Time
Real-Time - Nueva Plataforma de Tracking
Load Balancer
WS
Stream
Hadoop
Real Time Consumers
Real-Time - Nueva Plataforma de Tracking - Stream
Sources
Complementador
Pipeline Consumidores
1
N
Real-Time - Por que Kafka?
● Escalabilidad Horizontal● Poco consumo de recursos● Rapido● Soporte de volúmenes muy elevados de tráfico● Confiable
Real-Time - Por que Kafka?
Proyecto usando Real-Time
Filter and Process
Std-INKReader
API
Stream
“Tenemos off-line y on-line, para BigData, que pasa con un warehouse tradicional? ”
DataWarehouse
DataWarehouse
Extract and Summarize Process
DataWarehouse
Proximos Pasos...
Proximos Pasos
● Real Time Analytics Query○ Impala○ Presto○ Shark
● Spark como remplazo a MapReduce● Consumo simple del Stream