Planeamento da implementação para Operações IoT do Azure

Muitas definições do Operações IoT do Azure são fixas no momento da implementação e só podem ser alteradas através da nova implementação. Antes de implementares, planeia a topologia do cluster, cardinalidade do broker, perfil de memória e as definições opcionais do broker de que precisas. Este artigo resume as decisões que deve tomar.

Entenda a arquitetura

Operações IoT do Azure é um conjunto de serviços modulares, nativos do Kubernetes, implementados num cluster compatível com Azure Arc. Os principais componentes incluem:

Componente Purpose
Corretor MQTT Broker MQTT 3.1.1 e 5 de alto desempenho para mensagens na periferia
Conector para OPC UA Recolhe dados dos servidores OPC UA e publica no MQTT
Fluxos de dados Roteia, transforma e envia dados para os endpoints da cloud
Registo de Dispositivos Azure Registo baseado na cloud para dispositivos, ativos e esquemas
Serviços Akri Descoberta de dispositivos e adaptadores de protocolo
Loja estatal Camada de persistência de chave-valor no corretor MQTT

Dois termos são usados em toda a documentação:

  • Implementação — A instância, extensões Arc, localizações personalizadas e todos os recursos configuráveis (ativos, dispositivos, fluxos de dados).
  • Instância — O recurso principal que agrupa os serviços.

Escolha a topologia do seu cluster

Antes de implementar, decide se precisas de um cluster de um único nó ou de múltiplos nós. Esta decisão determina os requisitos de hardware e as definições de cardinalidade do corretor.

Topology Caso de uso Hardware mínimo
Nó único Implantações mais pequenas onde não é necessária alta disponibilidade 4 vCPUs, 16 GB de RAM, 30 GB de armazenamento
Multinó (3-5 nós) Alta disponibilidade e requisitos de maior capacidade de processamento 8 vCPUs, 32 GB de RAM por nó

Importante

A cardinalidade é definida apenas no momento de implementação. Uma nova implantação será necessária se as configurações de cardinalidade precisarem ser alteradas.

Compreenda a cardinalidade do corretor

A cardinalidade é o número de réplicas do frontend, processos de trabalho do frontend, partições do backend e processos de trabalho do backend na implantação do broker. A cardinalidade controla como o broker escala horizontalmente e quão resiliente é a falhas de pods ou nós.

O broker MQTT tem uma arquitetura de dois níveis: os pods frontend gerem ligações ao cliente e processamento de protocolos, enquanto os pods backend gerem o armazenamento e entrega de mensagens. É importante compreender como cada nível cresce para o planeamento de capacidade.

Frontend

Os pods frontend aceitam ligações de cliente MQTT e encaminham mensagens para o backend. Os pods frontend não armazenam mensagens por si só. Existem duas definições principais para o nível frontend:

  • Replicas: O número de pods de frontend a implantar. Adicionar mais réplicas de frontend aumenta o número de ligações simultâneas de clientes que o broker consegue gerir e proporciona elevada disponibilidade caso um dos pods de frontend falhe.
  • Trabalhadores: O número de trabalhadores lógicos por pod frontend. Adicionar mais trabalhadores permite que o pod frontend use mais núcleos de CPU. Cada trabalhador pode consumir até um núcleo de CPU.

Cadeia de backend

Os pods de backend tratam do armazenamento e entrega de mensagens. Existem três definições principais para o nível backend:

  • Partições: O número de partições a serem implantadas. As partições são a unidade de escalonamento horizontal para a taxa de transferência de mensagens. Através de um processo chamado sharding, cada partição trata uma parte das mensagens, fragmentadas por tópico e sessão. Os pods frontend distribuem o tráfego de mensagens pelas partições. Adicionar mais partições aumenta o throughput total de mensagens que o broker consegue gerir.
  • Fator de redundância: O número de pods de backend a implementar por partição. O aumento do fator de redundância aumenta o número de cópias de dados para proporcionar resiliência contra falhas de nós no cluster.
  • Trabalhadores: O número de trabalhadores por pod de backend. Os trabalhadores são a unidade de escalabilidade vertical dentro de uma partição — adicionar mais trabalhadores permite que o pod backend use mais núcleos de CPU no mesmo nó. Cada processo de trabalho pode consumir até dois núcleos de CPU, por isso tenha cuidado ao aumentar o número de processos de trabalho por réplica para não exceder o número de núcleos de CPU no aglomerado.

Note

A eficácia da escalabilidade de partições depende de quão uniformemente o espaço temático está distribuído entre as partições. Uma distribuição altamente assimétrica pode criar hotspots numa única partição.

Importante

O fator de redundância do backend deve ser 2 ou superior. O broker exige pelo menos duas réplicas de back-end por partição para alta disponibilidade e suporte para atualizações contínuas. Definir o fator de redundância para 1 resulta num erro de validação de implantação.

Estimativa da taxa de transferência

O desempenho de uma partição específica depende fortemente das características da CPU do nó em que está a ser executada. Como regra geral, espere cerca de 5.000 a 6.000 mensagens QoS 1 por segundo por partição com cargas úteis de 8 KB num CPU de 2 GHz (~4 GHz turbo). O desempenho no mundo real depende de muitos fatores, por isso use este número apenas como ponto de partida para o planeamento da capacidade.

Para dados de referência detalhados, consulte avaliação de desempenho do broker MQTT.

Recomendações de nó único

  • Réplicas de front-end: Definidas como 1.
  • Trabalhadores frontend: Definir para metade do número de núcleos de CPU por nó.
  • Réplicas do backend (fator de redundância): Defina como, no mínimo, 2 para que o broker possa realizar atualizações progressivas.

Exemplo: nó único, 4 núcleos de CPU

Configuração frontend Value Configuração do backend Value
Replicas 1 Fator de redundância 2
Trabalhadores 2 Trabalhadores 1
Partitions 1

Recomendações para múltiplos nós

São recomendados os seguintes valores para um desempenho ótimo. Para clusters grandes com pouco tráfego, estes valores podem ser definidos abaixo das recomendações sem causar problemas. Mais considerações como memória (RAM) e características de desempenho são discutidas nas secções seguintes. Teste sempre a sua configuração com a carga de trabalho esperada para confirmar o desempenho.

  • Réplicas de front-end: Definidas para corresponder ao número de nós no cluster.
  • Trabalhadores frontend: Definir para metade do número de núcleos de CPU por nó.
  • Réplicas do backend (fator de redundância): Definido para 2 para redundância e suporte a atualizações progressivas.
  • Partições de backend: Definir como igual ao número de nós do cluster.
  • Trabalhadores do backend: Definido para metade do número de núcleos de CPU por nó.

Exemplo: cluster de 3 nós, 8 núcleos de CPU por nó

Configuração frontend Value Configuração do backend Value
Replicas 3 Fator de redundância 2
Trabalhadores 4 Trabalhadores 4
Partitions 3

Exemplo: cluster de 5 nós, 16 núcleos de CPU por nó

Configuração frontend Value Configuração do backend Value
Replicas 5 Fator de redundância 2
Trabalhadores 8 Trabalhadores 8
Partitions 5

Importante

O número total de trabalhadores frontend e backend por nó não deve exceder o número de núcleos de CPU disponíveis nesse nó. O excesso de provisionamento dos trabalhadores para além dos núcleos disponíveis pode causar contenção na CPU e degradar o desempenho.

Limites de recursos da CPU

Para evitar falta de recursos no cluster, o broker pode ser configurado para solicitar limites de recursos da CPU Kubernetes com base nas definições de cardinalidade. Quando ativado, escalar o número de réplicas ou trabalhadores aumenta proporcionalmente os recursos da CPU necessários.

Importante

O valor padrão para generateResourceLimits.cpu depende do método de implementação:

  • CLI do Azure (az iot ops create): Disabled por defeito, para evitar falhas de implementação em clusters com recursos limitados, como clusters de nó único onde os pedidos de CPU podem exceder os recursos disponíveis.
  • REST API, Bicep e modelos ARM: Enabled por predefinição. Se implementares com estes métodos sem definir generateResourceLimits.cpuexplicitamente , os limites de recursos da CPU são aplicados automaticamente.

Se ativares limites de recursos da CPU, certifica-te de que o teu cluster tem recursos suficientes para satisfazer os pedidos do broker com base na tua configuração de cardinalidade.

O padrão para os templates REST API, Bicep e ARM está definido na especificação Broker API.

O broker MQTT solicita recursos de CPU por pod com base no número de trabalhadores configurados:

  • Frontend pods: 1.0 CPU por processo
  • Pods de backend: 2.0 CPU por trabalhador

Use as seguintes fórmulas para calcular os requisitos totais de CPU:

Componente Formula
CPU de Frontend replicas × frontend.workers × 1,0 CPU
CPU de Backend partitions × redundancyFactor × backend.workers × 2.0 CPU
Total broker CPU Processador de Frontend + Processador de Backend

Atenção

O broker não é o único componente que consome CPU no cluster. Outros componentes do Operações IoT do Azure (como o motor de fluxo de dados, o conector OPC UA e os pods do sistema) também reservam recursos de CPU, normalmente entre 200 e 300 m no total. Ao planear a capacidade do cluster, certifique-se de ter em conta esta sobrecarga para além dos requisitos de CPU do corretor. Se o total de CPU solicitado por todos os pods exceder o CPU disponível no seu cluster, os broker pods ficam presos num estado Pending.

Exemplo: pequeno agrupamento

Considere um cluster de 2 nós com 4 núcleos de CPU por nó (8 núcleos no total) com a seguinte cardinalidade:

{
  "cardinality": {
    "frontend": {
      "replicas": 2,
      "workers": 2
    },
    "backendChain": {
      "partitions": 1,
      "redundancyFactor": 2,
      "workers": 1
    }
  }
}

O corretor solicita:

  • Frontend de CPU: 2 réplicas × 2 trabalhadores × 1.0 = 4.0 CPU
  • Backend CPU: 1 partição × 2 RF × 1 trabalhador × 2.0 = 4.0 CPU
  • CPU do broker total: 8,0 CPU

Esta configuração exige CPU 8.0 num cluster com apenas 8 núcleos, não deixando nada para outros componentes do Operações IoT do Azure (200-300m) ou para pods do sistema Kubernetes. Os pods do broker permanecem no estado Pending com erros Insufficient cpu.

Para resolver isto, pode adicionar mais nós, aumentar o número de núcleos por nó ou reduzir a cardinalidade do corretor.

Exemplo: implantação maior

A seguinte cardinalidade exige significativamente mais recursos de CPU:

{
  "cardinality": {
    "frontend": {
      "replicas": 3,
      "workers": 2
    },
    "backendChain": {
      "partitions": 3,
      "redundancyFactor": 2,
      "workers": 2
    }
  }
}
  • Frontend CPU: 3 réplicas × 2 trabalhadores × 1.0 = 6.0 CPU
  • CPU do Backend: 3 partições × 2 RF × 2 workers × 2.0 = 24.0 CPU
  • CPU total do broker: CPU 30.0

Um cluster precisa de ter, pelo menos, 30 núcleos de CPU disponíveis apenas para os pods do broker, além de margem de capacidade para outros componentes do Operações IoT do Azure e para os pods de sistema do Kubernetes.

Configuração do limite de recursos da CPU

Os limites de recursos da CPU são controlados pelo generateResourceLimits.cpu campo no recurso Broker. Esta configuração é suportada apenas usando a flag --broker-config-file quando se implementa Operações IoT do Azure usando o comando az iot ops create. Para mais informações, consulte o suporte da CLI Azure para configuração avançada de corretores MQTT.

Prepare um ficheiro de configuração do Broker seguindo a referência da API GenerateResourceLimits . Os exemplos seguintes mostram os dois valores possíveis:

{
  "generateResourceLimits": {
    "cpu": "Enabled"
  }
}

Ou

{
  "generateResourceLimits": {
    "cpu": "Disabled"
  }
}

Escolha o seu perfil de memória

O perfil de memória controla o tamanho máximo da mensagem MQTT que o broker aceita, o uso de memória inativa e o uso máximo de memória de cada pod. Decida o perfil de memória adequado antes da implementação, com base nos tamanhos de mensagem e na taxa de transferência esperados.

Perfil de memória Tamanho máximo da mensagem Memória ociosa do frontend (por pod) Memória máxima de frontend (por pod) Memória ociosa do backend (por pod) Memória máxima do backend (por pod) Caso de uso
Tiny 4 MB ~29 MiB ~99 MiB ~41 MiB ~102 MiB Pouco tráfego, apenas pacotes pequenos
Baixo 16 MB ~33 MiB ~387 MiB ~66 MiB ~390 MiB Memória limitada, pacotes pequenos
Médio (padrão) 64 MB ~169 MiB ~1,9 GiB ~211 MiB ~1,5 GiB Tráfego moderado e tamanhos de mensagens
High 256MB ~4,9 GiB ~4,9 GiB ~5,8 GiB ~5,8 GiB Alta capacidade de consumo, mensagens grandes

Note

Os valores de memória na tabela são por cada pod. Todos os trabalhadores dentro de um pod partilham a mesma alocação de memória — adicionar mais trabalhadores não aumenta o limite de memória do pod.

Warning

O intermediário rejeita mensagens quando a utilização de memória atinge 75% capacidade. Escolha um perfil com margem suficiente para o tamanho e o débito esperados de mensagens.

Buffer de entrada e contrapressão

Cada perfil de memória define um tamanho máximo de buffer de entrada para dados PUBLISH por trabalhador backend. Quando o buffer atinge 75% capacidade, o corretor ativa mecanismos de contrapressão e começa a rejeitar mensagens recebidas. Os pacotes rejeitados recebem uma resposta PUBACK com o código de erro Quota excedida.

A tabela seguinte mostra os tamanhos dos buffers recebidos por trabalhador para cada perfil:

Perfil de memória Buffer máximo de entrada (por trabalhador) Buffer efetivo (com 75% de retropressão)
Tiny ~16 MiB ~12 MiB
Baixo ~64 MiB ~48 MiB
Medium ~576 MiB ~432 MiB
High ~2 GiB ~1,5 GiB

Ao escolher um perfil de memória, considere:

  • Tiny: Só deve ser usado um frontend. Envie apenas pacotes menores que 4 MiB.
  • Baixo: Devem ser usados apenas um ou dois front-ends. Envie apenas pacotes menores que 16 MiB.
  • Médio: Adequado para a maioria das cargas de produção com mensagens de tamanho moderado.
  • Alta: Use quando precisa de lidar com mensagens grandes ou alta capacidade com grandes buffers.

A memória total do broker depende tanto do perfil de memória como também da cardinalidade (número de réplicas de frontend, partições de backend e fator de redundância). Mais pods significam mais memória total. Para consumo de recursos de referência medido em diferentes configurações, veja Perfis de recursos de referência.

Calcular o uso total de memória

Pode calcular o uso total de memória com esta fórmula:

M_total = (R_fe × M_fe) + (P_be × RF_be × M_be × W_be)

Where:

Variable Descrição
M_total Utilização total de memória
R_fe O número de réplicas de frontend
M_fe O uso de memória de cada réplica de frontend
P_be O número de partições de back-end
RF_be Fator de redundância de back-end
M_be O uso de memória de cada réplica de backend
W_be O número de trabalhadores por réplica de backend

Por exemplo, se escolher o perfil de memória Medium , o perfil tem uma utilização de memória frontend de 1,9 GiB e uma utilização de memória backend de 1,5 GiB. Suponha que a configuração do broker seja de 2 réplicas de front-end, 2 partições de back-end e um fator de redundância de back-end de 2. O uso total de memória é:

M_total = (2 × 1.9 GiB) + (2 × 2 × 1.5 GiB × 2)
        = 15.8 GiB

Em comparação, o perfil de memória Tiny tem uma utilização de memória frontend de 99 MiB e uma utilização de memória backend de 102 MiB. Com a mesma configuração do broker, o uso total de memória é:

M_total = (2 × 99 MiB) + (2 × 2 × 102 MiB × 2)
        = 198 MiB + 816 MiB
        = 1014 MiB (≈ 1.0 GiB)

Configuração do perfil de memória

Quando implementa o IoT Operations usando o az iot ops create comando, o --broker-mem-profile parâmetro especifica as definições do perfil de memória.

Por exemplo, o comando seguinte define o perfil de memória para Tiny (outros parâmetros são omitidos para brevidade):

az iot ops create ... --broker-mem-profile Tiny

Para saber mais, consulte az iot ops create Parâmetros opcionais.

Definições opcionais do corretor

As seguintes definições do corretor também são configuradas no momento da implementação e não podem ser alteradas posteriormente. Analise estes pontos caso se apliquem ao seu caso:

  • Buffer de mensagens com suporte em disco — Armazena as mensagens em disco quando as filas dos assinantes excedem a memória disponível. Útil para sessões persistentes e desafios de conectividade.
  • Persistência — Escreva dados críticos do broker no disco para os preservar durante reinícios.
  • Diagnóstico — Configure métricas, registos e sondas de auto-verificação para o corretor MQTT.
  • Opções avançadas de MQTT — Configure a expiração da sessão, a expiração das mensagens, os limites da fila de subscritores e as definições de keep-alive.
  • Encriptação do tráfego interno — Configurar a encriptação do tráfego interno entre os pods frontend e backend do broker (ativada por defeito).

Passos seguintes