Segue o Fluxo: Elixir's GenStage e Flow

Segue o Fluxo: Elixir's GenStage e Flow

4b178f929b750c873b4d2b0c0a682051?s=128

Guilherme de Maio, nirev

March 18, 2017
Tweet

Transcript

  1. @nirev Guilherme Nogueira Segue o
 Fluxo Elixir's GenStage e Flow

  2. Por quê? Flow e GenStage

  3. Processamento de Dados Flow e GenStage

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

    • Indexação de dados para busca • Algoritmos de Recomendação • Dashboards em tempo real • etc…
  5. Processamento de Dados 1.ávido 2.preguiçoso 3.??? 4.PROFIT

  6. Processamento de Dados 1.ávido 2.preguiçoso 3.concorrente 4.distribuído

  7. Ávido (Eager)

  8. Ávido 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()
  9. Á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()
  10. Preguiçoso (Lazy)

  11. Preguiçoso 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()
  12. 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()
  13. Concorrente

  14. 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()
  15. 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()
  16. 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()
  17. Flow

  18. 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
  19. GenStage

  20. GenStage • É um behaviour • Feito para trocar dados

    entre “estágios” • de forma transparente • e com back-pressure
  21. GenStage Producer/ Consumer Producer Producer/ Consumer Consumer

  22. 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
  23. GenStage Producer Consumer Pede X Recebe no máximo X

  24. 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
  25. GenStage Producer 1 2,4 3 Despacho 1,2,3,4 DemandDispatcher

  26. GenStage Producer 1,2 1,2 1,2 Despacho 1,2 BroadcastDispatcher

  27. GenStage Producer 1,4 2,5 3,6 Despacho 1,2,3,4,5,6 PartitionDispatcher rem(e,3)

  28. GenStage Exemplo (https://github.com/nirev/gen_stage_example)

  29. Distribuído

  30. Distribuído • Não tem ainda • Faltam mecanismos de garantias

    no Flow • Precisa mesmo distribuir? • Mais informações em breve…
  31. Conclusão

  32. 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
  33. Thanks! https://xerpa.recruiterbox.com/ Estamos contratando! @nirev Guilherme Nogueira

  34. 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