Escalabilidade e performance – Filas

Introdução

Nos posts anteriores sobre este assunto, umas das técnicas sugeridas era, quando possível, usar técnicas assíncronas, onde foi abordado superficialmente a utilização de filas. Vamos entrar um pouco mais fundo nesse tema, e exemplificá-lo na medida do possível, inicialmente revisando na íntegra o tópico sobre filas e técnicas assíncronas.

Utilização de técnicas assíncronas

Filas podem ser criadas por bons motivos: seja para manter a consistência de dados (ex.: filas de contenção devido à locks), ou para diminuir o risco do uso indiscriminado de recursos.O uso de técnicas assíncronas, quando permitido pelas regras de negócio, traz algumas oportunidades de otimização no uso de recursos. Com o enfileiramento de mensagens em sistemas de filas (Message Queues) , podemos alocar recursos limitados e suficientes para o tratamento das mensagens. Com isto, poderemos consumir aos poucos os elementos da fila sem aumentar os recursos em momentos de pico.

Por exemplo, disponibilizamos 10 threads para tratamento de um tipo de requisição e não estaremos usando mais recursos caso haja um pico de requisições. O tempo médio do tratamento será maior (devido ao tempo de espera), mas estaremos garantindo um limite no uso dos recursos (Princípio 5), além de permitir por exemplo que operações secundárias decorrentes de um processamento de interface, que normalmente precisa ser o mais rápido possível, possam ser realizados após o processamento principal ter sido completo e seu retorno será mais rápido ao cliente ou solicitante do processo enquanto a etapa secundária será processada na fila quando chegar a sua vez.

O que é uma fila ?

Uma fila é uma estrutura de dados, onde os primeiros elementos inseridos nela serão os primeiros a serem removidos. Basicamente uma fila possui apenas as operações de ENQUEUE ( Acrescentar elemento na Fila ) e DEQUEUE ( Remover elemento da Fila ). Uma fila de caixa em um supermercado é um bom exemplo análogo. Você sempre entra no final da fila, um caixa disponível chama o primeiro da fila para ser atendido, ele sai da fila, e o próximo da fila será atendido assim que for chamado, e com a fila andando, em alguns minutos será sua vez.

Filas para etapas complementares de processos

Em determinados casos, e isto é mais comum do que se imagina, um processamento pode gerar demanda de processamentos secundários. Por exemplo, uma rotina de finalização de pedido por telefone, onde a confirmação do pedido deve disparar um ou mais e-mails para outros departamentos. Colocar a rotina de envio de e-mail no final da gravação do pedido pode segurar o sistema quando o servidor SMTP para envio de e-mails esteja carregado ou mesmo indisponível. O envio de e-mail é uma parte importante do processo, mas não necessariamente eu precise fazê-lo neste instance, segurando um processo de interface.

Neste caso, o mais elegante a fazer é criar uma fila para envio de e-mails, onde um ou mais processos dedicados (e especialistas) é colocado no ar em um ou mais serviços, para garantir o envio dos e-mails da fila, e várias partes do programa responsáveis por enviar e-mail podem ser clientes desta fila, bastando acrescentar a requisição na fila, sem aguardar o envio do e-mail para a rotina estar disponível para uma nova inclusão de pedido.

Fila para limitar consumo de recursos

Pegando carona no exexmplo acima, a fila serve também para não sobrecarregar o servidor de e-mails. Você decide quantos processos dedicados serão colocados no ar para enviar e-mails, e ainda pode especializar estes processos, para que caso um servidor não esteja disponível, o processo tente a conexão com outros servidores de SMTP para envio dos e-mais pendentes.

Mesmo que todos os operadores do sistema disparem ao mesmo tempo uma requisição para enviar e-mail, , todas entam na fila muito rápido, e somente um numero fixo de processos dedicados será responsável para processar a fila, sem sobrecarregar o servidor de e-mail.

Manutenção das filas

Para que a fila seja eficiente e segura, alguns procedimentos adicionais são necessários. Por exemplo, caso não exista nenhum processo removendo itens da fila, a fila pode crescer indiscriminadamente. Um processo em fila deve ser capaz de saber quanto tempo ele ficou esperando, isto é relativamente fácil de implementar, e você pode emitir um alerta ou registrar uma advertência caso os processos estejam ficando mais que um tempo determinado em fila, isto pode indicar um aumento de carga do sistema, e apontar uma necessidade de escalar melhor o recurso de processamento utilizado.

A fila deve ser preferencialmente transacionada, isto é, um item pode ser removido da fila somente se seu processamento foi feito com sucesso. Ou, para ela não necessariamente ser transacionada, pode ser criada uma fila auxiliar de processos em andamento, onde o elemento sai da fila de pendências e entra na fila de processos em andamento, saindo na hora da fila principal, e ficará na fila de processos em andamento até o processo ser concluído com sucesso. Neste caso, a fila de processos em andamento deve ser monitorada de tempos em tempos … se tem um processo que entrou e não saiu, algo não saiu como o planejado.

Com filas, você consegue até mesmo parar o sistema e fazer uma manutenção, e quando o sistema for colocado no ar novamente, o que ainda não foi processado em uma fila pode ser retomado do ponto onde parou.

Conclusão

Uma forma muito prática de lidar com filas é criar uma funcionalidade para encapsular a criação e manutenção das filas, e usá-la no sistema onde a mesma for necessária ou útil. O ponto importante so processamento assíncrono é saber se, onde e por quê algum elemento da fila não foi processado. Se você nao projetar a fila e seus mecanismos para ter algum tipo de rastreabilidade, se algo não sair como o esperado, você vai correr em círculos e não vai saber o que aconteceu.

Até o próximo post, pessoal 😉

Referências

ESTRUTURA DE DADOS. In: WIKIPÉDIA, a enciclopédia livre. Flórida: Wikimedia Foundation, 2014. Disponível em: <http://pt.wikipedia.org/w/index.php?title=Estrutura_de_dados&oldid=40608431>. Acesso em: 14 dez. 2014.

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s