Multiprocessamento Python com Fila vs ZeroMQ IPC

10

Estou ocupado escrevendo um aplicativo Python usando o ZeroMQ e implementando uma variação do padrão Majordomo, conforme descrito no ZGuide .

Eu tenho um corretor como intermediário entre um conjunto de trabalhadores e clientes. Desejo fazer um registro extensivo para cada solicitação recebida, mas não quero que o corretor perca tempo fazendo isso. O intermediário deve passar essa solicitação de log para outra coisa.

Eu pensei em duas maneiras: -

  1. Crie trabalhadores que são apenas para log e use o transporte ZeroMQ IPC
  2. Usar multiprocessamento com uma fila

Não tenho certeza de qual é o melhor ou o mais rápido para esse assunto. A primeira opção permite que eu use as classes base de trabalhadores atuais que eu já uso para trabalhadores normais, mas a segunda opção parece mais rápida de implementar.

Gostaria de alguns conselhos ou comentários sobre o acima exposto ou possivelmente uma solução diferente.

Imraan
fonte

Respostas:

4

Eu gosto da abordagem de usar ferramentas padrão, como o que Jonathan propôs. Você não mencionou em qual SO está trabalhando, mas outra alternativa que segue o mesmo espírito pode ser usar o módulo de log padrão do Python junto com logging.handlers.SysLogHandlere enviar as mensagens de log para o serviço rsyslog (disponível em qualquer linux / unix, mas eu acho que também existe uma opção do Windows , mas nunca a usei).

Essencialmente, todo esse sistema implementa a mesma coisa que você está pensando. Seu processo local enfileira a mensagem de log para ser tratada / processada / gravada por outra pessoa. Nesse caso, o alguém ( rsyslog) é um serviço bem conhecido e comprovado que possui muita funcionalidade e flexibilidade internas.

Outra vantagem dessa abordagem é que seu produto se integrará muito melhor a outras ferramentas sysadmin criadas sobre o syslog. E nem seria necessário que você escrevesse qualquer código para obter essa opção.

DXM
fonte
1
+1 para uma sugestão que evita reinventar a roda. Eu não me importaria de herdar um sistema projetado dessa maneira. Ele faz o trabalho bem, mas oferece muitos graus de liberdade para futuras modificações.
Evadeflow
2

Você pode considerar uma terceira possibilidade para implementar o log remoto. Se você usar o módulo de log Python padrão, poderá considerar o uso da logging.QueueHandlerclasse em seus trabalhadores, clientes e broker e a logging.QueueListenerclasse em seu processo de log remoto.

Em vez de usar o Python normal multiprocessing.Queuecomo o transporte entre os processos de seu aplicativo e o processo de log, implemente sua própria Queueclasse de substituição usando o ZeroMQ com digitação de pato para que sua classe seja um substituto para o Python padrão Queue. Dessa maneira, seu aplicativo poderá ser executado inalterado em qualquer ambiente, a partir de um único computador com vários núcleos, por meio de data centers distribuídos.

Para resumir, use um logger padrão do Python com a QueueHandlerem todos os seus funcionários, clientes e corretores e crie um processo independente com base no (s) manipulador (es) QueueListenerPython loggingde sua escolha para lidar com o trabalho pesado do log.

Jonathan
fonte
Estou usando o Python 2.7. Acredito que a classe QueueHandler esteja disponível apenas no Python 3.2.
Imraan
Seria muito fácil pegar o código do Python 3 e usá-lo diretamente como parte do seu aplicativo.
11133 Jonathan
Vou tentar isso e que você saiba se ele funciona
Imraan
0

Essas são abordagens radicalmente diferentes, cada uma com seus próprios conjuntos de prós e contras, que você provavelmente verá em uma fase posterior do desenvolvimento:

Eu pensei em duas maneiras: -

  1. Crie trabalhadores que são apenas para log e use o transporte ZeroMQ IPC
  2. Usar multiprocessamento com uma fila

Uma maneira de tentar tentar é ter um trabalhador de log adicional, como na abordagem 1. Você pode permitir que seus trabalhadores façam logon em um cluster de log do memcache, e o trabalhador de log monitora a carga atual de recursos e, ao decedir um determinado parâmetro de carga de recursos, o trabalhador registra em um dispositivo limitado de IOPs (por exemplo, disco rígido).

Também gosto da abordagem de Jonathan com a ressalva de que eu também uso principalmente o Python 2.x e que você provavelmente precisará configurar seu próprio back-end de log para realmente forçar o desempenho.

Corrija-me se eu estiver errado, mas minha opinião é que você está realizando alguma tarefa com muitos dados, com as IOPs de armazenamento sendo seu gargalo.

Uma maneira conveniente ainda seria permitir que o broker faça o brokeragelog - no formato descrito - com todas as desvantagens de uma instância central do broker. Por exemplo, se o broker estiver em uma demanda tão alta que nunca tenha espaço para gravar os logs do cache de memórias de volta ao armazenamento, você precisará adotar outra abordagem.

Você pode acabar tendo um modelo sem corretor. Isso é com os trabalhadores gerenciando seu trabalho entre si. Em um exemplo simples, por meio de um algoritmo de round-robin distribuído .

Lorenz Lo Sauer
fonte