Slides

Transcrição

Slides
Aficionado por open
source
Expert em
escalabilidade
Mestre Jedi Scala
Prefere uma sessão de
profiling a uma tarde
na praia
@flaviowbrasil
Fundador de Startups
Dois Easter Eggs
publicados
Padawan Scala
Tem um cachorro
@herval
A Nuvem de Som
12 horas de novo conteúdo/ minuto
350 milhões de usuários/mês
12 milhões de horas ouvidas/mês
1 usuário no espaço
Era uma vez uma startup...
Era uma vez uma startup...
Uma base de código
Era uma vez uma startup...
Uma base de código
Um punhado de construtores
Move fast
and break
things
Um milhão de features
Base de código gigante
Quebrando os muros
Muitos vilarejos, muitos idiomas
Muitos vilarejos, muitos idiomas
Microserviços → "tudo é http"
Culturas de código
Infraestrutura
Monitoramento
"production ready"
Ninguém entende ninguém
Move fast
without breaking everything, bitte.
Java
Java
Serviços de base
Bibliotecas compartilhadas
Monitoria
Autenticação/segurança
(cross-cutting concerns)
Java
Serviços de base
Bibliotecas compartilhadas
Monitoria
Autenticação/segurança
(cross-cutting concerns)
INFRAESTRUTURA BÁSICA
JVM-Kit
+ Finagle
Estudo de caso
O novo Stream
Reescrever pra quê?
Reescrever pra quê?
Cassandra
API
MySQL
Reescrever pra quê?
Cassandra
API
MySQL
Reescrever pra quê?
80% request queueing
Cassandra
API
MySQL
Reescrever pra quê?
Novas features
Latência
Vazão
Microserviços
API
Timeline
API
Timeline
Roshi
Autoriz.
Autentic.
API
Geo loc.
Timeline
Roshi
Autoriz.
Autentic.
API
Geo loc.
Timeline
Roshi
Autoriz.
Autentic.
API
Geo loc.
Playlists
Tracks
Usuários
Timeline
Roshi
Autoriz.
Likes
Autentic.
Coment.
API
Promoted
Geo loc.
Stats
Playlists
Tracks
Usuários
Timeline
Roshi
Autoriz.
Likes
Autentic.
Coment.
API
Promoted
Geo loc.
Stats
Playlists
...
Tracks
Usuários
Timeline
Roshi
Autoriz.
Likes
Buscar
Agregar
Autentic.
Coment.
API
Promoted
Geo loc.
Stats
Playlists
...
Tracks
Usuários
Timeline
Roshi
Buscar
Latência
Autoriz.
Likes
Autentic.
Coment.
API
Promoted
Geo loc.
Stats
Playlists
...
Tracks
Usuários
Timeline
Roshi
Agregar
Complexidade
Autoriz.
Likes
Autentic.
Coment.
API
Promoted
Geo loc.
Stats
Playlists
...
Tracks
Usuários
Timeline
Roshi
Scala
yay!
Buscar
Paralelizar
Futuros
Futuros
Referência para um
valor que será
disponibilizado no
futuro.
Futuros
val response: Future[Int] = …
// Não compila
response + 1
Futuros
val response: Future[Int] = …
// Adiciona um callback
response.onSuccess { int =>
println(int)
}
Futuros
val response: Future[Int] = …
// Compõe um novo futuro
val count: Future[Int] =
response.map { int =>
int + 1
}
Futuros
for {
user <- authenticate(request)
} yield {
}
Futuros
for {
user <- authenticate(request)
geo <- geoLocationFor(request, user)
} yield {
}
Futuros
for {
user <- authenticate(request)
geo <- geoLocationFor(request, user)
timeline <- timelineFor(user, geo)
} yield {
}
Futuros
for {
user <- authenticate(request)
geo <- geoLocationFor(request, user)
timeline <- timelineFor(user, geo)
resources <fetchTracks(timeline)
.join(fetchPlaylists(timeline))
.join(fetchComments(timeline))
} yield {
}
Futuros
for {
user <- authenticate(request)
geo <- geoLocationFor(request, user)
timeline <- timelineFor(user, geo)
resources <fetchTracks(timeline)
.join(fetchPlaylists(timeline))
.join(fetchComments(timeline))
} yield {
new EnrichedTimeline(timeline, resources)
}
Futuros
def handle(request: Request): Future[EnrichedTimeline] =
for {
user <- authenticate(request)
geo <- geoLocationFor(request, user)
timeline <- timelineFor(user, geo)
resources <fetchTracks(timeline)
.join(fetchPlaylists(timeline))
.join(fetchComments(timeline))
} yield {
new EnrichedTimeline(timeline, resources)
}
Futuros
+ NIO
Escalabilidade
Máquinas
Máquinas
Processos
Máquinas
Processos
Threads
Máquinas
Processos
Threads
Futuros
Futuros
def handle(request: Request): Future[EnrichedTimeline] =
for {
user <- authenticate(request)
geo <- geoLocationFor(request, user)
timeline <- timelineFor(user, geo)
resources <fetchTracks(timeline)
.join(fetchPlaylists(timeline))
.join(fetchComments(timeline))
} yield {
new EnrichedTimeline(timeline, resources)
}
Agregar
Funcional
Collections
val timeline: Timeline = …
val timeline: Timeline = …
val actorsToFetch: List[User] =
timeline.items.map(_.actor)
val timeline: Timeline = …
val actorsToFetch: List[User] =
timeline.items.map(_.actor)
val itemsByActor: Map[User, List[Item]] =
timeline.items.groupBy(_.actor)
val timeline: Timeline = …
val actorsToFetch: List[User] =
timeline.items.map(_.actor)
val itemsByActor: Map[User, List[Item]] =
timeline.items.groupBy(_.actor)
val numberOfItemsByActor: Map[User, Int] =
itemsByActor.mapValues(_.size)
def createEnrichedTimeline(
timeline: Timeline,
users: Map[User, EnrichedUser]) = {
timeline.items.map { item =>
new EnrichedItem(
item, users.get(item.actor))
}
}
Options
Option[T]
None
Some(value)
Options
def findUser(id: Int): Option[User]
// Não compila
render.json(findUser(666).name)
Options
def findUser(id: Int): Option[User]
// Compila
findUser(666).map {
case Some(user) => render.json(user.name)
case None => render.notFound
}
Pattern
Matching
case class User(name: String, gender: Gender, email: Email)
case class User(name: String, gender: Gender, email: Email)
timelineActors.foreach {
}
case class User(name: String, gender: Gender, email: Email)
timelineActors.foreach {
case User(name, Female, Email(_, “soundcloud.com”) =>
println(“mulher trabalhando na soundcloud”)
}
case class User(name: String, gender: Gender, email: Email)
timelineActors.foreach {
case User(name, Female, Email(_, “soundcloud.com”) =>
println(“mulher trabalhando na soundcloud”)
case User(name, Male, Email(_, “soundcloud.com”) =>
println(“homem trabalhando na soundcloud”)
}
case class User(name: String, gender: Gender, email: Email)
timelineActors.foreach {
case User(name, Female, Email(_, “soundcloud.com”) =>
println(“mulher trabalhando na soundcloud”)
case User(name, Male, Email(_, “soundcloud.com”) =>
println(“homem trabalhando na soundcloud”)
case User(name, gender, Email(_, “qconrio.com.br”) =>
println(“organizador da qconrio”)
}
case class User(name: String, gender: Gender, email: Email)
timelineActors.foreach {
case User(name, Female, Email(_, “soundcloud.com”) =>
println(“mulher trabalhando na soundcloud”)
case User(name, Male, Email(_, “soundcloud.com”) =>
println(“homem trabalhando na soundcloud”)
case User(name, gender, Email(_, “qconrio.com.br”) =>
println(“organizador da qconrio”)
case _ =>
println(“pessoa desconhecida”)
}
Nem tudo são flores...
Código denso
def flatMap[B, That]
(f: (A) ⇒ Traversable[B])
(implicit bf: CanBuildFrom[
List[A], B, That]): That
Código denso
def flatMap[B, That]
(f: (A) ⇒ Traversable[B])
(implicit bf: CanBuildFrom[
List[A], B, That]): That
listOfThings.flatMap(_.toUpperCase)
XML também é código?
<fruits>
<fruit type="banana" origin="brazil"/>
<fruit type="apple"/>
<fruit type="orange" origin="usa"/>
<fruit type="orange" origin="brazil"/>
</fruits> \\ "fruit"
filter { _ \\ "@origin"
exists (_.text == "brazil") }
Mas e o Stream...?
Mas e o Stream...?
Cassandra
API
MySQL
Mas e o Stream...?
Tracks
Playlists
Service
Multiple
Service
Services
MySQL
API
Timeline
Service
Redis
Mas e o Stream...?
~150 ms
Tracks
Playlists
Service
Multiple
Service
Services
MySQL
API
Timeline
Service
Redis
Mas só o Stream...?
Data team
Outros serviços em
Scala
Ferramental jvmkit
Stranglers
Stranglers
Stranglers
Novo
stream
Cache
O presente
Em resumo...
Produtivo como Ruby, typesafe
como Java*
Move faster
break fewer things
O futuro
O futuro
Padrões de código
Bibliotecas mais estáveis
Facilidade de inovação
"One Scala"
Perguntas?

Documentos relacionados

Untitled

Untitled Branco Supremo

Leia mais