Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Segue o Fluxo: Elixir's GenStage e Flow

Segue o Fluxo: Elixir's GenStage e Flow

Avatar for Guilherme de Maio, nirev

Guilherme de Maio, nirev

March 18, 2017
Tweet

More Decks by Guilherme de Maio, nirev

Other Decks in Programming

Transcript

  1. Processamento de Dados Flow e GenStage • Processamento de Logs

    • Indexação de dados para busca • Algoritmos de Recomendação • Dashboards em tempo real • etc…
  2. Ávido • Simples • Tudo em memória • Lento para

    arquivos muito grandes • 0% de concorrência File.read!("path/to/some/file") |> Enum.flat_map(&String.split(&1, " ")) |> Enum.reduce(%{}, fn word, acc -> Map.update(acc, word, 1, & &1 + 1) end) |> Enum.to_list()
  3. Preguiçoso • Melhor, um de cada vez • Menos uso

    de memória • Ainda lento para arquivos muito grandes • 0% de concorrência File.stream!("path/to/some/file") |> Stream.flat_map(&String.split(&1, " ")) |> Enum.reduce(%{}, fn word, acc -> Map.update(acc, word, 1, & &1 + 1) end) |> Enum.to_list()
  4. Concorrente File.stream!("path/to/some/file") |> Flow.from_enumerable() |> Flow.flat_map(&String.split(&1, " ")) |> Flow.partition()

    |> Flow.reduce(fn -> %{} end, fn word, acc -> Map.update(acc, word, 1, & &1 + 1) end) |> Enum.to_list()
  5. Concorrente • Agora, sim! Multi-processos • Perde noção de ordem

    File.stream!("path/to/some/file") |> Flow.from_enumerable() |> Flow.flat_map(&String.split(&1, " ")) |> Flow.partition() |> Flow.reduce(fn -> %{} end, fn word, acc -> Map.update(acc, word, 1, & &1 + 1) end) |> Enum.to_list()
  6. Concorrente • Agora, sim! Multi-processos • Perde noção de ordem

    File.stream!("path/to/some/file") |> Flow.from_enumerable() |> Flow.flat_map(&String.split(&1, " ")) |> Flow.partition() |> Flow.reduce(fn -> %{} end, fn word, acc -> Map.update(acc, word, 1, & &1 + 1) end) |> Enum.to_list()
  7. Flow • Um meio de expressar processamento em cima de

    coleções (tipo Enum e Stream), mas feitas em paralelo com GenStage • Funciona com dados finitos e não-finitos • Inspirado no Apache Spark
  8. GenStage • É um behaviour • Feito para trocar dados

    entre “estágios” • de forma transparente • e com back-pressure
  9. GenStage • O Consumidor se subscreve ao Produtor • Quem

    dita a velocidade é o Consumidor • Produtor pode enviar à vários Consumidores • Diferentes políticas para despacho aos Consumidores
  10. GenStage Producer Consumer Pede X Recebe no máximo X max_demand:

    máximo de itens que o consumidor pede min_demand: mínimo de itens, quando atingir esse número pede mais
  11. Distribuído • Não tem ainda • Faltam mecanismos de garantias

    no Flow • Precisa mesmo distribuir? • Mais informações em breve…
  12. Conclusão • Pipelines de dados como “cidadãos" do Elixir •

    API muito familiar pra quem já usou outros frameworks • Bastante promissor • Não tem garantias ainda: 
 ou seja, não usar para processar pagamento ;D
  13. Referências • https://hexdocs.pm/gen_stage • https://hexdocs.pm/flow • https://www.youtube.com/watch?v=aZuY5-2lwW4 • https://www.youtube.com/watch?v=IBcLOxW1Zgs •

    http://teamon.eu/2016/tuning-elixir-genstage-flow-pipeline-processing/ • https://blog.discordapp.com/how-discord-handles-push-request-bursts-of-over-a-million-per- minute-with-elixirs-genstage-8f899f0221b4 Documentação e Palestras Relatos de Uso