fun[ctional] spark with scala
Post on 21-Apr-2017
391 Views
Preview:
TRANSCRIPT
13 Junio 2016
Fun[ctional] Sparkwith Scala
Quienes somos
Fun[ctional] Spark with Scala
José Carlos García Serrano Arquitecto Big Data en Stratio.
Granadino e ingeniero por la ETSII, master de Big Data en la UTad, certificado en Spark y AWS
Amante de las nuevas tecnologías y de las arquitecturas basadas en Big Data
FanBoy de cosas como:
● Scala● Spark● Akka● MongoDB● Cassandra
Pero todos tenemos un pasado:
● Delphi● C++● BBDD SQL● Hadoop
Quienes somos
Fun[ctional] Spark with Scala
David Vallejo Navarro Desarrollador Scala en Stratio.
Trabajando con Scala desde 2012 (si...cuando nadie sabía qué era eso de Scala)
Actualmente cursando un máster en Investigación informática.
He trabajado en:
● DSLs para la creación de aplicaciones sociales
● Sistemas distribuidos
● Aplicaciones WEB
● Migración de antiguas arquitecturas a Scala
● Y ahora, Big Data!
Ah! Y tengo un blog de Scala: www.scalera.es
José Carlos García SerranoArquitecto Big Data
jcgarcia@stratio.com
CONTACTO
ÍNDICE
INTRODUCCIÓN1
2
3
VENTAJAS DE SCALA EN SPARK
DESVENTAJAS DE SCALA EN SPARK4
David Vallejo NavarroDesarrollador Big Data
dvallejo@stratio.com
SCALA AVANZADO CON SPARK
1 INTRODUCCIÓN
Fun[ctional] Spark with Scala
¿Qué es Scala?
2003 - Martin Odersky, estando borracho, ve un anuncio de mantequilla de cacahuete Reese sobre
el chocolate y tiene una idea. Crea Scala, un lenguaje que unifica las construcciones de los
lenguajes funcionales y los orientados a objetos. Consigue cabrear a los partidarios de ambos tipos
de lenguaje que declaran al unísono la jihad.
Incomplete, and Mostly Wrong History of Programming Languages por James Iry
Fun[ctional] Spark with Scala
¿Qué es Scala?
CARACTERÍSTICAS PRINCIPALES
CORRE EN LA JVM1
2
3
MULTIPARADIGMA
TIPADO ESTÁTICO
INFERENCIA DE TIPOS4
5 HERENCIA MÚLTIPLE
Fun[ctional] Spark with Scala
Scala en Noviembre de 2014
72.992 miembros319 meetups
72.992 miembros319 meetups
Fun[ctional] Spark with Scala
Scala en Junio de 2016 (1 año y 7 meses después)
233.375 miembros570 meetups
Fun[ctional] Spark with Scala
Algunas empresas que usan Scala
Fun[ctional] Spark with Scala
Spark Scala
+ =
2 VENTAJAS DESCALA ENSPARK
Fun[ctional] Spark with Scala
2. VENTAJAS
2.1 Ventajas de usar Scala
• Uso de JVM
-> Librerías - Polimorfismo - Gestión
• Estáticamente tipado
-> Optimización del uso de memoria y de los algoritmos aplicados
• Modularidad
-> Grandes proyectos entendibles por humanos
• Sintaxis simple y rápido desarrollo
-> Programación funcional, poco código y simplicidad
• Multi-threading y concurrencia
-> Akka y la programación funcional son nuestros amigos
Fun[ctional] Spark with Scala
Los inicios como padawan scalero son duros y no puros ...
Fun[ctional] Spark with Scala
2. VENTAJAS
Java??
Ventajas
• trait JavaNoMola {
val advantages : Seq[String] = ???
}
Desventajas
• No data-centric language
• Líneas de código infinitas
• Difícil uso de colecciones
• Var = efectos de lado
• Concurrencia descontrolada
Python??
Ventajas
• Data-centric language
• Fácil uso de colecciones
Desventajas
• Tipado dinámico
• Compilado mejor que interpretado
Performance - Errores
• No es modular
• Mala integración con Hadoop
• Api limitada de Streaming
Y por qué no en C ...
Fun[ctional] Spark with Scala
2. VENTAJAS
Fun[ctional] Spark with Scala
2. VENTAJAS
Probablemente en un futuro veremos a Spark como la colección de elementos distribuidos de Scala
Fun[ctional] Spark with Scala
2. VENTAJAS
2.2 Ventajas de usar Scala en Spark
• Escrito en Scala
• RDD es una colección distribuida, funciones conocidas map, flatMap, groupBy, foreach, etc …
• Lambda va de serie
• RDD tipados -> Datasets tipados y no tipados
• Poco código para realizar ETLs y apps sencillas
• Datos inmutables
• Efectos de lado minimizados (Closure)
• Evaluación perezosa (Lazy)
Fun[ctional] Spark with Scala
2. VENTAJAS
Funciones conocidas por cualquier escalero ...
def flatMap[U: ClassTag](f: T => TraversableOnce[U]): RDD[U] = withScope { val cleanF = sc.clean(f) new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.flatMap(cleanF))}
private[spark] class MapPartitionsRDD[U: ClassTag, T: ClassTag]( var prev: RDD[T], f: (TaskContext, Int, Iterator[T]) => Iterator[U], // (TaskContext, partition index, iterator) preservesPartitioning: Boolean = false) extends RDD[U](prev) {
override def compute(split: Partition, context: TaskContext): Iterator[U] = f(context, split.index, firstParent[T].iterator(split, context))
Fun[ctional] Spark with Scala
Fun[ctional] Spark with Scala
2. VENTAJAS
val textFile = sc.textFile("hdfs://...")
val counts = textFile.flatMap(line => line.split(" "))
.map(word => (word, 1))
.reduceByKey(_ + _)
JavaRDD<String> textFile = sc.textFile("hdfs://...");
JavaRDD<String> words = textFile.flatMap(new FlatMapFunction<String, String>() {
public Iterable<String> call(String s) { return Arrays.asList(s.split(" ")); }
});
JavaPairRDD<String, Integer> pairs = words.mapToPair(new PairFunction<String, String, Integer>() {
public Tuple2<String, Integer> call(String s) { return new Tuple2<String, Integer>(s, 1); }
});
JavaPairRDD<String, Integer> counts = pairs.reduceByKey(new Function2<Integer, Integer, Integer>() {
public Integer call(Integer a, Integer b) { return a + b; }
});
Java
Típico word count, pero refleja la realidad … Scala vs Java vs Python
Scala Pythontext_file = sc.textFile("hdfs://...")
counts = text_file.flatMap(lambda line: line.split(" ")) \
.map(lambda word: (word, 1)) \
.reduceByKey(lambda a, b: a + b)
Fun[ctional] Spark with Scala
Fun[ctional] Spark with Scala
2. VENTAJAS
Nuestra querida inmutabilidad ...
• Mutabilidad y concurrencia no mola -> Efectos de lado
• Al ser inmutable un RDD puede ser recreado en cualquier momento
• Difícil mantenimiento de datos que mutan -> update de memoria y disco -> Pésimo performance
• Queremos programación funcional y transformaciones que son funciones
Fun[ctional] Spark with Scala
2. VENTAJAS
Lazy?? mismo concepto de una variable lazy de scala pero en RDD
• Todas las transformaciones se van añadiendo al DAG de operaciones
• Solo son ejecutadas cuando realizamos una acción
• Se computan las transformaciones de las que depende la acción
• Las que no dependan de la acción no son computadas
Odersky querría este concepto para sus colecciones ;)
Fun[ctional] Spark with Scala
def collect(): Array[T] = withScope { val results = sc.runJob(this, (iter: Iterator[T]) => iter.toArray) Array.concat(results: _*)}
def map[U: ClassTag](f: T => U): RDD[U] = withScope { val cleanF = sc.clean(f) new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF))}
def runJob[T, U: ClassTag]( rdd: RDD[T], func: (TaskContext, Iterator[T]) => U, partitions: Seq[Int], resultHandler: (Int, U) => Unit): Unit = { if (stopped.get()) { throw new IllegalStateException("SparkContext has been shutdown") } val callSite = getCallSite val cleanedFunc = clean(func) logInfo("Starting job: " + callSite.shortForm) if (conf.getBoolean("spark.logLineage", false)) { logInfo("RDD's recursive dependencies:\n" + rdd.toDebugString) } dagScheduler.runJob(rdd, cleanedFunc, partitions, callSite, resultHandler, localProperties.get) progressBar.foreach(_.finishAll()) rdd.doCheckpoint()
Fun[ctional] Spark with Scala
2. VENTAJAS
2.3 Optimizaciones en Scala
Tungsten
● Serialización
● DataSets
DataFrames
● UDFs más eficientes que en Python
MLlib
● Coste adicional de convertir Python objects a Scala objects
Recordemos el meetup de Fun[ctional] Spark with Scala ...
Fun[ctional] Spark with Scala
2. VENTAJAS
Y antes de spark 1.6 ...
Fun[ctional] Spark with Scala
2. VENTAJAS
desde Spark 1.4 tungsten ya optimizaba algunas funciones de DataFrames de Scala
3 SCALA AVANZADOCON SPARK
Fun[ctional] Spark with Scala
3. Scala avanzado
Fun[ctional] Spark with Scala
3.1 Implícitos
def mean(xs: RDD[Int]): Double = xs.sum / xs.count
mean(rdd)
Queremos calcular la media de un RDD:
Fun[ctional] Spark with Scala
3.1 Implícitos
Implícitos: partes de código que se ejecutan sin ser llamados
Fun[ctional] Spark with Scala
3.1 Implícitos
implicit val timeout = 5000
def tryConnection(dbUri: String)(implicit timeout: Int) = ???
tryConnection("127.0.0.1/8080")
case class Point(x: Int, y: Int)
implicit def tupleToPoint(tuple: (Int, Int)): Point = Point(tuple._1, tuple._2)
def sumPoints(p1: Point, p2: Point) = Point(p1.x + p2.x, p1.y + p2.y)
sumPoints(Point(1, 2), (3, 4))
Valores implícitos
Funciones implícitas
Fun[ctional] Spark with Scala
3.1 Implícitos
implicit class RichSparkRDD(rdd: RDD[Int]) {
def mean: Double = rdd.sum / rdd.count}
rdd.mean //new RichSparkRDD(rdd).mean
Podemos utilizar una implicit class para expandir funcionalidad:
Fun[ctional] Spark with Scala
3.2 Funciones de orden superior
Funciones que reciben funciones y/o devuelven funciones
Fun[ctional] Spark with Scala
3.2 Funciones de orden superior
type Term = Inttype Result = Inttype Operation = (Term, Term) => Result
def add: Operation = (n1, n2) => n1 + n2def sub: Operation = (n1, n2) => n1 - n2
def calculate(n1: Term, n2: Term)(f: Operation): Result = f(n1, n2)
calculate(2, 5)(add)calculate(1, 6)((n1, n2) => n1 * n2)
Construyendo una calculadora
Fun[ctional] Spark with Scala
3.2 Funciones de orden superior
def withSparkContext[T](name: String)(blockCode: SparkContext => T): T = {
val sparkConf = new SparkConf().setAppName(name).setMaster("local[4]") val sc = new SparkContext(sparkConf)
val result = blockCode(sc)
sc.stop()
result}
¿Y en Spark…?
withSparkContext("Meetup SDK") { sc =>
val myRDD = sc.parallelize(List(1, 2, 3, 4))
// ...}
Fun[ctional] Spark with Scala
3.3 For comprehension
Map, flatMap, syntactic sugar ….
Fun[ctional] Spark with Scala
3.3 For comprehension
Métodos map y flatMap
val myRDD = sc.parallelize(List(1, 2, 3, 4))
myRDD map (_ + 1) //RDD(2, 3, 4, 5)
myRDD flatMap (i => List(i - 1, i + 1)) // RDD(0, 2, 1, 3, 2, 4, 3, 5)
Fun[ctional] Spark with Scala
3.3 For comprehension
Iterando sobre una colección de tweets
case class Tweet(id: Int, content: String, retweets: Int, user: String)
case class VipUserFactor(id: Int, factor: Double)
tweets.flatMap ( tweet => vipUsers.filter(_.id == tweet.id).map ( vipUser => tweet.retweets * vipUser.factor ))
Fun[ctional] Spark with Scala
3.3 For comprehension
Syntactic sugar al rescate!
case class Tweet(id: Int, content: String, retweets: Int, user: String)
case class VipUserFactor(id: Int, factor: Double)
for { tweet <- tweets vipUser <- vipUsers if tweet.id == vipUser.id} yield tweet.retweets * vipUser.factor
Fun[ctional] Spark with Scala
3.4 Type Classes
Patrón de diseño que nos permite extender funcionalidad a distintos tipos al vuelo usando implícitos
trait MyCollection[T[Int]] {
def sum(coll: T[Int]): Double def size(coll: T[Int]): Long}
Fun[ctional] Spark with Scala
3.4 Type Classes
Quiero testear mi core con listas en memoria
implicit object RDDAsCollection extends MyCollection[RDD] { def sum(coll: RDD[Int]) = coll.sum def size(coll: RDD[Int]) = coll.count}
implicit object ListAsCollection extends MyCollection[List] { def sum(coll: List[Int]) = coll.sum def size(coll: List[Int]) = coll.size}
Fun[ctional] Spark with Scala
3.4 Type Classes
Quiero testear mi core con listas en memoria
implicit class RichMyCollection[T[_]](coll: T[Int])(implicit ev: MyCollection[T]) {
def mean = ev.sum(coll) / ev.size(coll)
}
List(1, 2, 3).meanrdd.mean
4 DESVENTAJASDE SCALAEN SPARK
Fun[ctional] Spark with Scala
Fun[ctional] Spark with Scala
4. DESVENTAJAS
Desventajas de usar Scala en Spark
• Curva de aprendizaje para desarrolladores
• Curva de aprendizaje para Data Scientists en Machine Learning
• Costoso en tiempo para realizar PoC
• Código Javero
• Performance en la JVM (recordemos el anterior meetup)
• + Algoritmos implementados en Python - Algoritmos MLlib distribuidos
Fun[ctional] Spark with Scala
4. DESVENTAJAS
override def hasNext: Boolean = { if (!finished) { if (!gotNext) { nextValue = getNext() if (finished) { closeIfNeeded() } gotNext = true } } !finished } override def next(): U = { if (!hasNext) { throw new NoSuchElementException("End of stream") } gotNext = false nextValue }}
private[spark] abstract class NextIterator[U] extends Iterator[U] { private var gotNext = false private var nextValue: U = _ private var closed = false protected var finished = false
def closeIfNeeded() { if (!closed) { closed = true close() } }
Código Spark = Java Style
Fun[ctional] Spark with Scala
Haría vomitar al mismísimo Odersky ...
Fun[ctional] Spark with Scala
4. DESVENTAJAS
JVM
• Los objetos de Java consumen más memoria de la que deberían
“abcd” 4 bytes en Nativo UTF-8 y 48 bytes en Java
• El GC de Java tiende a sobre trabajar y no tiene suficiente info.
Fun[ctional] Spark with Scala
4. DESVENTAJAS
Difícil de aprender??
Coursera Scala Specialization
Scalera
Scala Center
BIG DATACHILD`S PLAY
Gracias!!
Stratio busca Talento
Contacto:jcgarcia@stratio.comes.linkedin.com/in/gserranojc
dvallejo@stratio.comes.linkedin.com/in/davidvallejonavarro
PREGUNTAS
top related