Share via


Abordagens de arquitetura para computação em soluções de multilocatário

A maioria das soluções baseadas em nuvem é composta por recursos de computação de algum tipo, como camadas da Web e de aplicativos, processadores em lote, tarefas agendadas e até recursos especializados, como GPUs e computação de alto desempenho (HPC). As soluções multilocatários geralmente se beneficiam de recursos de computação compartilhados, pois uma maior densidade de locatários para a infraestrutura reduz o custo operacional e o gerenciamento. Você deve considerar os requisitos de isolamento e as implicações da infraestrutura compartilhada.

Este artigo fornece diretrizes sobre considerações e requisitos essenciais para consideração dos arquitetos de solução ao planejar uma camada de computação multilocatário. Isso inclui alguns padrões comuns para aplicar multilocação a serviços de computação, juntamente com alguns antipadrões a serem evitados.

Considerações e requisitos

A multilocação e o modelo de isolamento selecionado afetam o dimensionamento, o desempenho, o gerenciamento de estado e a segurança de seus recursos de computação. Nesta seção, revisamos algumas das principais decisões que você deve tomar ao planejar uma solução de computação multilocatário.

Escala

Os sistemas precisam ser executados adequadamente sob a alteração da demanda. À medida que o número de locatários e a quantidade de tráfego aumentam, talvez seja necessário aumentar a capacidade de seus recursos para acompanhar o número crescente de locatários e manter uma taxa de desempenho aceitável. Da mesma forma, quando o número de usuários ativos ou a quantidade de tráfego diminuir, você deve reduzir automaticamente a capacidade de computação para reduzir os custos, mas deve reduzir a capacidade com impacto mínimo para os usuários.

Se você implantar recursos dedicados para cada locatário, terá a flexibilidade de dimensionar os recursos de cada locatário de forma independente. Em uma solução em que os recursos de computação são compartilhados entre vários locatários, se você dimensionar esses recursos, todos esses locatários poderão usar a nova escala. No entanto, todos eles também sofrerão quando a balança for insuficiente para lidar com sua carga geral. Para saber mais, confira Problema do Vizinho Barulhento.

Ao criar soluções em nuvem, você pode escolher se deseja dimensionar horizontalmente ou verticalmente. Em uma solução de vários locatários com um número crescente de locatários, o dimensionamento horizontal normalmente oferece maior flexibilidade e um teto de escala geral mais alto.

Problemas de desempenho muitas vezes permanecem não detectados até que um aplicativo esteja sob carga. Você pode usar um serviço totalmente gerenciado, como o Teste de Carga do Azure, para saber como seu aplicativo se comporta sob estresse.

Gatilhos de escala

Seja qual for a abordagem usada para dimensionar, normalmente você precisa planejar os gatilhos que fazem com que seus componentes sejam dimensionados. Quando você tiver componentes compartilhados, considere os padrões de carga de trabalho de cada locatário que usa os recursos, para garantir que sua capacidade provisionada possa atender à capacidade total necessária e minimizar a chance de um locatário enfrentar o Problema do vizinho barulhento. Você também pode planejar sua capacidade de dimensionamento levando em consideração o número de locatários. Por exemplo, se você medir os recursos que usa para atender a 100 locatários, à medida que integrar mais locatários, poderá planejar o dimensionamento de modo que seus recursos dobrem para cada 100 locatários adicionais.

Estado

Os recursos de computação podem estar sem estado ou com estado. Os componentes sem estado não mantêm nenhum dado entre as solicitações. De uma perspectiva de escalabilidade, os componentes sem estado geralmente são fáceis de escalar porque você pode adicionar rapidamente novos trabalhadores, instâncias ou nós, e eles podem começar imediatamente a processar solicitações. Se sua arquitetura permitir, você também poderá redirecionar as instâncias atribuídas a um locatário e alocá-las para outro locatário.

Os recursos com estado podem ser subdivididos ainda mais, com base no tipo de estado que eles mantêm. Estado persistente consiste de dados que precisam ser armazenados permanentemente. Em soluções de nuvem, você deve evitar armazenar um estado persistente em sua camada de computação. Alternativamente, use serviços de armazenamento como bancos de dados ou contas de armazenamento. Estado transitório consiste de dados armazenados temporariamente e incluem caches de memória somente leitura e o armazenamento de arquivos temporários em discos locais.

O estado transitório geralmente é útil para melhorar o desempenho de sua camada de aplicativo, reduzindo o número de solicitações para serviços de armazenamento de back-end. Por exemplo, ao usar um cache na memória, você poderá atender a solicitações de leitura, sem se conectar a um banco de dados e sem realizar uma consulta intensiva que você executou recentemente quando atendeu a outra solicitação.

Em aplicativos sensíveis à latência, o custo de hidratação do cache pode se tornar significativo. Uma solução multilocatário pode agravar esse problema, se cada locatário exigir que dados diferentes sejam armazenados em cache. Para atenuar esse problema, algumas soluções usam afinidade de sessão para garantir que todas as solicitações para um usuário ou locatário específico sejam processadas pelo mesmo nó do trabalhador de computação. Embora a afinidade de sessão possa melhorar a capacidade da camada de aplicativo de usar seu cache com eficiência, também dificulta o dimensionamento e o balanceamento da carga de tráfego entre os funcionários. Essa compensação precisa ser cuidadosamente considerada. Para muitos aplicativos, a afinidade de sessão não é necessária.

Também é possível armazenar dados em caches externos, como o Cache do Azure para Redis. Os caches externos são otimizados para recuperação de dados de baixa latência, mantendo o estado isolado dos recursos de computação, para que possam ser dimensionados e gerenciados separadamente. Em muitas soluções, os caches externos permitem que você melhore o desempenho do aplicativo, enquanto mantém a camada de computação sem estado.

Importante

Evite o vazamento de dados entre locatários, sempre que você usar caches na memória ou outros componentes que mantêm o estado. Por exemplo, considere anexar um identificador de locatário a todas as chaves de cache para garantir que os dados sejam separados para cada locatário.

Isolamento

Ao projetar uma camada de computação multilocatário, muitas vezes você tem muitas opções a serem consideradas para o nível de isolamento entre locatários, incluindo a implantação de recursos de computação compartilhados, a serem usados por todos os locatários, recursos de computação dedicados para cada locatário ou algo entre esses extremos. Cada opção vem com uma troca não conciliável. Para ajudar você a decidir qual opção se adequa melhor à sua solução, considere seus requisitos de isolamento.

Você pode se preocupar com o isolamento lógico dos locatários e como separar as responsabilidades ou políticas de gerenciamento aplicadas a cada locatário. Como alternativa, talvez seja necessário implantar configurações de recursos distintas para locatários específicos, como implantar um SKU de máquina virtual específico para atender à carga de trabalho de um locatário.

Seja qual for o modelo de isolamento selecionado, verifique se os dados do locatário permanecem isolados adequadamente, mesmo quando os componentes estão indisponíveis ou com defeito. Considere usar o Azure Chaos Studio como parte de seu processo de teste automatizado regular para introduzir deliberadamente falhas que simulam interrupções do mundo real e verificar se sua solução não vaza dados entre locatários e está funcionando corretamente mesmo sob pressão.

Abordagens e padrões a serem considerados

Autoscale

Os serviços de computação do Azure fornecem recursos diferentes para dimensionar suas cargas de trabalho. Muitos serviços de computação oferecem suporte ao dimensionamento automático, o que exige que você considere quando deve dimensionar e seus níveis mínimo e máximo de dimensionamento. As opções específicas disponíveis para dimensionamento dependem dos serviços de computação que você usa. Veja os seguintes serviços de exemplo:

Padrão de Carimbos de Implantação

Para obter mais informações sobre como o padrão Selos de Implantação pode ser usado para dar suporte a uma solução multilocatário, confira Visão geral.

Padrão de consolidação de recursos de computação

O padrão de Consolidação de Recursos de Computação ajuda a obter uma densidade maior de locatários para calcular a infraestrutura, compartilhando os recursos de computação subjacentes. Ao compartilhar recursos de computação, muitas vezes você consegue reduzir o custo direto desses recursos. Adicionalmente, seus custos de gerenciamento geralmente são menores porque há menos componentes para gerenciar.

