Partilhar via


Recomendações para otimizar os custos de dimensionamento

Aplica-se a esta recomendação de lista de verificação de otimização de custos do Azure Well-Architected Framework:

CO:12 Otimize os custos de escala. Avalie o dimensionamento alternativo dentro de suas unidades de escala. Considere configurações alternativas de dimensionamento e alinhe-se com o modelo de custo. As considerações devem incluir a utilização em relação aos limites de herança de cada instância, recurso e limite de unidade de escala. Utilizar estratégias de controlo da procura e da oferta.

Este guia fornece recomendações para otimizar os custos de dimensionamento. O dimensionamento de otimização de custos é o processo de remoção de ineficiências no dimensionamento da carga de trabalho. O objetivo é reduzir os custos de dimensionamento e, ao mesmo tempo, atender a todos os requisitos não funcionais. Gastar menos para obter o mesmo resultado. A otimização do dimensionamento permite evitar despesas desnecessárias, excesso de provisionamento e desperdício. Também ajuda a evitar picos inesperados nos custos, controlando a demanda e limitando a oferta. Práticas de dimensionamento ineficientes podem levar ao aumento da carga de trabalho e dos custos operacionais e afetar negativamente a saúde financeira geral da carga de trabalho.

Definições

Termo Definição
Dimensionamento automático Uma abordagem de dimensionamento que adiciona ou remove recursos automaticamente quando um conjunto de condições é atendido.
Métricas de custo Dados numéricos relacionados ao custo da carga de trabalho.
Reduzir a escala Uma estratégia de dimensionamento vertical que muda para uma SKU mais baixa para fornecer menos recursos à carga de trabalho.
Reduzir horizontalmente Uma estratégia de dimensionamento horizontal que remove instâncias para fornecer menos recursos à carga de trabalho.
Aumentar horizontalmente Uma estratégia de dimensionamento horizontal que adiciona instâncias para fornecer mais recursos à carga de trabalho.
Unidade de escala Um grupo de recursos que se dimensionam proporcionalmente.
Aumentar verticalmente Uma estratégia de dimensionamento vertical que muda para uma SKU mais alta para fornecer mais recursos à carga de trabalho.
Unidade de manutenção de estoque (SKU) Uma camada de serviço para um serviço do Azure.
Dados de utilização Os dados de uso são informações diretas (reais) ou indiretas/representativas (proxy) sobre o quanto uma tarefa, serviço ou aplicativo está sendo usado.

Principais estratégias de design

O objetivo do escalonamento de otimização de custos é aumentar e diminuir a escala no último momento responsável e reduzir e entrar assim que for prático. Para otimizar o dimensionamento para sua carga de trabalho, você pode avaliar opções alternativas de dimensionamento dentro das unidades de escala e alinhá-las com o modelo de custo. Uma unidade de escala representa um agrupamento específico de recursos que podem ser dimensionados de forma independente ou em conjunto. Você deve projetar unidades de escala para lidar com uma quantidade específica de carga, e elas podem incluir várias instâncias, servidores ou outros recursos. Você precisa avaliar a relação custo-benefício de sua carga de trabalho, dimensionar unidades e modelos alternativos.

Se você não usar o dimensionamento, consulte as orientações sobre o dimensionamento da carga de trabalho. Você precisa descobrir se seu aplicativo pode ser dimensionado. Os aplicativos sem estado são mais fáceis de dimensionar porque podem lidar com várias solicitações ao mesmo tempo. Além disso, avalie se o aplicativo é construído usando princípios de sistemas distribuídos. Os sistemas distribuídos podem lidar com o aumento da carga distribuindo a carga de trabalho entre vários nós. No entanto, um aplicativo singleton foi projetado para ter apenas uma instância em execução a qualquer momento. Portanto, o dimensionamento pode não ser apropriado para todas as cargas de trabalho.

Avaliar a expansão versus o aumento da escala

A avaliação de scale-out versus scale-up envolve determinar a abordagem mais econômica entre aumentar os recursos em um sistema existente (scale-up) ou adicionar mais instâncias desse sistema (scale-out) com base em vários fatores, como preços, requisitos de carga de trabalho e tempo de inatividade aceitável. Escolher a abordagem de dimensionamento correta pode levar a economias significativas, garantindo que você pague apenas pelo que precisa e, ao mesmo tempo, atenda aos padrões de desempenho e confiabilidade.

