Quando NÃO é bom usar atores em akka / erlang?

53

Eu tenho trabalhado com akka por 7-8 meses agora diariamente. Quando comecei, trabalhava em aplicativos e observava que os atores seriam usados basicamente em qualquer lugar dentro do sistema de atores para se comunicar entre a maioria dos objetos. Então eu fiz o mesmo - crie outro ator para x / y / z.

Parece-me que isso pode ser muito indiscriminado, adicionando complexidade onde não é necessário - mas não consigo encontrar nenhuma discussão sobre onde os atores versus lógica síncrona simples ou mesmo assíncrona via futuro devem ser usados. Comecei a ponderar minha postura depois que meu colega de trabalho mencionou algo parecido. Percebi vários casos mais recentemente em que ponderei uma tarefa e depois evitei criar outro ator porque consegui o mesmo resultado com segurança em uma implementação imutável - por exemplo, algo como obter valores de configuração de um banco de dados ou arquivo em algum lugar onde você acessa com pouca frequência e aguarde o resultado ser o caso de uso real.

Em particular, parece-me que em qualquer caso em que você está jogando com um estado imutável, os atores criam complexidade e limitam o rendimento - uma função pura em um objeto, por exemplo, pode ser chamada simultaneamente sem risco com qualquer nível de simultaneidade, mas um ator só pode processar uma mensagem por vez. A consideração alternativa é que você irá estacionar o tópico se você precisar esperar pelo resultado, a menos que você comece a usar futuros, mas casos em que não precisa se preocupar com mensagens assíncronas ou escalas, parece ser um exagero empregar um ator. / p>

Então, minha pergunta é: há um momento ruim para usar atores? Estou curioso para saber como o Erlang se parece e gostaria muito do insight de outras pessoas. Ou se existem alguns princípios sobre o uso de atores.

    
por JasonG 27.09.2013 / 21:16
fonte

5 respostas

21

Vale a pena considerar para que o modelo de ator é usado: o modelo do ator é

  1. um modelo de simultaneidade
  2. que evita o acesso simultâneo ao estado mutável
  3. usando mecanismos de comunicação assíncrona para fornecer simultaneidade.

Isso é valioso porque é muito difícil usar o estado compartilhado de vários segmentos, especialmente quando há relacionamentos entre diferentes componentes do estado compartilhado que devem ser mantidos sincronizados. No entanto, se você tiver componentes de domínio em que:

  • Você não permite concorrência, OU
  • Você não permite o estado mutável (como na programação funcional), OR
  • Você deve confiar em algum mecanismo de comunicação síncrona,

o modelo de ator não fornecerá muito (se houver) benefício.

Espero que ajude.

    
por 28.09.2013 / 22:14
fonte
20

Esta é uma questão em que estou interessado e tenho pesquisado. Para outros pontos de vista, veja este post de Noel Walsh ou esta pergunta no estouro de pilha. Eu tenho algumas opiniões que gostaria de oferecer:

  • Eu acho que Akka, porque funciona com mensagens, encoraja uma "mentalidade de empurrar". Muitas vezes, por concorrência, eu diria que isso não é o que você quer. Puxar é muito mais seguro. Por exemplo, um padrão comum para sistemas distribuídos é ter um conjunto de trabalhadores processando informações em uma fila . Obviamente isso é possível em Akka mas não necessariamente parece seja a primeira abordagem que as pessoas tentam A Akka também oferece caixas de correio duráveis , mas novamente depende de como você as usa - uma única fila compartilhada é muito mais flexível do que por filas de trabalhadores para balancear / reatribuir o trabalho.
  • É fácil entrar na mentalidade de substituir suas aulas por atores. Na verdade, algumas pessoas parecem até mesmo defender isso dizendo que os atores devem fazer apenas uma coisa: . Levando à sua conclusão lógica, isso aumenta a complexidade do código, como Jason descreve, porque se cada classe é um ator, são muitas mensagens extras e blocos de recebimento / envio. Também torna mais difícil entender e testar o código porque você perde a formalidade das interfaces - e não estou convencido de que comentários são uma solução para isso . Além disso, apesar da eficiência lendária da Akka , eu suspeito que a proliferação de atores não é uma boa ideia desempenho sábio - quando usamos os encadeamentos Java, sabemos que eles são preciosos e os conservamos de acordo.
  • Está relacionado ao ponto anterior, mas outro incômodo é a perda de informações de tipo que Noel e Pino destacam, pois, para muitos de nós, é por isso que estamos usando o Scala em vez de outras linguagens como o Python. Existem algumas formas de contornar isso, mas elas são não padrão , não recomendado ou experimental .
  • Por fim, a simultaneidade, mesmo que você tenha uma deixe funcionar" mentalidade, é difícil. Modelos alternativos de programação podem ajudar, mas eles não fazem os problemas desaparecerem - eles os modificam - é por isso que é bom pense sobre eles formalmente . É também por isso que o desenvolvedor Joe Average procura ferramentas prontas como bancos de dados RabbitMQ, Storm, Hadoop, Spark, Kafka ou NoSQL. A Akka tem algumas ferramentas e componentes pré-construídos, o que é legal, mas também parece bastante baixo, então elementos comuns mais prontos de sistemas distribuídos ajudariam os desenvolvedores e garantiriam que os sistemas fossem construídos corretamente.

Como Jason, estou ansioso para ouvir a opinião de outras pessoas aqui. Como posso resolver alguns dos problemas acima e usar Akka melhor?

    
por 11.02.2014 / 03:32
fonte
12

Sua intuição está correta, IMHO. Usar atores em todos os lugares é como ter o martelo proverbial e ver apenas unhas.

A melhor prática do Erlang é usar processos / atores para todas as atividades que acontecem simultaneamente. Isto é, assim como na vida real. Às vezes, é difícil encontrar a granularidade correta, mas na maioria das vezes você só conhece o domínio modelado e usa um pouco de bom senso. Eu tenho medo de não ter um método melhor do que isso, mas espero que ajude.

    
por 27.09.2013 / 22:59
fonte
0

Para enviar mensagens de entrada / saída:

Recentemente, eu me encontrei com um aplicativo baseado em akka, onde o modelo de ator realmente causava problemas de concorrência, um modelo mais simples teria sido melhor sob carga.

O problema era que as mensagens recebidas estavam se movendo em diferentes 'faixas' (através de diferentes caminhos de ator), mas o código assumia que as mensagens chegariam ao seu destino final na mesma ordem em que chegavam. Desde que os dados chegassem com intervalos suficientemente grandes, isso funcionava porque haveria apenas uma única mensagem conflitante correndo para o destino. Quando os intervalos diminuíram, eles começaram a chegar fora de ordem e causando um comportamento estranho.

O problema poderia ter sido resolvido corretamente com um pouco menos de atores, mas é um erro fácil cometê-lo ao usá-los em excesso.

    
por 06.06.2017 / 00:23
fonte
-1

Na minha opinião, há dois casos de uso para os atores. Recursos compartilhados, como portas e similares, e grande estado. O primeiro foi bem coberto pela discussão até agora, mas o estado grande também é uma razão válida.

Uma grande estrutura sendo passada com cada chamada de procedimento pode usar muita pilha. Esse estado pode ser colocado em um processo separado, a estrutura substituída por um ID de processo e esse processo consultado conforme necessário.

Bancos de dados como mnesia podem ser considerados como armazenando o estado externamente ao processo de consulta.

    
por 02.04.2016 / 02:25
fonte