segunda-feira, 7 de fevereiro de 2011

Processamento de fluxo de eventos

Eventos são mensagens que não são explicitamente endereçadas e que sinalizam a ocorrência de alguma mudança de estado em um sistema. Os eventos propriamente ditos podem de uma simples lista de nomes de atributos e valores associados até mesmo um objeto serializado de uma linguagem tipo Java.

Quando os componentes de um sistema se comunicam apenas através da geração e recebimento de eventos, diz-se que o sistema possui uma arquitetura orientada a eventos (EDA – Event Driven Architecture). Como os eventos não são explicitamente endereçados, um sistema orientado a eventos requer um canal de comunicação de eventos. Esse canal funciona da seguinte forma: (a) os componentes geradores de eventos registram no sistema de comunicação os tipos de eventos que serão gerados; (b) por sua vez, os componentes interessados em monitorar eventos de certo tipo, registram o seu interesse em receber eventos daquele tipo; (c) finalmente, quando um evento é de fato gerado, o sistema de comunicação entrega o evento a todos os componentes interessados naquele tipo de evento. Observe que o componente gerador dos eventos não conhece os componentes que receberão o evento. Esse isolamento faz com que sistemas orientados a eventos sejam fracamente acoplados.

Arquitetura orientada a eventos é muito comum em sistemas de monitoramento, pois a adição de mais monitores não influencia o sistema monitorado. Em um sistema de monitoramento, um sistema monitor observa o comportamento de outro sistema, o monitorado. O monitor precisa então observar os eventos gerados pelo sistema monitorado e interpretá-los, de forma a detectar se algo relevante aconteceu no sistema monitorado. Desta forma, é preciso primeiro coletar os eventos que este sistema observado produz e depois processar esses eventos de forma a determinar se eles sinalizam situações de interesse. Um exemplo de situação de interesse é uma queda brusca de preço em uma ação no mercado de ações. Neste caso, o sistema monitorado é o mercado de ações e o sistema monitor pode ser uma aplicação que detecta oportunidades de negócios no mercado de ações. Quando uma situação de interesse é detectada, neste caso, uma oportunidade de negócio, o sistema de monitoramento pode acionar uma atividade de resposta, por exemplo, uma compra de ações cujos preços estão atraentes.

O exemplo acima é conhecido como negociação de alta frequência (High Frequency Trading). Observe que em uma aplicação como o mercado de ações, eventos de compra ou venda acontecem constantemente, milhares de vezes por segundo. O sistema de monitoramento recebe então eventos continuamente. Por essa razão, sistemas de monitoramento baseados em eventos são também conhecidos como sistemas de processamento de fluxos de eventos. Sistemas de processamento de fluxos de eventos (no inglês, ESP – Event Stream Processing) são tipicamente compostos por um grafo de operadores. Cada operador executada parte da tarefa de processar os eventos. Exemplos de operadores são os seguintes:

  • Filtros (descartam ou repassam eventos de acordo com atributos do mesmo);
  • Conversores (aplicam uma função a um evento, gerando um evento de saída que possui, por exemplo, um formato diferente);
  • Agregadores (combinam vários eventos, gerando um evento de saída que agrega informações de todos eles como, por exemplo, a média aritmética).

Observe que alguns dos tipos de operações acima requerem que o operador mantenha algum estado local. Por exemplo, para calcular uma média, é preciso considerar não somente o último evento, mas também os eventos anteriores (normalmente, operações de agregação são feitas considerando uma janela de eventos, por exemplo, os eventos dos últimos 10 minutos). Quando operações não tem estado, é fácil paralelizá-las, basta criar várias cópias do mesmo operador e dividir o fluxo de eventos entre eles. No entanto, quando o operador mantem um estado (no caso da média, uma janela com um determinado número de eventos), as várias cópias do operador precisam coordenar de que forma elas acessam o estado do mesmo.

Infelizmente, coordenar o acesso de várias cópias do operador a um só estado não é fácil. Se travas forem utilizadas, ou a área de código coberta por uma trava é minimizada ou pouco paralelismo será alcançado. No entanto, minimizar a área de cobertura de uma trava é difícil e é uma causa frequente para bugs não determinísticos no código. Além do problema da paralelização correta, aplicações de processamento de eventos têm frequentemente outro requisito, a ordem de processamento dos eventos é importante. Quando um operador é paralelizado com travas, a ordem de processamento dos eventos não é necessariamente a mesma de uma execução sequencial.

Durante meu trabalho de doutorado, investiguei formas de prover paralelização automática que preservam a ordem do fluxo de eventos. O resultado foi um sistema de paralelização especulativa baseado em memórias transacionais em software (STM – Software Transactional Memory). Este sistema processa eventos em paralelo de forma especulativa e monitora os acessos ao estado do operador. Quando o processamento de dois eventos não acessa posições de memória em comum, a execução paralela especulativa funcionou e a ordem foi garantida. Caso contrário, quando há interferências, o processamento do evento que deveria ser processado primeiro é confirmado e o processamento do segundo evento é repetido para considerar as modificações no estado causadas pelo processamento do primeiro. Um exemplo de interferência é quando o processamento dos dois eventos exige o incremento de um mesmo contador, neste caso, se nenhuma abordagem especial (específica para o incremento de variáveis) for utilizada, os eventos precisam ser processados sequencialmente para que o segundo considere o incremento feito durante o processamento do primeiro.

Por fim, investiguei formas de tolerância a falhas em sistemas de processamento de eventos. Como resultado, propus abordagens para a implantação de replicação ativa e passiva que aproveita os mecanismos de especulação providos pelo esquema de paralelização especulativa para reduzir o custo em desempenho da replicação.

Slides: http://www.lsd.ufcg.edu.br/~andrey/ConversaLSD_IntroESP.pdf