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

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