No entanto, a consolidação de recursos de computação aumenta a probabilidade do Problema do vizinho barulhento. A carga de trabalho de qualquer locatário pode consumir uma quantidade desproporcional da capacidade de computação disponível. Muitas vezes, você pode mitigar esse risco garantindo o dimensionamento adequado da sua solução e aplicando controles como cotas e limites de API, para evitar locatários que consomem mais do que seu quinhão da capacidade.

Esse padrão é obtido de diferentes maneiras, dependendo do serviço de computação que você usa. Veja os seguintes serviços de exemplo:

  • Serviço de Aplicativo do Azure e Azure Functions: implante planos compartilhados dos planos do Serviço de Aplicativo que representem a infraestrutura do servidor de hospedagem.
  • Aplicativos de Contêiner do Azure: implantar ambientes compartilhados.
  • AKS (Serviço de Kubernetes do Azure): implantar pods compartilhados, com um aplicativo com reconhecimento de várias dependências.
  • Máquinas virtuais: implante um único conjunto de máquinas virtuais para todos os locatários usarem.

Recursos de computação dedicados por locatário

Você também pode implantar recursos de computação dedicados para cada locatário. Os recursos dedicados reduzem o risco do Problema do Vizinho Barulhento, garantindo que os recursos de computação de cada locatário sejam isolados dos outros. Eles também permitem que você implante uma configuração distinta para os recursos de cada locatário, com base em seus requisitos. Porém, os recursos dedicados geralmente têm um custo mais alto, porque você tem uma densidade menor de locatários para recursos.

Dependendo dos serviços de computação do Azure que você usa, você precisa implantar diferentes recursos dedicados, da seguinte forma:

  • Serviço de Aplicativo do Azure e Azure Functions: implantar planos de Serviço de Aplicativo separados para cada locatário.
  • Aplicativos de Contêiner do Azure: implante ambientes separados para cada locatário.
  • Serviço de Kubernetes do Azure (AKS): implante clusters dedicados para cada locatário.
  • Máquinas virtuais: implante máquinas virtuais dedicadas para cada locatário.

Recursos de computação semi-isolados

Abordagens semi-isoladas exigem que você implante aspectos da solução em uma configuração isolada, enquanto compartilha os outros componentes.

Ao trabalhar com o Serviço de Aplicativo e o Azure Functions, você pode implantar aplicativos distintos para cada locatário e hospedar os aplicativos em planos compartilhados dos planos do Serviço de Aplicativo. Essa abordagem reduz o custo de sua camada de computação, pois os planos do Serviço de Aplicativo representam a unidade de cobrança. Ele também permite que você aplique configurações e políticas distintas a cada aplicativo. No entanto, essa abordagem introduz o risco do Problema d Vizinho Barulhento.

Os Aplicativos de Contêiner do Azure permitem implantar vários aplicativos em um ambiente compartilhado e usar o Dapr e outras ferramentas para configurar cada aplicativo separadamente.

O AKS (Serviço de Kubernetes do Azure) e o Kubernetes de forma mais ampla fornecem uma variedade de opções para multilocação, incluindo o seguinte:

  • Namespaces específicos de locatário, para isolamento lógico de recursos específicos de locatário, que são implantados em clusters compartilhados e pools de nós.
  • Nós ou pools de nós específicos do locatário em um cluster compartilhado.
  • Pods específicos de locatário que podem usar o mesmo pool de nós.

O AKS também permite que você aplique a governança em nível de pod para mitigar o Problema do Vizinho Barulhento. Para obter mais informações, confira Melhores práticas para desenvolvedores de aplicativos gerenciarem recursos no AKS (Serviço de Kubernetes do Azure).

Também é importante estar ciente dos componentes compartilhados em um cluster Kubernetes e como esses componentes podem ser afetados pela multilocação. Por exemplo, o servidor da API Kubernetes é um serviço compartilhado usado em todo o cluster. Mesmo que você forneça pools de nós específicos do locatário para isolar as cargas de trabalho do aplicativo dos locatários, o servidor de API poderá sofrer contenção de um grande número de solicitações entre os locatários.

Antipadrões a serem evitados

Antipadrão de vizinho barulhento

