40
Princípios de Concorrência em Ruby Renan Ranelli (Milhouse)

Princípios de Concorrência em Ruby e Além

  • Upload
    locaweb

  • View
    55

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Princípios de Concorrência em Ruby e Além

Princípios de Concorrência em Ruby

Renan Ranelli (Milhouse)

Page 2: Princípios de Concorrência em Ruby e Além

Agenda

➢ O que é concorrência ?➢ Pra quê escrever código concorrente ?➢ (Breve) Explicação dos diferentes modelos de concorrência➢ Por que escrever código concorrente é dificil ?➢ O que é o tão odiado GIL➢ Abstrações úteis que facilitam sua vida multithreaded➢ Exemplo de como usamos isso tudo em uma app real &

lições aprendidas

Page 3: Princípios de Concorrência em Ruby e Além

O que é concorrência?

➢Concorrência, assincronia e paralelismo são coisas relacionadas mas que muita gente as confunde.

➢ “Concurrency is when two tasks can start, run, and complete in overlapping time periods. It doesn’t necessarily mean they’ll ever both be running at the same instant. E.g. Multitasking in a single core machine”

➢ “Parallelism is when tasks literally run at the same time, e.g. on a multicore processor or SIMD instructions”

- Sun’s Multithreaded programming guide

Page 4: Princípios de Concorrência em Ruby e Além

O que é concorrência?

➢ Assincronia significa que o resultado de uma computação não esta disponível imediatamente após a avaliação.

➢ Significa que a maquina pode fazer outras coisas enquanto espera essa computação terminar e eventualmente no futuro fazer uso do resultado da mesma

Page 5: Princípios de Concorrência em Ruby e Além

Pra quê escrever código concorrente

➢ Concorrência possibilita assincronia e paralelismo➢ Libera o CPU para fazer outras coisas enquanto

espera por IO (http, banco, rede, disco, etc.) oferece mais performance. E.g. você poderá servir os requests de 30 usuários ao mesmo tempo ao invés de 1.

Page 6: Princípios de Concorrência em Ruby e Além

Diferentes modelos de concorrência

➢ Multiprocesses (resque, unicorn)➢ Multithreading (sidekiq)➢ Fibers (Ruby tem fibers!)➢ Corroutines ➢ Actors (Celluloid)➢ Outras bruxarias que eu não manjo(process calculi)

Page 7: Princípios de Concorrência em Ruby e Além

Multithreading

➢ Threads, assim como processos, são coisas oferecidas pelo SO.

➢ Mutexes ~➢ Deadlocks ~➢ Thread#join ~➢ Comportamento diferente com exceptions (e.g.

streaming do log no package-installer)

Page 8: Princípios de Concorrência em Ruby e Além

Multithreading

Page 9: Princípios de Concorrência em Ruby e Além

Multithreading

Page 10: Princípios de Concorrência em Ruby e Além

Pausa para o GIL

Page 11: Princípios de Concorrência em Ruby e Além

Pausa para o GIL

Page 12: Princípios de Concorrência em Ruby e Além

Pausa para o GIL

➢ O GIL (Global Interpreter Lock) impede que código ruby rode em paralelo.

➢ A unica ocasião em que é seguro para o GIL deixar coisas acontecerem em paralelo é com IO.

➢ Se sua vida é IO-bound, isso é o que importa.

Page 13: Princípios de Concorrência em Ruby e Além

Pausa para o GIL

Page 14: Princípios de Concorrência em Ruby e Além

Pausa para o GIL

Page 15: Princípios de Concorrência em Ruby e Além

Pausa para o GIL

Page 16: Princípios de Concorrência em Ruby e Além

Multithreading

➢ Considere que os jobs no sidekiq são unicos

Tem algum ruim nessa implementação ??➢

Page 17: Princípios de Concorrência em Ruby e Além

Multithreading – Evite Thread.new

➢ É uma boa idéia não usar threads diretamente.