O objetivo é determinar a escolha mais econômica com base nos preços da camada de serviço, nas características da carga de trabalho, no tempo de inatividade aceitável e no modelo de custo. Para alguns, pode ser mais econômico optar por instâncias mais caras em menor número. Por outro lado, para outros, um nível mais barato com mais instâncias pode ser melhor. Para tomar uma decisão informada, você precisa analisar dados reais ou representativos de sua configuração e avaliar os méritos de custo relativo de cada estratégia. Para avaliar a abordagem mais eficiente em termos de custos, considere estas recomendações:

  • Coletar dados de uso: colete dados reais de produção ou dados de proxy que representem os padrões de uso da carga de trabalho e a utilização de recursos. Esses dados devem incluir métricas como uso de CPU, uso de memória, tráfego de rede e quaisquer outras métricas relevantes que afetem o custo de dimensionamento.

  • Definir métricas de custo: identifique as métricas de custo relevantes para sua carga de trabalho, como o custo por hora, custo por transação ou custo por unidade de uso de recursos. Essas métricas ajudam a comparar a relação custo-benefício de diferentes opções de escala.

  • Coletar dados de uso: colete dados reais de produção ou dados de proxy que representem os padrões de uso da carga de trabalho e a utilização de recursos. Esses dados devem incluir métricas como uso de CPU, uso de memória, tráfego de rede e quaisquer outras métricas relevantes que afetem o custo de dimensionamento

  • Definir métricas de custo: identifique as métricas de custo relevantes para sua carga de trabalho, como o custo por hora, custo por transação ou custo por unidade de uso de recursos. Essas métricas ajudam a comparar a relação custo-benefício de diferentes opções de escala.

  • Consulte os requisitos: Ao decidir entre estratégias de expansão e expansão, considere os requisitos de confiabilidade, desempenho e dimensionamento de sua carga de trabalho. A expansão pode melhorar a confiabilidade por meio da redundância. A expansão aumenta a capacidade de um recurso, mas pode haver limites para o quanto você pode escalar.

  • Considere os limites de recursos: ao avaliar as opções de dimensionamento, é importante considerar os limites inerentes de cada limite de instância, recurso e unidade de escala. Esteja ciente dos limites superiores de escala para cada recurso e planeje de acordo. Além disso, tenha em mente os limites da sua assinatura e outros recursos.

  • Dimensionamento de teste: crie testes para diferentes cenários de dimensionamento, incluindo opções de expansão e expansão. Aplicando os dados de uso, simule o comportamento da carga de trabalho em diferentes configurações de dimensionamento. Realize testes no mundo real usando os cenários de dimensionamento modelados.

  • Calcular custos: use os dados coletados e as métricas de custo para calcular os custos associados a cada configuração de escala. Considere fatores como preços de instâncias, utilização de recursos e quaisquer custos extras relacionados ao dimensionamento.

Otimize o dimensionamento automático

A otimização da política de dimensionamento automático envolve o refinamento do dimensionamento automático para reagir a alterações de carga com base nos requisitos não funcionais da carga de trabalho. Você pode limitar as atividades de dimensionamento excessivo ajustando os limites e usando o período de resfriamento correto. Para otimizar o dimensionamento automático, considere as seguintes recomendações:

  • Analise a política de dimensionamento automático atual: entenda a política existente e seu comportamento em resposta a níveis de carga variáveis.

  • Consulte os requisitos não funcionais: identifique os requisitos não funcionais específicos que você precisa considerar, como tempo de resposta, utilização de recursos ou custo.

  • Ajustar limites de dimensionamento: ajuste os limites de dimensionamento com base nas características da carga de trabalho e nos requisitos não funcionais. Defina limites para aumentar ou diminuir a escala com base em fatores como a utilização da CPU ao longo do tempo, o tráfego de rede ou o comprimento da fila.

  • Ajuste um período de resfriamento: ajuste o período de resfriamento para evitar atividades de dimensionamento excessivas desencadeadas por picos de carga temporários. Um período de resfriamento introduz um atraso entre os eventos de dimensionamento, permitindo que o sistema se estabilize antes de novas ações de dimensionamento.

  • Monitorar e ajustar: Monitore continuamente o comportamento e o desempenho do sistema. Analise as atividades de dimensionamento e ajuste a política conforme necessário para otimizar os custos e atender aos requisitos não funcionais desejados.