Sempre que você implanta componentes compartilhados entre locatários, o Problema do Vizinho Barulhento é um risco potencial. Lembre-se de incluir governança e monitoramento de recursos para mitigar o risco de a carga de trabalho de computação de um locatário ser afetada pela atividade de outros locatários.

Vazamento de dados entre locatários

As camadas de computação podem estar sujeitas a vazamento de dados entre locatários, se não forem tratadas adequadamente. Isso geralmente não é algo que você precisa considerar ao usar um serviço multilocatário no Azure, porque a Microsoft fornece proteções na camada de plataforma. No entanto, ao desenvolver seu próprio aplicativo multilocatário, considere se algum recurso compartilhado (como caches de disco local, RAM e caches externos) pode conter dados que outro locatário pode exibir ou modificar inadvertidamente.

Antipadrão do front-end ocupado

Para evitar o antipadrão Busy Front-End, evite que sua camada de front-end faça muito do trabalho que poderia ser tratado por outros componentes ou camadas de sua arquitetura. Esse antipadrão é particularmente importante quando você cria front-ends compartilhados para uma solução de vários locatários, porque um front-end ocupado prejudicará a experiência de todos os locatários.

Em vez disso, considere o uso de processamento assíncrono usando filas ou outros serviços de mensagens. Essa abordagem também permite que você aplique controles de QoS (qualidade de serviço) para diferentes locatários, com base em seus requisitos. Por exemplo, todos os locatários podem compartilhar uma camada de front-end comum, mas os locatários que pagam por um nível de serviço mais alto podem ter um conjunto maior de recursos dedicados para processar o trabalho de suas mensagens de fila.

Dimensionamento inelástico ou insuficiente

As soluções multilocatárias geralmente estão sujeitas a padrões de escala intermitentes. Os componentes compartilhados são particularmente suscetíveis a esse problema, porque o escopo de intermitência é maior e o impacto é maior quando você tem mais locatários com padrões de uso distintos.

Lembre-se de fazer bom uso da elasticidade e escala da nuvem. Considere se você deve usar o dimensionamento horizontal ou vertical e use o dimensionamento automático para lidar com picos de carga. Teste sua solução para entender como ela se comporta em diferentes níveis de carga. Lembre-se de incluir os volumes de carga esperados na produção e o crescimento esperado. Você pode usar um serviço totalmente gerenciado, como o Teste de Carga do Azure, para saber como seu aplicativo se comporta sob estresse.

Antipadrão de Sem Cache

O antipadrão Sem cache consiste de um desempenho de sua solução prejudicado porque a camada do aplicativo solicita ou recalcula repetidamente informações que podem ser reutilizadas nas solicitações. Se você tem dados que podem ser compartilhados, entre locatários ou entre usuários em um único locatário, provavelmente vale a pena armazená-los em cache para reduzir a carga em sua camada de back-end/banco de dados.

Estado desnecessário

O corolário do antipadrão Sem Cache é que você também deve evitar armazenar estados desnecessários em sua camada de computação. Explicite onde você manterá o estado e por quê. As camadas de aplicativos ou front-end com estado podem reduzir sua capacidade de dimensionamento. As camadas de computação com estado normalmente também exigem afinidade de sessão, o que pode reduzir sua capacidade de balancear efetivamente a carga do tráfego entre trabalhadores ou nós.

Considere as compensações para cada parte do estado que você mantém em sua camada de computação e se isso afeta sua capacidade de dimensionar ou crescer à medida que os padrões de carga de trabalho de seus locatários mudam. Você também pode armazenar o estado em um cache externo, como o Cache do Azure para Redis.

Colaboradores

Esse artigo é mantido pela Microsoft. Ele foi originalmente escrito pelos colaboradores a seguir.

Principais autores:

  • Dixit Arora | Engenheiro de Cliente Sênior da FastTrack para Azure
  • John Downs | Engenheiro principal de atendimento ao cliente, FastTrack for Azure

Outros colaboradores:

  • Arsen Vladimirskiy | Engenheiro principal de atendimento ao cliente, FastTrack for Azure

Próximas etapas

Revise as diretrizes específicas de serviço para seus serviços de computação: