Você pode implementar a multilocação com o MongoDB Search para que uma única instância de um aplicativo sirva a vários locatários. Esta página descreve recomendações de design que se aplicam especificamente ao MongoDB Search para dados estruturados e aos índices do MongoDB Search para dimensionar com segurança enquanto mantém o isolamento do locatário.
Importante
Esta orientação pressupõe que você pode colocar locatários em uma única VPC. Se o isolamento rigoroso da rede for necessário, você deverá manter projetos separados para cada locatário.
Escolher uma estratégia
Selecione uma estratégia com base em suas necessidades de isolamento, metas de dimensionamento e requisitos de carga de gravação. As estratégias mais comuns são:
Uma única coleção para todos os locatários – essa estratégia é recomendada para a maioria das cargas de trabalho.
Um banco de dados por locatário - Essa estratégia oferece alto isolamento, mas aumenta a contagem de índices.
Uma coleção por locatário – essa estratégia não é recomendada para cargas de trabalho do MongoDB Search.
Uma única coleção para todos os inquilinos (recomendado)
Recomendamos aplicar a estratégia de uma coleção para todos os locatários. Nessa arquitetura, você armazena todos os dados de locatários em uma única coleção dentro de um único banco de dados. Você pode distinguir entre inquilinos incluindo um campo tenant_id dentro de cada documento. Este campo pode ser qualquer identificador exclusivo para o locatário, como UUID ou um nome de locatário.
Essa abordagem centralizada oferece os seguintes benefícios:
Reduz o número de índices
Como todos os dados do locatário são armazenados em uma coleção, você precisa de apenas um único índice que sirva documentos para todos os locatários. Você evita atingir os limites de recursos do cluster. Por exemplo, você pode incluir o
tenant_ide outros campos compartilhados ou específicos do inquilino em um único índice.Simplifica as operações de manutenção
Com apenas uma única coleção armazenando todos os dados, você não precisa manter várias coleções ou dimensionar recursos em vários bancos de dados. Você também simplifica as operações de backup, fragmentação e replicação, pois precisa direcionar apenas uma única coleção em um único banco de dados.
Processa query de forma eficiente
Você fornece o campo
tenant_idem suas queries como um filtro usando o operador igual na cláusula$search.compound.filter.Observação
Os resultados da query incluirão apenas documentos do locatário correspondente, evitando o vazamento de dados entre locatários.
Se os locatários que você coloca compartilharem padrões de acesso e tamanhos de recursos semelhantes, essa estratégia também manterá a contagem de campo de índice Lucene baixa.
Importante
Quando cada locatário tem uma alta carga de gravação, colocar todos os locatários em uma única coleção pode criar uma contenção de gravação. Nesse cenário, considere dividir os locatários com o maior número de gravações em coleções separadas para distribuir a carga de gravação por mais recursos subjacentes.
Se você tiver locatários grandes com requisitos exclusivos de recursos ou indexação, use uma Visualização:
Isolar um inquilino. Crie uma visualização utilizando um
$matchcom uma operação$exprpara filtrar somente os documentos do inquilino.Índice separadamente. Crie um índice de pesquisa MongoDB na visualização.
Isso permite que você personalize a definição de índice para o locatário grande sem afetar o índice compartilhado usado por outros. Todos os outros locatários podem usar um único índice.
Uma contagem alta de índice gera uma carga significativa no cluster base e pode interromper sua carga de trabalho. O limite rígido para índices de pesquisa em um único cluster é 2,500. No entanto, o número de índices que seu cluster pode suportar depende da camada do cluster e da carga de trabalho. Camadas de cluster menores, como
M10, podem sofrer degradação de desempenho ou erros de falta de memória com muito menos índices. Comece com um pequeno número de índices e monitore o uso de recursos do cluster à medida que você escala.
Se você aplicar atualmente a estratégia de uma coleção por locatário, recomendamos o dimensionamento do tier base para evitar o aumento dos erros de replicação ou OOM devido à contenção de recursos de um alto número de índices. Também recomendamos migrar para a estratégia de uma coleção para todos os locatários.
Lidando com inquilinos de alta gravação
Se locatários específicos tiverem cargas de escrita massivas, eles poderão causar contenção em uma coleção compartilhada. Recomendamos que você mova somente os locatários de maior volume para coleções separadas para distribuir a carga de E/S.
Tratamento de requisitos únicos (visualizações)
Se um locatário exigir indexação exclusiva ou for significativamente maior que outros, use uma visualização MongoDB:
Crie uma visualização usando
$matchpara filtrar apenas os documentos desse locatário.Crie um índice de pesquisa do MongoDB nessa visualização. Isso permite a personalização para locatários outliers sem interromper o índice compartilhado usado pela maioria.
Um banco de dados por locatário
Em uma configuração de banco de dados por locatário, cada locatário contém seu próprio banco de dados. Essa configuração isola os dados do locatário, mas também multiplica o número de índices no cluster. Se houver mais de 2,500 bancos de dados suportando todos os locatários, o cluster poderá atingir o 2,500-teto de índice.
Aviso
Uma contagem alta de índice gera uma carga significativa no cluster base e pode interromper sua carga de trabalho. O limite rígido para índices de pesquisa em um único cluster é 2,500. No entanto, o número de índices que seu cluster pode suportar depende da camada do cluster e da carga de trabalho. Camadas de cluster menores, como M10, podem sofrer degradação de desempenho ou erros de falta de memória com muito menos índices. Comece com um pequeno número de índices e monitore o uso de recursos do cluster à medida que você escala.
Uma coleção por locatário (não recomendado)
A estratégia de coleção por inquilino mapeia cada inquilino para sua própria coleção em um banco de dados compartilhado. A sobrecarga de manter um índice por coleção pode causar:
Maior atraso de replicação
Erros de OOM devido à contenção de recursos
Instabilidade no nível base
Não recomendamos essa estratégia para o MongoDB Search, a menos que os locatários tenham cargas de trabalho leves e muito previsíveis. Se você usa essa estratégia atualmente, migre para a estratégia de uma coleção para todos os locatários strategy.
Gerenciando campos indexados
Considere as seguintes recomendações para gerenciar campos indexados:
Aplicativos de vários locatários geralmente exigem campos personalizados por locatário que podem ser pesquisados, classificados, facetados e filtrados. Use um typeSet para indexar dinamicamente os subcampos de um caminho para que o MongoDB Search escolha novos campos automaticamente sem uma reconstrução completa do índice. Evite a indexação estática desses campos, pois isso aciona uma reconstrução que aumenta a pressão da CPU e consome até 2x do espaço em disco do índice.
Observação
Arriscar muitos campos
O desempenho do índice Lucene poderá diminuir se houver mais de 1000 campos distintos. Você pode monitorar o número de campos exclusivos no índice do MongoDB Search nas métricas do MongoDB Search. Se você precisar oferecer suporte a mil ou mais campos, recomendamos o seguinte:
Separando um subconjunto de locatários em um índice separado usando uma Visualização, de modo que o número distinto de campos existentes em um único índice Lucene permaneça inferior a mil.
Limitando o número de campos que um único locatário pode adicionar.
Se você usar o padrão de atributo para armazenar chaves diferentes por locatário, recomendamos que faça o seguinte:
Nivelar o array incorporado de documentos usando uma Visualização.
Crie um índice do MongoDB Search na visualização, que é armazenado em disco.
Se você não nivelar a array de documentos, precisará usar queries do operador embeddedDocuments (semelhantes a $elemMatch) para consultar os atributos, o que é menos eficiente do que consultar uma estrutura nivelada.