➢ Existem várias abstrações melhores e mais seguras para expressar a task que você tem em mãos.

➢ Uma referência excelente é a lib do java java.util.concurrent. No mundo Ruby existe a gem concurrent-ruby que implementa parte do java.util.concurrent.

Page 18: Princípios de Concorrência em Ruby e Além

Multithreading – Abstrações

➢Abstrações úteis (todas disponíveis no concurrent-ruby):➢ IVars➢ Futures➢ Promises➢ Thread Pools➢ Channels➢ Software Transactional Memory (STM)➢ Agents

Page 19: Princípios de Concorrência em Ruby e Além

Multithreading – Abstrações

➢ IVars

Page 20: Princípios de Concorrência em Ruby e Além

Multithreading – Abstrações

➢ Futures

Feature:

As a highly responsive Ruby application

I want long-running tasks on a separate thread

So I can perform other tasks without waiting

Page 21: Princípios de Concorrência em Ruby e Além

Multithreading – Abstrações

➢ Futures

Page 22: Princípios de Concorrência em Ruby e Além

Multithreading – Abstrações

➢ Implementação porca

Page 23: Princípios de Concorrência em Ruby e Além

Multithreading – Abstrações

➢ Promises➢ Tipo Futures (só que Monads ;D)

➢ Pros Haskellistas: (then) = >==

Page 24: Princípios de Concorrência em Ruby e Além

Multithreading – Abstrações

➢Thread pools➢ Worke-horse dos executors.

Page 25: Princípios de Concorrência em Ruby e Além

Multithreading – Abstrações

Page 26: Princípios de Concorrência em Ruby e Além

Caso de uso - Hodor

Page 27: Princípios de Concorrência em Ruby e Além

Caso de uso - Hodor

Novo sistema

Old database

Page 28: Princípios de Concorrência em Ruby e Além

Caso de uso - Hodor

Page 29: Princípios de Concorrência em Ruby e Além

Caso de uso - Hodor

Page 30: Princípios de Concorrência em Ruby e Além

Caso de uso - Hodor

Page 31: Princípios de Concorrência em Ruby e Além

Caso de uso - Hodor

➢ Dahora! Tudo funcionava....

➢ Mas ai resolvemos medir:

Tempo atualizando status dos eventos na “fila”

Tempo fazendo o processamento dos eventos

Page 32: Princípios de Concorrência em Ruby e Além

Pareceu Fácil né ???

Page 33: Princípios de Concorrência em Ruby e Além
Page 34: Princípios de Concorrência em Ruby e Além

Foi nada.

Page 35: Princípios de Concorrência em Ruby e Além

Lições aprendidas

➢ PELO AMOR DE DEUS NÃO USA `Timeout::timeout` !!1!!1!!um!!onze!

Page 36: Princípios de Concorrência em Ruby e Além

Lições aprendidas

➢ Cuidado com o connection pool do ActiveRecord (Principalmente se for Rails < 4)

Page 37: Princípios de Concorrência em Ruby e Além

Lições aprendidas

➢ Por favor, atualizem as versões dos drivers de banco. TinyTds ~ 0.5 tinha zilhares de issues relacionadas a multi-threading.

Page 38: Princípios de Concorrência em Ruby e Além

Lições aprendidas

➢ Metricas são muito mais legais que logs

➢ http://webleela.service.ita.consul.locaweb.com.br/index.html#/dashboard/db/heisenberghodor

Page 39: Princípios de Concorrência em Ruby e Além

Lições aprendidas

➢ Converse (e ajude!) com a galera que desenvolve as gems

Page 40: Princípios de Concorrência em Ruby e Além

➢Figura pare pense ?➢

➢Para evitar problemas como o da foto do mimi triste:➢ 1. Não use concorrência➢ 2. Se for usar, não compartilhe nada. Não decida usar

antes de MEDIR e ter certeza que você realmente precisa.

➢ 3. Se tiver que compartilhar, tomar muito cuidado pra sincronizar o acesso