Compensação: Reduzir o número de eventos de dimensionamento aumenta as chances de encontrar problemas relacionados ao dimensionamento. Isso significa que você está eliminando a almofada ou buffer extra que poderia ajudar a gerenciar possíveis problemas ou atrasos do dimensionamento.

Usar dimensionamento baseado em eventos

O dimensionamento automático controlado por eventos permite que o aplicativo ajuste dinamicamente os recursos com base em eventos ou gatilhos específicos, em vez de métricas tradicionais, como a utilização da CPU ou da memória. Por exemplo, o Kubernetes event-driven autoscaling (KEDA) pode dimensionar aplicativos com base em escaladores, como o comprimento de um tópico Kafka. A precisão ajuda a evitar flutuações de escala desnecessárias e desperdício de recursos. Um alto nível de precisão acaba otimizando os custos. Para usar o dimensionamento baseado em eventos, siga estas etapas:

  • Escolha uma fonte de evento: determine a fonte de evento que aciona o dimensionamento da unidade de escala. Uma fonte pode ser uma fila de mensagens, uma plataforma de streaming ou qualquer outro sistema controlado por eventos.

  • Configurar ingestão de eventos: configure seu aplicativo para consumir eventos da fonte de eventos escolhida. Normalmente, envolve o estabelecimento de uma conexão, a assinatura dos tópicos ou filas relevantes e o processamento dos eventos de entrada.

  • Implementar lógica de escala: escreva a lógica que determina quando e como sua unidade de escala deve ser dimensionada com base nos eventos recebidos. Essa lógica deve considerar fatores como o número de eventos, a taxa de eventos recebidos ou qualquer outra métrica relevante.

  • Integração com mecanismos de dimensionamento: Dependendo do ambiente de tempo de execução do seu aplicativo, você pode usar diferentes mecanismos de dimensionamento para ajustar os recursos alocados ao aplicativo.

  • Configurar regras de dimensionamento: defina as regras de dimensionamento que especificam como sua unidade de escala deve ser dimensionada em resposta a eventos. Essas regras podem ser baseadas em limites, padrões ou quaisquer outros critérios que se alinhem com os requisitos do seu aplicativo. Os limites de dimensionamento devem estar relacionados às métricas de negócios. Por exemplo, se você adicionar mais duas instâncias, poderá oferecer suporte a mais 50 usuários no processamento do carrinho de compras.

  • Teste e monitore: valide o comportamento de sua implementação de dimensionamento baseada em eventos testando-a com diferentes cenários de evento. Monitore as ações de dimensionamento e garanta que elas estejam alinhadas com suas expectativas.

Compensação A configuração e o ajuste fino do dimensionamento automático baseado em eventos podem ser complexos, e a configuração inadequada pode levar ao provisionamento excessivo ou insuficiente de recursos.

Otimizar a procura e a oferta

Controle a procura em relação à sua oferta. Em cargas de trabalho em que o uso determina o dimensionamento, o custo se correlaciona com o dimensionamento. Para otimizar os custos de dimensionamento, você pode minimizar os gastos com dimensionamento. Você pode descarregar a demanda distribuindo a demanda para outros recursos ou pode reduzir a demanda implementando filas de prioridade, descarregamento de gateway, buffering e limitação de taxa. Ambas as estratégias podem evitar custos indesejados devido à escala e ao consumo de recursos. Você também pode controlar o fornecimento limitando os limites de dimensionamento. Para otimizar a demanda e a oferta da carga de trabalho, considere as seguintes recomendações.

Demanda de descarga

A demanda de descarga refere-se à prática de distribuir ou transferir a demanda de recursos para outros recursos ou serviços. Você pode usar várias tecnologias ou estratégias:

  • Cache: use o cache para armazenar dados ou conteúdo acessados com frequência, reduzindo a carga em sua infraestrutura de back-end. Por exemplo, use redes de distribuição de conteúdo (CDNs) para armazenar em cache e fornecer conteúdo estático, reduzindo a necessidade de dimensionamento do back-end. No entanto, nem toda carga de trabalho pode armazenar dados em cache. Cargas de trabalho que exigem dados atualizados e em tempo real, como cargas de trabalho de negociação ou jogos, não devem usar um cache. Os dados armazenados em cache seriam antigos e irrelevantes para o usuário.

    Compensação. O cache pode introduzir desafios em termos de invalidação de cache, consistência e gerenciamento da expiração do cache. É importante projetar e implementar cuidadosamente estratégias de cache para evitar possíveis compensações.

  • Descarregamento de conteúdo: descarregue conteúdo para serviços ou plataformas externos para reduzir a carga de trabalho na sua infraestrutura. Por exemplo, em vez de armazenar arquivos de vídeo no servidor primário, você pode hospedar esses arquivos em um serviço de armazenamento separado que seja independente do servidor primário. Você pode carregar esses arquivos grandes diretamente do serviço de armazenamento. Essa abordagem libera recursos em seus servidores, permitindo que você use um servidor menor. Pode ser mais barato armazenar arquivos grandes em um armazenamento de dados separado. Você pode usar uma CDN para melhorar o desempenho.

  • Balanceamento de carga: distribua solicitações de entrada em vários servidores usando o balanceamento de carga. O balanceamento de carga distribui uniformemente a carga de trabalho e evita que um único servidor fique sobrecarregado. Os balanceadores de carga otimizam a utilização de recursos e melhoram a eficiência de sua infraestrutura.

  • Descarregamento de banco de dados: reduza a carga em seu servidor de aplicativos principal descarregando operações de banco de dados para um servidor de banco de dados separado ou um serviço especializado. Por exemplo, use uma CDN para cache de conteúdo estático e um cache Redis para cache de conteúdo dinâmico (dados do banco de dados). Técnicas como fragmentação de banco de dados, réplicas de leitura ou uso de serviços de banco de dados gerenciados também podem reduzir a carga.

    Compensação: o descarregamento de tarefas específicas para alternar recursos ajuda a reduzir ou evitar o dimensionamento extra e os custos associados ao dimensionamento. No entanto, é importante considerar os desafios operacionais e de manutenção que podem surgir com o descarregamento. A realização de uma análise de custo-benefício abrangente é crucial ao selecionar as técnicas de descarregamento mais adequadas para sua carga de trabalho. Esta análise garante que o método escolhido é eficiente e viável em relação às economias previstas e às complexidades operacionais.

Reduzir a procura

Reduzir a demanda de recursos significa implementar estratégias que ajudam a minimizar a utilização de recursos em uma carga de trabalho. O descarregamento da procura desloca a procura para outros recursos. A redução da demanda diminui a demanda sobre a carga de trabalho. A redução da demanda permite evitar o provisionamento excessivo de recursos e o pagamento por capacidade não utilizada ou subutilizada. Você deve usar padrões de design de nível de código para reduzir a demanda de recursos de carga de trabalho. Para reduzir a demanda por meio de padrões de design, siga estas etapas:

  • Compreender padrões de design: familiarize-se com vários padrões de design que promovem a otimização de recursos.

  • Analise os requisitos da carga de trabalho: avalie os requisitos específicos da sua carga de trabalho, incluindo seus padrões de demanda esperados, cargas de pico e necessidades de recursos.

  • Selecione padrões de design apropriados: escolha os padrões de design que se alinham com os requisitos e objetivos da sua carga de trabalho. Por exemplo, se sua carga de trabalho tiver uma demanda flutuante, os padrões de dimensionamento e limitação orientados a eventos podem ajudar a gerenciar a carga de trabalho alocando recursos dinamicamente. Aplique os padrões de design selecionados à sua arquitetura de carga de trabalho. Talvez seja necessário separar componentes da carga de trabalho, colocar aplicativos em contêineres, otimizar a utilização do armazenamento e muito mais.

  • Monitorar e otimizar continuamente: Avalie regularmente a eficácia dos padrões de projeto implementados e ajuste conforme necessário. Monitore o uso de recursos, métricas de desempenho e oportunidades de otimização de custos.

Seguindo essas etapas e usando padrões de projeto apropriados, você pode reduzir a demanda de recursos, otimizar custos e garantir a operação eficiente de suas cargas de trabalho.

Use estes padrões de design para reduzir a demanda:

  • Cache à parte: o padrão verifica o cache para ver se os dados já estão armazenados na memória. Se os dados forem encontrados no cache, o aplicativo poderá recuperar e retornar rapidamente os dados, reduzindo a necessidade de consultar o armazenamento de dados persistente.

  • Verificação de declarações: ao separar os dados do fluxo de mensagens, esse padrão reduz o tamanho das mensagens e oferece suporte a uma solução de mensagens mais econômica.

  • Consumidores concorrentes: esse padrão lida eficientemente com itens em uma fila aplicando processamento distribuído e simultâneo. Esse padrão de design otimiza os custos por meio de dimensionamento baseado na profundidade da fila e na definição de limites máximos de instâncias de consumidor simultâneas.

  • Consolidação de recursos de computação: esse padrão aumenta a densidade e consolida os recursos de computação combinando vários aplicativos ou componentes em uma infraestrutura compartilhada. Maximiza a utilização de recursos, evitando a capacidade provisionada não utilizada e reduzindo custos.

  • Selos de implantação: O uso de carimbos de implantação oferece várias vantagens, como a distribuição geográfica de grupos de dispositivos, a implantação de novos recursos em carimbos específicos e a observação do custo por dispositivo. Os carimbos de implantação permitem melhor escalabilidade, tolerância a falhas e utilização eficiente de recursos.

  • Descarregamento de gateway: esse padrão descarrega o processamento de solicitações em um dispositivo de gateway, redirecionando os custos de recursos por nó para a implementação do gateway. O uso desse padrão de design pode resultar em um menor custo de propriedade em um modelo de processamento centralizado.

  • Editor/assinante: esse padrão separa componentes em uma arquitetura, substituindo a comunicação direta por um agente de mensagens intermediário ou barramento de eventos. Ele permite uma abordagem orientada a eventos e faturamento baseado no consumo, evitando o provisionamento excessivo.

  • Nivelamento de carga baseado em fila: o padrão armazena em buffer solicitações ou tarefas de entrada em uma fila. O buffer suaviza a carga de trabalho e reduz a necessidade de provisionamento excessivo de recursos para lidar com picos de carga. As solicitações recebidas são processadas de forma assíncrona para reduzir custos.

  • Compartilhamento: esse padrão direciona solicitações específicas para um destino lógico, permitindo otimizações com colocalização de dados. O compartilhamento pode gerar economia de custos usando várias instâncias de recursos de computação ou armazenamento de baixa especificação.

  • Hospedagem de conteúdo estático: esse padrão fornece conteúdo estático de forma eficiente usando uma plataforma de hospedagem projetada para essa finalidade. Ele evita o uso de hosts de aplicativos dinâmicos mais caros, otimizando a utilização de recursos.

  • Limitação: esse padrão coloca limites na taxa (limitação de taxa) ou taxa de transferência de solicitações de entrada para um recurso ou componente. Ele ajuda a informar a modelagem de custos e pode ser vinculado diretamente ao modelo de negócios do aplicativo.

  • Chave de manobrista: Este padrão concede acesso seguro e exclusivo a um recurso sem envolver mais componentes, reduzindo a necessidade de recursos intermediários e melhorando a eficiência.

Controlo do fornecimento

Definir um limite máximo para o valor que você está disposto a gastar em um determinado recurso ou serviço é uma maneira de controlar a oferta. É uma estratégia importante para controlar os custos e garantir que as despesas não ultrapassem um determinado nível. Estabeleça um orçamento e monitore os gastos para garantir que eles permaneçam dentro do valor definido. Você pode usar plataformas de gerenciamento de custos, alertas de orçamento ou rastrear padrões de uso e gastos. Alguns serviços permitem que você acelere o fornecimento e limite as taxas, e você deve usar esses recursos quando for útil.

Controlar o fornecimento refere-se à definição de um limite máximo para o valor que você está disposto a gastar em um determinado recurso ou serviço. É uma estratégia importante porque ajuda a controlar os custos e garante que as despesas não ultrapassem um determinado nível. Estabeleça um orçamento e monitore os gastos para garantir que eles permaneçam dentro do limite definido. Você pode usar plataformas de gerenciamento de custos, alertas de orçamento ou rastrear padrões de uso e gastos. Alguns serviços permitem que você acelere o fornecimento e limite as taxas, e você deve usar esses recursos quando for útil.

Compensação: limites mais rígidos podem resultar em oportunidades perdidas de escalar quando a demanda aumenta, potencialmente afetando a experiência do usuário. Pode causar desligamentos ou incapacidade de responder à carga. É importante encontrar um equilíbrio entre a otimização de custos e garantir que você tenha recursos suficientes para atender às necessidades do seu negócio.

Facilitação do Azure

Avaliando a expansão versus a expansão: o Azure fornece um ambiente de teste onde você pode implantar e testar diferentes configurações de dimensionamento. Usando os dados reais da carga de trabalho ou os dados de proxy, você pode simular cenários do mundo real e medir os efeitos sobre os custos. O Azure oferece ferramentas e serviços para testes de desempenho, testes de carga e monitoramento, que podem ajudá-lo a avaliar a relação custo-benefício das opções de expansão versus expansão.

O Azure fornece recomendações de gerenciamento de custos por meio de várias ferramentas e serviços, como o Azure Advisor. Essas recomendações analisam seus padrões de uso, utilização de recursos e configurações de dimensionamento para fornecer informações e sugestões para otimizar custos.

O Teste de Carga do Azure é um serviço de teste de carga totalmente gerenciado que gera carga de alta escala. O serviço simula o tráfego das suas aplicações, independentemente de onde estiverem alojadas. Desenvolvedores, testadores e engenheiros de garantia de qualidade (QA) podem usar testes de carga para otimizar o desempenho, a escalabilidade ou a capacidade do aplicativo.

Otimizando o dimensionamento automático: muitos serviços de computação do Azure oferecem suporte à implantação de várias instâncias idênticas e ao ajuste rápido dos limites e políticas de dimensionamento. O Azure fornece recursos de dimensionamento automático que permitem ajustar automaticamente o número de instâncias ou recursos com base na demanda de carga de trabalho. Você pode definir regras e limites de dimensionamento para acionar ações de expansão ou expansão. Usando o dimensionamento automático, você pode otimizar a alocação de recursos e a eficiência de custos dimensionando dinamicamente os recursos com base na demanda real.

O Azure mantém uma lista de limites de assinatura e serviço. Há um limite geral para o número de instâncias de um recurso que você pode implantar em cada grupo de recursos, com algumas exceções. Para obter mais informações, consulte Limites de instância de recurso por grupo de recursos.

Otimizando a demanda e a oferta: o Azure Monitor fornece informações sobre o desempenho e a integridade de seus aplicativos e infraestrutura. Você pode usar o Azure Monitor para monitorar a carga em seus recursos e analisar tendências ao longo do tempo. Usando métricas e logs coletados pelo Azure Monitor, você pode identificar áreas onde ajustes de dimensionamento podem ser necessários. Essas informações podem orientar o refinamento de sua política de dimensionamento automático para garantir que ela esteja alinhada com os requisitos não funcionais e as metas de otimização de custos.

  • Descarregamento de fornecimento: o Azure tem uma CDN (Rede de Entrega de Conteúdo) na nuvem moderna chamada Azure Front Door e serviços de cache (Cache do Azure para Redis e Cache HPC do Azure). A CDN armazena em cache o conteúdo mais perto dos usuários finais, reduzindo a latência da rede e melhorando os tempos de resposta. O cache armazena uma cópia dos dados na frente do armazenamento de dados principal, reduzindo a necessidade de solicitações repetidas para o back-end. Usando CDN e serviços de cache, você pode otimizar o desempenho e reduzir a carga nos servidores para possíveis economias de custos.

  • Controlando a oferta: o Azure também permite que você defina limites de recursos para sua carga de trabalho na nuvem. Ao definir limites de recursos, você pode garantir que sua carga de trabalho permaneça dentro dos recursos alocados e evitar custos desnecessários. O Azure fornece vários mecanismos para definir limites de recursos, como cotas, políticas e alertas de orçamento. Esses mecanismos ajudam a monitorar e controlar o uso de recursos.

    O Gerenciamento de API pode classificar, limitar e limitar solicitações. Ser capaz de limitar as solicitações de entrada é uma função fundamental do Gerenciamento de API do Azure. Controlando a taxa de solicitações ou o total de solicitações/dados transferidos, o Gerenciamento de API permite que os provedores de API protejam suas APIs contra abusos e criem valor para diferentes camadas de produtos de API.

Lista de verificação de otimização de custos

Consulte o conjunto completo de recomendações.