Os agentes baseados em thread do Clojure podem manipular o desempenho do c10k?

5

Estou escrevendo um serviço no estilo c10k e estou tentando avaliar o desempenho do Clojure. Os agentes do Clojure podem lidar com essa escala de simultaneidade com seus agentes baseados em encadeamentos? Outros sistemas de alto desempenho parecem estar se movendo em direção a async-IO / events / greenlets, embora a um custo de complexidade aparentemente maior.

Suponha que haja 10.000 clientes conectados, enviando mensagens que devem ser anexadas a 1.000 arquivos locais - o serviço Clojure está tentando gravar tantos arquivos paralelamente quanto possível, enquanto não permite que dois pedidos separados manipulem o mesmo single arquivo escrevendo ao mesmo tempo.

Os agentes do Clojure são extremamente elegantes conceitualmente - eles permitiriam que arquivos separados fossem escritos de forma independente e assíncrona, enquanto serialização (no sentido do banco de dados) várias solicitações para gravar no mesmo arquivo.

Meu entendimento é que os agentes funcionam iniciando um thread para cada operação (suponha que estamos ligados a E / S e usando send-off ) - então, neste caso, é correto que ele inicie mais de 1.000 threads? Os sistemas atuais podem lidar com esse número de threads de maneira eficiente? A maioria deles deve ser ligada a E / S e dormir a maior parte do tempo, mas eu presumo que ainda haveria uma penalidade de comutação de contexto que é teoricamente mais alta do que sistemas assíncronos / baseados em eventos (eg Erlang, Go, node.js) .

Se a solução Clojure puder lidar com o desempenho, parece ser a coisa mais elegante para codificar. No entanto, se ele não conseguir lidar com o desempenho, algo como os processos leves de Erlang ou Go podem ser preferíveis, já que eles são projetados para ter dezenas de milhares deles gerados de uma só vez e são apenas um pouco mais complexos para implementar.

Alguém abordou esse problema no Clojure ou comparou com essas outras plataformas? (Obrigado por seus pensamentos!)

    
por elliot42 17.11.2012 / 13:49
fonte

2 respostas

4

Os agentes usam um conjunto de encadeamentos expansíveis em vez de simplesmente iniciar um encadeamento por tarefa. Portanto, o número de encadeamentos ativos será cc próximo ao número de agentes ativos. 1000 threads parece razoável para um computador moderno. você provavelmente precisará aumentar os descritores de arquivos abertos máximos (assumindo o Linux)

    
por 17.11.2012 / 15:03
fonte
1

A partir do próximo Clojure 1.5, você pode usar o ExecutorServices (através de set-agent-send-executor! e set-agent-send-off-executor! ) personalizado.

Fazendo isso, você poderá limitar o número de threads - se necessário, 1k na maior parte dos threads para dormir não parece fora do alcance da JVM. Cuidado com o tamanho da pilha.

    
por 22.11.2012 / 16:11
fonte