Pontos Principais
- Na comunidade Flink, todas as fontes de dados são consideradas por natureza como ilimitadas, e as fontes de dados limitadas são uma conjunto de dados ilimitados.
- A utilização de uma solução de processamento de fluxo é mais adequado para aqueles processamentos de dados que mudam mais rapidamente, usando um conceito lógico que de alguma forma permanece sem alteração. Por outro lado, o processamento em lote é útil para executar dados inalterados que utilizam consultas de bancos de dados e lógica.
- No Flink, há uma relação entre latência e integridade. Com o processamento de fluxo de dados, os desenvolvedores consideram os parâmetros de ajuste entre os primeiros resultados e a integridade da processamento, enquanto em um processamento batch não é necessário porque todos os dados estão disponíveis no início do processamento.
- A estrutura atual da API do Flink inclui a API DataSet (para processamento batch), a API DataStream (para processamento em tempo real) e a API/SQL da tabela para programação declarativa.
- A estrutura incorpora alterações nas APIs, como descontinuar uma API DataSet e aprimorar a API DataStream para incluir totalmente aqueles casos de uso no estilo de processamento batch.
Processamento Batch e Streaming: Dois lados da mesma moeda
Desde o início, o Apache Flink seguiu a filosofia de adotar uma abordagem unificada tanto para processamento em batch como streaming. O principal componente é o "processamento contínuo ilimitado de data streams, em batch como um conjunto limitado e especial desses streams".
A filosofia de "streaming primeiro, com batch sendo um caso especial de streaming" é suportada por uma série de projetos (por exemplo, Flink, Beam, etc.) e tem sido frequentemente citado como uma poderosa maneira de construir aplicações que unificam o processamento de dados em batch e streaming ajudando a reduzir bastante a complexidade das infra-estruturas de dados.
Com a recente doação do Blink - um fork interno do Apache Flink do Alibaba - para a comunidade, os colaboradores e contribuidores do Flink trabalham para tornar essa filosofia "streaming primeiro, com batch sendo um caso especial de streaming" uma realidade no Flink 2.0.
Antes de mergulhar nos detalhes de como as APIs existentes no Apache Flink podem mudar para acomodar a unificação de cargas de trabalho em batch e streaming, vale a pena observar alguns requisitos que afetarão a aparência do design do sistema à medida que avançamos para a próxima etapa evolutiva do Apache Flink.
Na comunidade Flink, todas as fontes de dados são naturalmente consideradas ilimitadas, e as fontes de dados limitadas são o que é obtido de uma pequena fatia desses dados ilimitados.
Isso significa que os streams se tornam a base natural primitiva das fontes, enquanto a delimitação é uma propriedade adicional potencial delas. Seguindo esse paradigma, podemos cobrir perfeitamente ambas as cargas de trabalho em batch tradicionais e as cargas de trabalho de streaming com uma abstração. A figura a seguir fornece uma boa descrição visual desse modelo.
Por mais simples que essa idéia possa ser, você pode se perguntar por que temos sistemas de processamento em batch e streaming - incluindo o Flink, com suas APIs DataSet e DataStream - vivemos em um mundo complexo onde os requisitos são muito diferentes quando se trata de processamento de dados. Mais especificamente, entre batch e streaming, há uma diferença relacionada ao que muda mais rapidamente: os dados ou o programa. Para casos de uso no de processamento de streaming (como pipelines de dados, detecção de anomalias, avaliação de ML ou aplicações contínuas), precisamos processar dados muito mais rapidamente e produzir resultados em tempo real, ao mesmo tempo em que a lógica da aplicação permanece relativamente inalterada ou bastante duradoura. Por outro lado, para a maioria dos casos de uso de processamento em batch, como exploração de dados, treinamento de ML e ajuste de parâmetros, os dados tem uma mudança relativamente lenta em comparação com as consultas e a lógica que mudam de forma rápida.
Em outras palavras, há uma troca entre latência e integridade. Nos casos de uso de processamento de streaming, os dados vêm continuamente do fluxo infinito de eventos enquanto usamos temporizadores e marcas d'água para ajustar o processamento entre resultados iniciais (mas possivelmente incorretos) e de integridade. Nos casos de uso de processamento em batch, no entanto, temos todos os dados de entrada no início do cálculo e não precisamos usar temporizadores ou marcas d'água para ajustar as características de saída. Sempre podemos produzir um resultado completo e correto.
Essa diferença de requisitos é refletida nos diferentes estilos de execução ilustrados na figura a seguir. À direita, os cenários de processamento de streaming têm um gráfico de processamento "sempre ativo" (fontes, funções definidas pelo usuário, sinks, etc.), com todas as peças funcionando continuamente e ao mesmo tempo. À esquerda, para cenários de processamento batch, o gráfico de processamento entra em estágios de longos processamentos, permitindo uma melhor alocação de recursos em um determinado estágio. Por exemplo, o Flink pode ter fontes específicas executando com paralelismo de que elas precisam para ler dados, que são encerrados à medida que os estágios posteriores de computação fiquem online, levando a uma melhor alocação destes recursos.
Observando a estrutura atual da API do Flink
Agora que foi explicado as diferenças nos requisitos e no potencial de otimização entre batch e streaming, vamos observar mais de perto a estrutura atual da API do Flink e sua direção futura, à medida que avançamos em direção a uma estrutura unificada de processamento de dados.
Conforme ilustrado na figura abaixo, o conjunto de APIs existentes do Flink consiste de um Runtime como a abstração de nível mais baixo do sistema responsável pela implantação de jobs e execução de tasks em máquinas distribuídas. Fornecendo tolerância a falhas e interconexão de rede entre as diferentes tarefas no JobGraph. Com relação ao tempo de execução do Flink, existem duas APIs separadas, as APIs de DataSet e de DataStream. A DataSet API possui sua própria representação DAG (gráfico acíclico direcionado) para vincular os operadores de um job, bem como implementações de operadores para diferentes tipos de funções definidas pelo usuário. A API DataStream possui uma representação DAG diferente, além de seu próprio conjunto de implementações de operadores. Ambos os tipos de operadores são implementados em um conjunto separado de tasks, que são fornecidas ao Runtime para execução. Por fim, temos a Table API / SQL que oferece suporte à programação declarativa e vem com sua própria representação de operadores lógicos e com dois caminhos de conversão diferentes para converter os programas da Table API na API DataSet ou DataStream, dependendo do caso de uso e/ou o tipo de fontes que o programa acompanha.
Observando os programas existentes do ponto de vista do design do sistema, limpeza do código e desenvolvimento, observamos algumas áreas de melhoria:
- A representação gráfica é separada para cada API, resultando em uma duplicação de código;
- Existem vários componentes de conversão entre os diferentes gráficos, o que também resulta em duplicação de código;
- As implementações do operador são separadas e incompatíveis, resultando em implementações duplicadas do operador que são executadas em diferentes implementações de tasks de baixo nível;
- A Table API é convertida em duas APIs distintas de nível inferior, resultando em várias pilhas de conversão;
- As diferentes APIs atualmente têm conectores separados, resultando em duplicação do trabalho de manutenção e implementações diferentes para cada API. (Por exemplo, a API DataStream possui um conector Kafka, enquanto o mesmo não existe para a API DataSet. A API DataSet possui um conector HBase que está ausente na API DataStream.
O futuro das APIs do Flink para uma framework unificado de processamento em batch e streaming
Uma vez que o Apache Flink visualiza "Batch como um caso especial de Streaming", o tema geral do roadmap do Flink está evoluindo para aprimorar a API DataStream para que possa substituir totalmente os casos de uso de processamento em batch. Quando isso for alcançado, a DataSet API poderá ser depreciada. Abaixo, são descritos algumas idéias que a comunidade já está discutindo e as propostas de melhoria ativas e estórias que já estão sendo trabalhadas.
Introdução de BoundedStream na DataStream API
Um dos aprimoramentos da DataStream API inclui a introdução de BoundedStreams, um conceito que permitirá que a DataStream API aproveite ao máximo o potencial de otimização e a semântica da DataSet API - ou seja, excluindo temporizadores e marcas d'água de tempo de processamento de quaisquer cargas de trabalho batch e usando a execução em etapas, quando possível, para uma melhor alocação de recursos.
Uma nova interface de fonte unificada
Outro passo importante é a introdução de uma interface de origem unificada que inclui a interface de origem de streaming atual (SourceFunction) e a interface de lote (InputFormat). Este trabalho está registrado como FLIP 27.
Aprimoramentos na representação gráfica da DataStream API
A representação gráfica da API será aprimorada para oferecer suporte a informações adicionais sobre limites. Além disso, componentes como traduções, agendamento e implantação dos operadores, bem como gerenciamento de memória e implementações de rede serão aprimorados para oferecer suporte a execuções em batch, incluindo agendamento combinado para execução eficiente de casos de uso do tipo hash-join.
Aprimoramentos nos tradutores e operadores da DataStream API
A DataStream API será ainda mais otimizada com aprimoramentos para seus operadores e tradutores, tornando a operação de processamento streaming como sendo a padrão do Flink. Enquanto isso, as execuções batch simplesmente exibirão regras de otimização adicionais que permitem a paridade de recursos na sua estrutura. Por exemplo, para processar gráficos que incorporam fluxos de dados limitados e ilimitados, os StreamOperators podem inicializar o estado de alguns operadores e gerenciar com eficiência os recursos entre os dois fluxos, executando primeiro qualquer parte limitada da carga de trabalho e continuando com os streams ilimitados. A API do operador de streaming será aprimorada ainda mais para oferecer suporte a leitura seletiva e EndOfInputevents para execuções no estilo batch (FLINK 11875).
Aprimoramentos na Table API / SQL
Como a Table API / SQL do Apache Flink já está unificada para cargas de trabalho em batch e streaming, o trabalho de desenvolvimento da comunidade se concentra principalmente em adicionar uma nova implementação de um executor da Table API com base no trabalho realizado no Alibaba (FLINK 11439). Este é um novo runtime da Table API que utiliza os recursos avançados da API de Streaming que foi aprimorada recentemente.
Todas as melhorias mencionadas acima eventualmente orientarão o futuro do framework para se parecer com a figura abaixo.
O runtime do Flink está no centro da framework, juntamente com um aperfeiçoado Stream Transformation DAG. Ambas DataStream API e a Table API / SQL ficam sobre essas mesmas abstrações, a primeira como uma API de aplicação física capaz de lidar com execuções em batch e streaming, e a segunda como uma API mais declarativa que executa SQL para ambos streams de dados limitados e ilimitados.
Fique ligado para obter mais atualizações sobre a jornada do Flink para se tornar um framework unificado de processamento de dados, assinando as listas de email públicas do Apache Flink e seguindo os FLIPs mencionados no artigo.
Sobre o Autor
Aljoscha Krettek é parceiro de PMC no Apache Beam e Apache Flink, onde se concentra predominantemente na Streaming API, bem como no design e implementação de adições às APIs do Flink. Aljoscha é co-fundador e engenheiro de software da Ververica (anteriormente data Artisans). Anteriormente, trabalhou na IBM Alemanha e no IBM Almaden Research Center em San Jose. Aljoscha já apresentou no Hadoop Summit, Strata, Flink Forward, Big Data Madrid e em vários Meetups sobre processamento de stream e Apache Flink. Estudou ciência da computação na TU Berlin.