ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
Configurações de aplicações distribuidas com etcd
1. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 1/53
Configurações de
aplicações distribuidas
com etcd
Wilson Júnior
Software enthusiast, Globo.com
2. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 2/53
Wilson Júnior
Pythonista desde moleque (=
Também é Gopher
Goiano root's
Apaixonado por tecnologia e como ela se apoia nas pessoas
Biker
Desenvolvedor na Globo.com há 3 anos
3. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 3/53
Caracteristicas de uma configuração
Descreve o comportamento
Infrequentemente alterada
Aplicações modificam seu comportamento
4. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 4/53
Imaginemos que possuimos
uma aplicação escalada
horizontamente 100 vezes em
diferentes lugares
5. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 5/53
E cada dessas instancias
recebem uma carga de
transações muito alta
6. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 6/53
Como lidariamos com a
consulta e escrita de
configurações ?
7. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 7/53
Not better approach: variáveis de
ambiente
8. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 8/53
Good to handle
Variáveis de ambientes são rápidas e não requerem nenhum I/O
externo em tempo de consulta
9. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 9/53
Bad to handle
Cordenar 100 restarts para quando houver mudanças
a aplicação deve fazer gracefull restart não sacrificando
nenhuma transação em andamento
10. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 10/53
Not better approach: consultar no
banco de dados
11. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 11/53
Good to handle
os dados sempre estarão frescos pois foram consultados no
momento
não preocupar com um componente para manter
12. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 12/53
Bad to handle
criamos um gargalo.
too many: 304 not modified content.
13. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 13/53
Not better approach: consultar no
banco de dados + sistema de cache
14. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 14/53
Good to handle
o cache garantirá velocidade no acesso.
15. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 15/53
Bad to handle
Inconsistencia temporal
se a aplicação é crítica...
16. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 16/53
Better approach: escolha um banco de
dados especializados em
configurações
17. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 17/53
O que é o etcd
Criado pela core os
Utilizado como storage do kubernetes
Key/value store
Persistente
Cluster Tolerante a falhas
18. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 18/53
O que é o etcd
Consistencia e via algoritmo Raft
MVCC Multiversion concurrency control
15K stars on github
utilizado em outras empresas
19. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 19/53
Protocolo debaixo dos panos
GRPC + HTTP (v3 da API)
Restful + JSON + HTTP (v2 da API)
20. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 20/53
Raft
21. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 21/53
Raft
Um algoritmo de Consensus
Conceito de *Log replicado*
Similar ao paxos
https://raft.github.io/
Necessidade de manter os dados consistentes e tolerante a
falhas
23. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 23/53
Replicated log
24. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 24/53
Exemplo
25. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 25/53
Transações lineares
26. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 26/53
Tradeoff: propagar x consultar
27. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 27/53
Somos treinados/viciados em
pensar no fluxo só de consultar
dados.
28. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 28/53
Quando propagar é melhor
29. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 29/53
Quando propagar é melhor
os dados não são frequentemente alterados
os dados não possuem um grande volume
30. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 30/53
Exemplos
Configurações de rede
Feature flags
Flags de negócio
31. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 31/53
Quando consultar é melhor
32. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 32/53
Quando consultar é melhor
os dados são frequentemente alterados
os dados possuem um grande volume
33. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 33/53
Exemplos
Conteúdo estruturado
Dados de usuários
34. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 34/53
Lets code
35. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 35/53
github.com/coreos/etcd/clientv3
36. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 36/53
Conectando no cluster
cli, err := clientv3.New(clientv3.Config{
Endpoints: []string{"localhost:2379"},
DialTimeout: 5 * time.Second,
})
if err != nil {
log.Fatal(err)
}
defer cli.Close()
37. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 37/53
Simple GET
resp, err := cli.Get(context.Background(), "my-key")
if err != nil {
log.Fatal(err)
}
if len(resp.Kvs) == 0 {
fmt.Println("my-key is not found")
return
}
fmt.Printf("The revision of cluster is: %dn", resp.Header.Re
fmt.Printf("The value of my-key is %sn", resp.Kvs[0].Value)
fmt.Printf("The value was created in revision: %dn", resp.Kv
fmt.Printf("The value was modified in revision: %dn", resp.K
}
38. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 38/53
Simple PUT
resp, err := cli.Put(
context.Background(),
"my-key",
value,
)
if err != nil {
log.Fatal(err)
}
fmt.Printf(
"Set value of my-key to: %sn",
value,
)
fmt.Printf(
"The revision created: %dn",
resp.Header.Revision,
)
}
39. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 39/53
Simple GET with prefix
resp, err := cli.Get(
context.Background(),
"my",
clientv3.WithPrefix(),
)
if err != nil {
log.Fatal(err)
}
for _, kv := range resp.Kvs {
fmt.Printf(
"The value of %s is %sn",
kv.Key,
kv.Value,
)
}
}
40. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 40/53
Simple Watch
watcher := cli.Watch(context.Background(), "my-key")
for resp := range watcher {
for _, ev := range resp.Events {
fmt.Printf(
"operation=%s key=%q value=%q mod_revision=%dn",
ev.Type,
ev.Kv.Key,
ev.Kv.Value,
ev.Kv.ModRevision,
)
}
}
}
41. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 41/53
Simple Watch + Prefix
watcher := cli.Watch(
context.Background(),
"my",
clientv3.WithPrefix(),
)
for resp := range watcher {
for _, ev := range resp.Events {
fmt.Printf(
"operation=%s key=%q value=%q mod_revision=%dn",
ev.Type,
ev.Kv.Key,
ev.Kv.Value,
ev.Kv.ModRevision,
)
}
}
}
42. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 42/53
Simple GET + Watch
resp, err := cli.Get(context.Background(), "my-key")
if err != nil {
log.Fatal(err)
}
if len(resp.Kvs) == 0 {
log.Fatal("my-key is not defined")
}
fmt.Printf("Initial value: %q", resp.Kvs[0].Value)
43. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 43/53
Simple GET + Watch
watcher := cli.Watch(
context.Background(),
"my-key",
clientv3.WithRev(resp.Header.Revision),
)
for resp := range watcher {
for _, ev := range resp.Events {
fmt.Printf("New value: %q", ev.Kv.Value)
}
}
}
44. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 44/53
Simple App
var (
discount atomic.Value
)
func handler(w http.ResponseWriter, r *http.Request) {
price := 50.0
fmt.Fprintf(w, "Temos o produto xn")
switch discount.Load().(string) {
case "blackfriday":
price = price * 0.9
case "pre-blackfriday":
price = price * 1.3
}
fmt.Fprintf(w, "Preço %0.2f", price)
}
46. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 46/53
Simple App
key := "discount"
resp, err := cli.Get(context.Background(), key)
if err != nil {
log.Fatal(err)
}
if len(resp.Kvs) == 0 {
log.Fatalf("%s is not defined", key)
}
discount.Store(string(resp.Kvs[0].Value))
47. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 47/53
Simple App
watcher := cli.Watch(
context.Background(),
key,
clientv3.WithRev(resp.Header.Revision),
)
for resp := range watcher {
for _, ev := range resp.Events {
log.Printf("Discount now is %s", ev.Kv.Value)
discount.Store(string(ev.Kv.Value))
}
}
}
48. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 48/53
Simple App
Let's run and test
49. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 49/53
Código fonte disponível
github.com/wpjunior/etcd-slides
50. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 50/53
Outros projetos semelhantes
Consul
Serf
Zookeeper
51. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 51/53
Estamos contratando
talentos.globo.com
52. 11/14/2017 Configurações de aplicações distribuidas com etcd
http://localhost:3999/index.slide#1 52/53
Thank you
Wilson Júnior
Software enthusiast, Globo.com
wilsonpjunior@gmail.com(mailto:wilsonpjunior@gmail.com)
https://about.me/wpjunior(https://about.me/wpjunior)
@wpjunior(http://twitter.com/wpjunior)