Apache Spark es un framework para procesamiento de datos en paralelo que permite el procesamiento de los mismos en la memoria. Es hasta 100x más rápido que Apache Hadoop. Hoy en día las aplicaciones estarán pensadas para DataWorkflows y Spark te permite esta interacción con esos datos ya sea en Scala o Python. Adicionalmente puedes aplicar una seríe de Transformaciones a esos datos y aplicar procesamiento en Grafos (GraphX) Machine Learning (MLLib)
2. Hands
–
On
• Instalación
en
su
sistema
• Introducción
a
Scala
• Ejercicios
con
Scala
• Break
• Introducción
a
Apache
Spark
• Ejemplo
de
Scala
con
Apache
Spark
• Preguntas
y
Respuestas
4. Instalación
en
su
sistema
• Descargar
de
ser
posible
en
hGps://spark.apache.org/downloads.html
• Descargar
la
versión
1.3.1
prebuilt
para
Hadoop
2.6
• Crear
una
carpeta
en
su
sistema
spark1.3
• Descomprimir
la
carpeta
y
renombrarla
a
spark1.3
5. Probando
instalación
• Dirigirse
a
su
carpeta
de
instalación
de
spark1.3
• Ejecutar
bin/spark-‐shell
• Se
abrirá
el
shell
de
Apache
Spark
con
Scala
scala
>
Nota:
Scala
es
completamente
descargable
de
hGp://www.scala-‐lang.org/download/all.html
6. Introducción
a
Scala
• Scala
es
un
lenguaje
orientado
a
objetos
(OOP)
y
de
programación
funcional
(FP)
• Compila
a
archivos
class
que
empaquetamos
como
JAR
(Java
Archive)
(Maven
o
SBT)
• Corre
sobre
la
Java
Virtual
Machine
• Creado
por
Mar^n
Odersky
• Cada
variable
es
un
objeto
y
cada
operador
es
un
método
• hGp://scala-‐lang.org
7. • Como
corre
sobre
la
JVM
nos
permite
usar
las
librerías
de
Java
• SCALA
CAMBIARÁ
LA
MANERA
EN
QUE
PIENSAS
COMO
PROGRAMAR
• Permite
escribir
código
de
manera
concisa
• No
te
desesperes
si
no
en^endes
al
principio
Introducción
a
Scala
8. Cadenas
• Abre
tu
prompt
de
Apache
Spark
(spark1.3)
bin/spark-‐shell
scala
>
“Hola
Mundo”
res0:
String
=
Hola
Mundo
scala>
"Hola
scala".getClass.getName
res2:
String
=
java.lang.String
9. Cadenas
scala>
val
s
=
"Hola
Scala
Meetup"
s:
String
=
Hola
Scala
Meetup
scala>
s.length
res4:
Int
=
17
scala>
s.foreach(println)
H
o
l
10. Cadenas
• Podemos
u^lizar
métodos
funcionales
como
filter
ej:
scala>
var
result
=
s.filter(_
!=
'l')
result:
String
=
Hoa
Scaa
Meetup
Ver
(StringOps,
StringLike,
WrappedString)
12. Cadenas
scala>
val
mensaje
=
"Apache
Spark
Meetup".map(c
=>c.toUpper)
mensaje:
String
=
APACHE
SPARK
MEETUP
Pero
también
podemos
usar
el
carácter
mágico
_
para
que
nuestro
código
se
vea
mucho
más
limpio
scala>
val
mensaje2
=
"Apache
Spark
Meetup".map(_.toUpper)
mensaje2:
String
=
APACHE
SPARK
MEETUP
A
el
método
map
se
le
pasan
funciones
(programación
funcional)
13. Cadenas
• Ver
como
funcionan
las
expresiones
regulares
scala>
val
address
=
"Dr
Levante
1234
Edif
302
".replaceAll("[0-‐9]","x")
address:
String
=
"Dr
Levante
xxxx
Edif
xxx
”
14. Clases
implicitas
• Las
clases
implícitas
deben
ser
definidas
en
un
ámbito
donde
las
definiciones
de
método
son
permi^das
(Scala
2.10)
• Permiten
agregar
nuestros
propios
métodos
a
objetos
sin
tener
que
extenderlos
16. Números
Char
-‐16
bit
unsigned
Byte
-‐
8
Bit
signed
value
Short
–
16
bit
signed
value
Int
–
32
bit
signed
value
Long
-‐
64
bit
signed
value
Float
–
32
bit
IEEE
754
single
precision
float
Double
–
64
bit
IEEE
754
single
precision
float
17. Números
“100”.toInt
-‐
Usar
métodos
to
para
cas^ng
“100”.toFloat
….
Scala
no
^ene
operadores
++
ni
–
val
es
inmutable
Scala
>
var
a
=
1
18. Números
scala>
val
a
=
1
a:
Int
=
1
scala>
a
+=
1
<console>:22:
error:
value
+=
is
not
a
member
of
Int
a
+=
1
^
scala>
var
b
=
1
b:
Int
=
1
scala>
b+=1
scala>
b
res11:
Int
=
2
19. val
r
=
scala.u^l.Random
r.nextInt
Podemos
limitar
la
generación
r.nextInt(100)
Números
20. val
r
=
1
to
100
val
j
=
1
to
100
by
2
val
x
=
(1
to
10).toList
val
z
=
(1
to
100).toArray
Números
21. Estructuras
de
Control
• If/then/else
es
similar
a
Java
• Pueden
regresar
un
resultado
val
x
=
if(a)
y
else
b
scala>
val
x
=
if("a"=="a")
9
else
7
x:
Int
=
9
22. • for
y
foreach
• Nos
sirven
para
hacer
ciclos
y
sobre
todo
iterar
en
colecciones
(List,
Array,
Range)
scala>
val
samp
=
List("isra","memo","paco")
samp:
List[String]
=
List(isra,
memo,
paco)
scala>
for(n
<-‐
samp)
yield
n.capitalize
res20:
List[String]
=
List(Isra,
Memo,
Paco)
Estructuras
de
Control
23. scala>
samp.foreach(println)
isra
memo
Paco
• Si
se
requiere
más
lineas
samp.foreach{
e=>
|
val
nuevo
=
e.toUpperCase
|
println(nuevo)
|
}
Estructuras
de
Control
24. Estructuras
de
Control
• Es
muy
importante
saber
como
los
ciclos
son
trasladados
por
el
compilador
• for
loop
que
itera
sobre
una
colección
se
transforma
en
foreach
• for
loop
con
un
guard
se
traslada
a
una
secuencia
de
withFilter
seguida
de
un
foreach
• for
loop
con
un
yield
se
traslada
a
un
map
e
la
colección
25. Estructuras
de
Control
scala>
val
i
=
5
i:
Int
=
5
scala>
val
month
=
i
match{
|
case
1
=>
"enero"
|
case
2
=>
"febrero"
|
case
3
=>
"marzo"
|
case
4
=>
"Abril"
|
case
5
=>
"Mayo”
|
case
_
=>
“Mes
inválido”
|
}
month:
String
=
Mayo
26. Métodos
• Los
métodos
los
definimos
como
def
scala>
def
square(x:Int):
Int
=
x
*
x
square:
(x:
Int)Int
scala>
square(5)
res33:
Int
=
25
27. Colecciones
• Las
colecciones
en
escala
son
amplias
y
debemos
aprender
a
u^lizarlas
dependiendo
el
contexto
de
nuestro
requerimiento
• List,
Array,
Map
y
Set
• Métodos
como
filter,
foreach,
map
y
reduceLe„
aplican
a
las
colecciones
^enen
loops
dentro
de
sus
algoritmos
• El
predicado
es
un
método
o
función
anónima
que
toma
uno
o
más
parámetros
y
regresa
un
valor
booleano
28. Colecciones
Ej:
(i:int)
=>
i
%
2
==
0
//función
anónima
_
%
2
==
0
val
list
=
List.range(1,20)
val
events
=
list.filter(_
%
2
==
0)
30. Colecciones
Sequence
:
es
una
colección
lineal
de
elementos
que
serán
indexados
Map:
Con^ene
una
colección
key/value
como
un
Java
Map,
Ruby
Hash
o
un
diccionario
en
Python
Set
:es
una
colección
que
con^ene
elementos
sin
duplicar
31. Colecciones
• Escoger
un
Sequence..¿La
secuencia
debe
ser
indexada
o
implementada
como
una
linked
list?
• ¿Queremos
una
colección
mutable
o
inmutable?
• Imutables:List,
Queue,
Range,Stack,
Stream,
String,
Vector
• Mutables:Array,
ArrayBuffer,ArrayStack,
LinkedList,ListBuffer,
MutableLIst,
Queue,
Stack,
StringBuilder
32. Colecciones
• Escoger
Map
es
más
sencillo
• Puedo
escoger
un
SortedMap
que
almacenará
elementos
ordenados
por
llave
• LinkedHashMap
para
almacenar
elementos
en
orden
de
inserción
• HashMap,LinkedHashMap,ListMap,Map,Sorte
dMap,TreeMap,WeakHashMap
33. Colecciones
• Escoger
un
set
es
similar
a
un
map
• Existen
clases
mutables
e
inmutables
• BitSet,HashSet,LinkedHashSet,ListSet,TreeSet,
Set,SortedSet
• Algunas
otras
colecciones
(Enumera^on,Iterator,Op^on,Tuple)
34. Colecciones
Un
método
de
transformación
es
un
método
que
construye
una
colección
a
par^r
de
una
existente.
Esta
incluye
métodos
como
map,
filter,
reverse
etc.
Existen
colecciones
strict
y
lazy.
Strict
aloja
los
elementos
inmediatamente
en
memoria
Lazy
no
aloja
los
elementos
inmediatamente
y
las
transformaciones
no
construyen
nuevos
elementos
hasta
que
se
ejecutan.
35. Colecciones
• Métodos
de
filtrado:
collect,diff,dis^nct,drop,dropWhile,filter,filterNot,find,foldLe„,fo
ldRight,head,headOp^on.
• Métodos
de
transformación:
diff,dis^nct,collect,flatMap,map,reverse,sortWith,takeWhile,zip,
zipWithIndex
• Métodos
de
agrupación:
groupBy,par^^on,sliding,span,splitAt,unzip
• Métodos
matemá^cos
y
de
información:
contains,containsSlice,count,endWith,exist,find,forAll,indexOf…
max,min,product,size,sum.
40. Colecciones
Ejercicios:
-‐ Filtrar
los
mayores
a
4
-‐ Filtrar
los
mayores
a
5
-‐ Sumar
los
elementos
de
la
colección
Mayor
información
:
hGp://www.scala-‐lang.org/api/2.10.4/
index.html#scala.collec^on.Seq
41. Programación
Funcional
• Se
construyen
programas
usando
funciones
puras
• Las
funciones
no
^enen
efectos
colaterales
• Modificar
una
variable,
una
estructura,
establecer
un
campo
en
un
objeto,
arrojar
una
excepción,
imprimir
en
la
consola,
leer
o
escribir
un
archivo,
dibujar
en
pantalla
• Programación
funcional
es
una
restricción
en
COMO
escribimos
programas
pero
no
en
lo
QUE
nuestros
programas
pueden
expresar.
48. Spark
101
• Map
reduce
es
el
modelo
de
programación
y
el
corazón
de
Hadoop
• Toma
datos
de
manera
masiva
y
los
divide
a
través
de
un
número
de
nodos
en
un
clúster
• Tiene
dos
fases
la
fase
Map
y
la
fase
Reduce
• Se
programa
en
Java
y
se
envía
de
manera
distribuida
al
clúster
(también
se
puede
en
Python,
R,
.NET
a
través
de
Hadoop
Streaming)
51. Spark
101
• Es
di‹cil
programar
en
Map
Reduce
• Cuellos
de
botellas
de
performance
• Existen
abstracciones
como
Hive
y
Pig
• Aún
así
es
complicado
desarrollar
52. Spark
• Spark
es
un
motor
de
cómputo
DISTRIBUIDO
• Op^mizado
para
velocidad,
fácil
uso
e
implementación
de
análisis
sofis^cado.
• Es
un
proyecto
open
source
de
APACHE
• APIS
en
Python,
Java
y
Scala
…R
en
Spark
1.4!
• Lo
u^lizamos
para
tareas
de
ciencia
en
datos
• Lo
u^lizamos
para
aplicaciones
de
procesamiento
a
gran
escala
(terabytes
o
petabytes
de
datos
=
BIG
DATA)
54. Resilient
Distributed
Datasets
(RDDs)
-‐Abstracción
de
programación
de
SPARK
-‐Se
desarrollan
programas
en
términos
de
transformaciones
y
acciones
(Dataflows)
-‐Colección
de
objetos
que
pueden
ser
almacenados
en
memoria
o
en
disco
a
través
de
un
clúster
-‐Estan
desarrollados
para
transformaciones
en
paralelo
(map,
filter,
etc)
-‐
Los
RDDs
pueden
ser
almacenados
en
memoría,
en
disco
u
ambos.
-‐Tolerancia
a
fallos
Spark
55. //Spark
context
sc
variable
especial
de
contexto
//RDD
Base
scala>
var
data
=
sc.textFile(“sample-‐syslog.log")
//Transformación
=
las
transformaciones
son
“lazy”
val
info
=
data.filter(_.contains("INFO"))
info.cache()
//Acciones
=
Hasta
aquí
se
ejecutan
las
val
n1=
info.filter(_.contains(“Alice”).count())
Val
n2=info.filter(_.contains(“Chuck”).count())
Spark
56. Spark
• Formatos:
Archivos
de
texto,
JSON,CSV,TSV,SequenceFiles,
ObjectFiles,Formatos
de
entrada/salida
de
Hadoop
Amazon
S3,HDFS,Avro,Parquet,Cassandra,
Hbase,Mongo,Elas^cSearch
etc.
57. • Spark
traza
una
grafo
lineal
de
transformaciones
y
acciones
• El
driver
se
encarga
de
enviar
nuestra
aplicación
a
todos
los
nodos
con
este
grafo
• Se
enviaran
instrucciones
a
los
workers
para
ser
ejecutadas
(archivos
de
texto,
hdfs
etc)
• Cada
worker
leerá
los
datos
y
hará
transformaciones
y
hará
cache
de
los
datos
Spark
tras
bambalinas
58. Spark
• RDDS
^enen
dos
^pos
de
operaciones
• TRANSFORMACIONES:
Las
transformaciones
siempre
me
regresarán
un
nuevo
RDD
y
no
son
procesadas
inmediatamente
• ACCIONES:Las
acciones
siempre
me
devolverán
un
resultado
(se
regresan
al
driver)
59. Spark
Clúster
Spark
Driver
Worker
Worker
Worker
Bloque
1
Bloque
2
Bloque
3
El
driver
se
encarga
de
enviar
nuestra
aplicación
a
todos
los
nodos
(workers)
60.
Driver
Worker
Worker
Worker
Bloque
2
Bloque
3
Spark
Bloque
1
Cache
1
Cache
2
Cache
3
Una
vez
que
los
procesa
los
pone
en
cache
por
cada
worker
scala>
var
data
=
sc.textFile(“sample-‐syslog.log")
//Transformación
=
las
transformaciones
son
“lazy”
val
info
=
data.filter(_.contains("INFO"))
info.cache()
//Acciones
=
Hasta
aquí
se
ejecutan
las
val
n1=
info.filter(_.contains(“Alice”).count())
Val
n2=info.filter(_.contains(“Chuck”).count())
Procesar
y
poner
en
cache
Procesar
y
poner
en
cache
Procesar
y
poner
en
cache
61. Spark
Driver
Worker
Worker
Worker
Bloque
2
Bloque
3
Bloque
1
scala>
var
data
=
sc.textFile(“sample-‐syslog.log")
//Transformación
=
las
transformaciones
son
“lazy”
val
info
=
data.filter(_.contains("INFO"))
info.cache()
//Acciones
=
Hasta
aquí
se
ejecutan
las
val
n1=
info.filter(_.contains(“Alice”).count())
Val
n2=info.filter(_.contains(“Chuck”).count())
Se
efectúa
la
acción
count
y
se
hace
en
paralelo.
Adicionalmente
por
cada
worker
serán
agregados
los
resultados
y
enviados
de
vuelta
al
driver.
62. Spark
WORD
COUNT
scala>
val
f
=
sc.textFile("Readme.md")
scala>
val
wc=f.flatMap(l
=>
l.split(“
”)).map(word=>(word,1)).reduceByKey(_
+
_)
scala>
wc.saveAsTextFile("salida1")
63. Spark
• En
procesos
ETL
es
muy
común
juntar
dos
conjuntos
de
registros
• Los
RDDs
pueden
juntarse
o
hacer
union.
• Tener
en
cuenta
los
Pairs
RDDS
que
son
RDDs
especiales
64. scala>
val
format
=
new
java.text.SimpleDateFormat("yyyy-‐MM-‐dd")
format:
java.text.SimpleDateFormat
=
java.text.SimpleDateFormat@f67a0200
scala>
case
class
Register(d:
java.u^l.Date,uuid:String,cust_id:String,lat:Float,lng:Float)
defined
class
Register
scala>
case
class
Click(d:java.u^l.Date,uuid:String,landing_page:Int)
defined
class
Click
scala>
val
reg
=
sc.textFile("reg.tsv").map(_.split("t")).map(
|
r
=>
(r(1),
Register(format.parse(r(0)),
r(1),
r(2),
r(3).toFloat,
r(4).toFloat))
|
)
scala>
val
clk
=
sc.textFile("clk.tsv").map(_.split("t")).map(
|
c
=>
(c(1),
Click(format.parse(c(0)),
c(1),
c(2).trim.toInt))
|
)
scala>reg.join(clk).collect()
Spark
65. Spark
• Enviar
aplicaciones
• Para
pruebas
el
shell
es
bueno
y
se
puede
reu^lizar
mucho
código
• En
ambientes
de
producción
las
aplicaciones
se
envían
a
través
de
bin/spark–submit
• Se
debe
tener
instalado
SBT
para
aplicaciones
en
Scala
y
poder
compilar
y
empaquetar
• Maven
en
el
caso
de
Java
67. Spark
1.-‐
Crear
build.sbt
2.-‐
Crear
lib,project,src
y
target
3.-‐
Dentro
de
src
crear
main
4-‐
Dentro
de
main
crear
java,
resources
y
scala
mkdir –p src/{main,test}/{java,resources,scala}!
mkdir lib project target!
68. name := "Spark Meetup Wordcount”!
!
version := "1.0”!
!
scalaVersion := "2.10.4”!
!
libraryDependencies ++= Seq(!
"org.apache.spark" %% "spark-core" % "1.3.0" % "provided",!
"org.apache.spark" %% "spark-streaming" % "1.3.0" % "provided"!
)!
Spark
Crear
en
la
raíz
build.sbt
69. Spark
Ejecutamos
sbt
para
que
cree
el
proyecto
MacBook-‐Pro-‐de-‐Israel:scala-‐wsh
israelgaytan$
sbt
[info]
Loading
project
defini^on
from
/Users/israelgaytan/Documents/Lambda/scala-‐wsh/project/project
[info]
Loading
project
defini^on
from
/Users/israelgaytan/Documents/Lambda/scala-‐wsh/project
[info]
Set
current
project
to
Spark
Meetup
Wordcount
(in
build
file:/Users/israelgaytan/Documents/Lambda/
scala-‐wsh/)
EMPAQUETAMOS
>package
71. Y
POR
ÚLTIMO
ENVIAMOS
!
!
!
bin/spark-submit --class "com.vitatronix.SimpleApp" --master local[*] /
Users/israelgaytan/Documents/Lambda/scala-wsh/target/scala-2.10/spark-
meetup-wordcount_2.10-1.0.jar!
!
Le pasamos en los parámetros en nombre de la clase, el cluster en este caso
–master local[*] tomará todos los cores de la máquina y finalmente el Jar
que empaquetamos con SBT!
Spark