
Estou pensando em configurar um serviço pub/sub com websockets. Pelo que posso dizer, os gargalos de escalabilidade serão principalmente com a memória, o que afeta quantos soquetes podem ser abertos por vez, portanto, acho sensato separar isso dos outros servidores que executam serviços como APIs. Isso está correto? Eu imagino que a memória é mais cara do que o poder de computação quando se trata de hospedagem. Portanto, existem práticas recomendadas quando se trata de otimizar esse tipo de servidor para escalabilidade e custo?
O objetivo é fornecer ao usuário desta aplicação web atualizações em tempo real à medida que os sistemas em campo fazem check-in com novos dados, sem ter que pesquisar o backend periodicamente. Mas não queremos duplicar os custos do nosso servidor ou pode não valer a pena. Estamos usando AWS EC2 com balanceamento de carga e escalonamento automático para nossos servidores API atuais.
Responder1
O uso real de memória de um único soquete não é muito.
O que consome memória é o estado associado a qual cliente está interessado em quais atualizações e qual cliente já recebeu uma atualização específica.
Em uma implementação primitiva (ou seja, usando a pilha de rede do sistema operacional), o último estado é mantido na forma de buffers de saída - portanto, se uma atualização for enviada para 10.000 clientes, os dados serão copiados 10.000 vezes, cada uma das cópias anexadas a um fila de saída, onde é aumentada com os cabeçalhos necessários (que contêm o estado por conexão) e, em seguida, um descritor é construído para o hardware que o instrui a enviar um pacote que é uma concatenação dos cabeçalhos e da carga útil.
A cópia da carga útil por cliente é mantida na memória até ser reconhecida pelo cliente, e é daí que vêm os requisitos de memória. Essa memória não pode ser paginada, por isso cria pressão de memória e cache em outros aplicativos.
Existem implementações que implementam partes da pilha de rede dentro do próprio programa do servidor, e podem evitar as cópias por contagem de referência ou recriando cargas úteis sob demanda, o que permite que você use muito menos memória, mas envolve muito de a codificação complicada para ser verdadeiramente escalonável, especialmente os servidores com vários soquetes, apresentam alguns problemas interessantes que a pilha de rede do sistema operacional já sabe como solucionar.
As opções que você tem
- execute o serviço pub/sub no mesmo servidor que o aplicativo
- execute o serviço pub/sub em um servidor dedicado com rede de sistema operacional
- execute o serviço pub/sub em um servidor dedicado com rede personalizada
- execute o serviço pub/sub em vários servidores dedicados
são sua estratégia de escalonamento à medida que o serviço cresce. Mudar de compartilhado para dedicado não requer muito planejamento e pode ser feito conforme necessário; uma vez que isso tenha acontecido, é hora de preparar as próximas etapas.
A expansão para vários servidores introduzirá o não-determinismo em seu sistema, pois os clientes podem receber atualizações em ordem diferente. Portanto, para que esta etapa de expansão seja bem-sucedida, seus clientes precisam estar cientes disso e ser capazes de apresentar uma visão consistente. se isso é trivial ou difícil depende da sua aplicação real.
dr:não há necessidade de otimizar prematuramente. Divida o serviço para que a primeira etapa de escalonamento seja uma simples alteração de configuração e comece a otimizar assim que isso acontecer.