Apache, processos, threads e django

Muitas vezes apenas adotamos os padrões e não nos questionamos porque eles foram escolhidos, então resolvi fazer uma breve pesquisa sobre threads e processos no Apache

Antes de mais nada, é importante falar um pouco sobre processos e threads. Os processos são independentes e têm seus próprios endereços de memória, os threads pertencem a um processo e compartilham o mesmo endereço de memória e recursos.

Tudo começa no webserver, vou falar do Apache. Existem dois sabores que se diferenciam em como será feito o processamento de múltiplas requisições: prefork e worker.

O prefork tem um processo de controle para outros sub-processos que irão receber e responder às requisições. Aqui não são utilizados threads, uma requisição é repassada para o primeiro sub-processo livre e este, por sua vez, só atenderá a uma requisição por vez.

O worker também tem um processo de controle para outros sub-processos, a diferença é que cada sub-processo cria um thread de escuta que fará o repasse de requisições para outros threads. Isto faz com que o uso de memória normalmente seja menor, pois os threads compartilham os mesmos recursos.

Em ambos os modelos é possível regular o mínimo ou máximo de processos e threads, o Apache se encarrega de reciclar os processos dentro destes limites. O ideal é que o servidor esteja configurado para aguentar o número esperado de requisições mas evitando consumir toda a RAM disponível, o que resultaria em uso da SWAP em disco e uma cascata de problemas.

Segundo a documentação, o prefork é indicado para evitar threading em aplicações que utilizam bibliotecas non-thread-safe, ou seja, evitar que ações em threads diferentes de um mesmo processo possam influenciar outro thread. Como o worker mantém um conjunto de threads em um mesmo processo, compartilhando recursos, bibliotecas mal preparadas podem causar resultados inesperados.

Em geral, o Django é tido como thread-safe, houve uma discussão sobre isso mas acredito que muitos dos problemas da época já tenham sido resolvidos. Ainda não fiz a experiência, mas este post do Armin Ronacher compara o sistema de templates do Django com o Jinja e comenta que algumas templatetags como a cycle não são thread-safe.

Por muito tempo o Django teve o modpython com Apache prefork como deploy recomendado, agora a recomendação oficial é para se utilizar o modwsgi* mas não cobre qual modelo de webserver é mais adequado.

* Curiosidade: conversando com o Jacob na Python Brasil aprendi que se pronuncia “mód uísgui”, mais fácil não?🙂

Aqui vão mais alguns links interessantes:

Sobre Rico
Software engineer

2 Responses to Apache, processos, threads e django

  1. Henrique disse:

    Tradicionalmente e dito que fork consome mais memória, pois cada processo tem sua propria copia de contexto, enquanto a thread compartilha.

    No entanto, o fork no Linux (na verdade uma syscall propria, clone()) é implementado com Copy-on-Write, o que a torna basicamente o mesmo que uma thread, o unico overhead imposto e a copia na tabela de processos em execucao.

    Vale muito mais a pena usar servidores que respondem com fork do que com threads, considerando a quantidade de problemas que voce pode ter na sua aplicacao quando executando sob threads.

  2. Rico disse:

    Legal Henrique, isso só reforça a escolha pelo prefork.

    Se for assim, não restam muitos motivos para se usar o worker não é?
    A não ser que você tenha certeza de que sua aplicação é thread-safe e não quer pagar pelo overhead da tabela de processos.

    Abraço.

Deixe uma resposta

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

%d blogueiros gostam disto: