View a markdown version of this page

Modelo de piscina para gráficos de propriedades rotulados - AWS Orientação prescritiva

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Modelo de piscina para gráficos de propriedades rotulados

Há três abordagens diferentes para o modelo de pool LPGs no Amazon Neptune:

  • Estratégia de propriedade ‒ Escolha a estratégia de propriedade quando precisar priorizar o uso de construções de biblioteca estabelecidas, como a linguagem Apache TinkerPop Gremlin, em detrimento do desempenho. PartitionStrategy

  • Estratégia de prefixo-rótulo ‒ Recomendamos a estratégia de prefixo-rótulo para a maioria dos cenários com base no desempenho e na limitação dos efeitos de vizinhos ruidosos.

  • Estratégia de rótulos múltiplos ‒ A estratégia de rótulos múltiplos melhorou o desempenho da estratégia de prefixo-rótulo. Ele também suporta a execução de consultas que abrangem todos os inquilinos em um cluster (por exemplo, consultas ISV para geração de relatórios ou monitoramento de todos os inquilinos).

Estratégia imobiliária

Com LPGs, os usuários podem adicionar propriedades de pares de valores-chave aos nós, vértices e bordas. Para obter a separação lógica, a maioria dos clientes modela intuitivamente isso como uma propriedade exclusiva em cada nó e borda com uma chave de propriedade comum do inquilino. A chave da propriedade do inquilino representa todos os inquilinos que possuem o nó. O identificador do inquilino é um valor exclusivo que identifica um inquilino individual.

O diagrama a seguir mostra esse modelo. Os dois subgráficos desconectados têm vários nós e bordas rotulados, com a chave da propriedade do locatário representada por. TId Cada nó e aresta de um subgráfico tem um TId valor de1. No outro subgráfico, cada nó e aresta tem um TId valor de2.

Nodos e seus relacionamentos.

Nos gráficos de propriedades rotulados, há duas maneiras de gerenciar isso. A linguagem de consulta Gremlin oferece a biblioteca PartitionStrategytransversal para ajudar a gerenciar o particionamento dos dados. O código no exemplo a seguir espera que cada nó e borda tenham uma propriedade chamadaTId:

strategy1 = new PartitionStrategy(partitionKey: "TId", writePartition: "1", readPartitions: ["1"]) strategy2 = new PartitionStrategy(partitionKey: "TId", writePartition: "2", readPartitions: ["2"])

Quando novos nós ou bordas são gravados, a propriedade "TId" é adicionada com um valor de "1" ou"2", dependendo se strategy1 ou strategy2 foi selecionada. Para o cliente com "TId" of"1", você usastrategy1. O exemplo a seguir mostra a gravação de dados desse cliente:

g.withStrategies(strategy1).addV("Label1").property("Value", "123456").property(id, "Item_1")

Para consultas de leitura, um filtro para "TId == '1'" ou "TId == '2'" é adicionado a cada nó ou passagem de borda usando strategy1 oustrategy2, respectivamente. Essas estratégias de partição simplificam seu código, mas não são necessárias. A vantagem de usar a estratégia é que ela pode ser injetada em um nível de autorização e passada para o código de nível inferior que forma a consulta. Isso separa o código que determina o identificador do cliente (TId) da lógica da consulta.

O código de exemplo a seguir mostra uma consulta Gremlin para ler dados:

g.withStrategies(strategy1).V().hasLabel("Label1")

O código anterior é equivalente ao exemplo a seguir:

g.V().hasLabel("Label1").has("TId", "1")

Da mesma forma, ao gravar dados usando o Gremlin, você pode usar a seguinte consulta:

g.withStrategies(strategy1).addV("Label1").property("Value").property(id, "Item_1")

O código anterior é equivalente ao exemplo a seguir, que não usa a estratégia de partição e, portanto, exige que a "TId" propriedade seja escrita explicitamente:

g.addV("Label1").property("TId", "1").property("Value").property(id, "Item_1")

No OpenCypher, essas bibliotecas não existem. Você é responsável por escrever e modificar suas consultas para adicionar o identificador do inquilino como uma propriedade nos nós e bordas. Por exemplo:

CREATE (n:Item {`~id`: 'Item_1', Value: '123456', TId: '1'}) CREATE (n:Item {`~id`: 'Item_2', Value: '123456', TId: '2'})

Observe a semelhança entre o código Gremlin sem a estratégia de partição. Em seguida, você pode ler o nó escrito na primeira CREATE declaração usando o seguinte código:

MATCH (n:Item {TId: '1'}) RETURN n --or MATCH (n:Item) WHERE n.TId == '1' RETURN n

Você pode escolher a estratégia de propriedade quando quiser usar construções nativas do TinkerPop Gremlin, como. PartitionStrategy No entanto, esse modelo tem desvantagens de desempenho no Amazon Neptune em comparação com a estratégia de prefixo-rótulo. Para uma discussão sobre essas desvantagens de desempenho, consulte a seção Implicações de desempenho para os modelos de GLP.

Se as condições a seguir se aplicarem, considere modelar a estratégia da propriedade somente nos nós, não nas bordas:

  • Seu gráfico tem muito mais bordas do que rótulos.

  • Cada inquilino é um gráfico desconectado.

  • Você acessa o gráfico somente usando nós como ponto de partida, não rótulos.

Estratégia de prefixo-rótulo

Se o desempenho for uma das principais preocupações, é altamente recomendável considerar a estratégia de prefixo-rótulo em vez da estratégia da propriedade.

Na estratégia prefix-label, você rotula cada nó com uma combinação de identificador de inquilino e rótulo de nó. Por exemplo, se o inquilino tiver um identificador de "1" e o rótulo do nó for"Label1", você especifica o rótulo do nó como"1-Label1". O diagrama a seguir mostra dois subgráficos desconectados que usam esse modelo.

Nódulos com rótulos que incluem prefixos e relacionamentos entre nós.

Ao gravar dados no Gremlin, você pode adicionar um número de identificação ao rótulo de qualquer nó:

g.addV("1-Label1") g.addV("2-Label6")

Ao consultar esse gráfico, você pode verificar a existência desse prefixo em um nó:

g.V().hasLabel("1-Label1")

No OpenCypher, você pode gravar dados usando uma declaração: CREATE

CREATE (n:`1-Label1` {`~id`: 'Item_1', Value: 'XYZ123456'})

Para consultar os dados que você escreveu no OpenCypher, use o código a seguir:

MATCH n= (:`1-Label1`) RETURN n

A estratégia de prefixo-rótulo pressupõe que todos os nós sejam atribuídos a um ou mais inquilinos e que as permissões não sejam atribuídas no escopo periférico. Evite usar essa estratégia em rótulos de borda, pois isso causará um grande número de predicados e afetará negativamente o desempenho de Neptune.

Há duas desvantagens principais na abordagem do rótulo de prefixo. Primeiro, é difícil executar qualquer consulta que abranja os locatários. Um exemplo é uma consulta que conta todos os nós de um determinado rótulo para geração de relatórios ou monitoramento. Se esse for seu caso de uso, considere combinar essa estratégia com a estratégia de vários rótulos. Para obter mais informações sobre como combinar estratégias, consulte a seção Modelo híbrido.

Em segundo lugar, a estratégia de prefixo-rótulo exige controles que imponham a aplicação adequada do prefixo apropriado a cada consulta para evitar o vazamento de dados. No entanto, essa estratégia é a opção mais eficiente para cargas de trabalho que exigem consultas de baixa latência, e é altamente recomendável. A seção Implicações de desempenho para modelos de GLP fornece exemplos de por que essa é a estratégia mais eficiente.

Estratégia de vários rótulos

A terceira opção é usar uma estratégia de vários rótulos. Para essa abordagem, você adiciona rótulos extras a cada nó no gráfico. Por exemplo, se você precisar filtrar todos os dados de um determinado inquilino, adicione a etiqueta de ID do inquilino. Se você precisar filtrar todos os dados de um determinado rótulo, independentemente do locatário, adicione esse rótulo. O diagrama a seguir mostra a estratégia de vários rótulos aplicada usando três rótulos para cada nó.

Agora você pode acessar o gráfico usando três padrões diferentes:

Nodes e seus relacionamentos, onde cada nó tem rótuloX, X, X-labelX.
  • Filtre Label1 para retornar todos os nós de Label1 todos os inquilinos.

  • Filtre 1 para retornar todos os nós do inquilino 1.

  • Filtre 1-Label1 para retornar todos os nós somente para o locatário 1 com etiquetaLabel1.

Pois LPGs, há duas maneiras de implementar isso.

No Gremlin, você pode usar a estratégia de travessia chamada SubgraphStrategypara limitar o escopo de todas as consultas a apenas vértices com um rótulo específico, como: "Label1"

g.withStrategies( new SubgraphStrategy( vertices=hasLabel("Label1") ) )

Ao contrário PartitionStrategy, SubgraphStrategy afeta somente a leitura de dados, não a gravação de dados. Para gravar os dados, atribua manualmente os rótulos em cada consulta:

g.addV("Label1").property("Value","XYZ123456") .addV("Label2").property("Value","XYZ123456")

Ao ler os dados, você pode usar SubgraphStrategy para consultar todos os nós com"Label1":

g.withStrategies( new SubgraphStrategy(vertices=.hasLabel("Label1")) ). V().has("Value","XYZ123456")

Neptune retorna somente o primeiro registro, que "Label1" tem um valor de. "XYZ123456" É equivalente à consulta a seguir, que não usa SubgraphStrategy:

g.V().hasLabel("Label1").hasValue("XYZ123456")

Nessa consulta básica, parece que SubgraphStrategy é mais complexo de usar. Lembre-se de que suas bibliotecas podem fornecer uma instância g com a estratégia já definida. Os desenvolvedores não precisam garantir que os filtros adequados sejam aplicados:

def getGraphTraversal(): return g.withStrategies(new SubgraphStrategy(vertices=.hasLabel("Label1")) getGraphTraversal().has("Value","XYZ123456")

As bibliotecas do OpenCypher não têm essas construções, então você deve criar vários rótulos para cada nó:

CREATE (n:`1`:`Label1`:`1-Label1` {`~id`: 'Item_1', Value: '12345'})

Ao usar esses rótulos para filtrar um subgráfico, você pode retornar nós que têm o rótulo do cliente que você está procurando ou que compartilham um relacionamento com outro nó que tenha esse rótulo:

MATCH n=(:Label1:`1`) // or MATCH n=(:`1-Label1`)

A estratégia de vários rótulos oferece a maior flexibilidade para consultar nós por tipo (Label1) ou locatário (1), ou para usar a estratégia mais eficiente de prefixo-rótulo quando o desempenho é mais importante (). 1-Label1

A principal desvantagem dessa estratégia é que cada rótulo é um objeto extra armazenado em seu gráfico. Um objeto é um nó, borda ou uma propriedade em um nó ou borda em LPGs. A velocidade de ingestão é medida e limitada por objetos por segundo, e os custos de armazenamento dependem do número de gigabytes consumidos. Isso significa que objetos extras podem ter um impacto mensurável em grande escala.

Implicações de desempenho para os modelos de GLP

O curso Modelagem de dados do AWS Skill Builder para o Amazon Neptune descreve detalhadamente os aspectos internos do modelo de dados do Neptune e as implicações da modelagem, mas resumiremos as considerações importantes para esses projetos aqui. Considere ter três inquilinos (T1, T2, T3) em um único cluster de Neptune. Esses inquilinos têm os seguintes atributos:

  • O locatário 1 (T1) tem 100 milhões de nós no total e 10 milhões são do tipo Item.

  • O locatário 2 (T2) tem um total de 10 milhões de nós e 1 milhão são do tipo Item.

  • O locatário 3 (T3) tem 100 milhões de nós no total e 1 milhão são do tipo Item.

Execute uma consulta que recuperará os itens do Locatário 3 usando a estratégia de propriedade. O Neptune inspeciona as estatísticas de duas chamadas de índice:

  • Onde tenant property key=T3 tem 100 milhões de resultados

  • Onde label = Item tem 12 milhões de resultados (10 milhões do T1 + 1 milhão do T2 + 1 milhão do T3)

O otimizador de consultas Neptune determina que a última consulta é melhor aplicada primeiro (12 milhões de resultados) e, em seguida, inspeciona cada item. tenant property key=T3 Você recupera 12 milhões de itens para encontrar 1 milhão de resultados.

Observe o impacto ruidoso dessa consulta na vizinhança. Se você tivesse 100 milhões de nós de item por inquilino, a primeira consulta teria 300 milhões de resultados em vez de 12 milhões (isso é excessivamente simplificado para fins ilustrativos). O otimizador Neptune pode ter aplicado uma ordem diferente de operações).

Em seguida, considere a estratégia de prefixo-rótulo. Faça uma única chamada de índice wherelabel=T3-Item, que retorna 1 milhão de resultados. Isso obtém o mesmo resultado da estratégia imobiliária, mas recupera 11 milhões de registros a menos. Além disso, você não se preocupa mais com vizinhos barulhentos porque o rótulo não se sobrepõe no índice.

A estratégia de vários rótulos não melhora diretamente o desempenho da consulta em relação à estratégia de propriedade. A filtragem pelo valor da propriedade é comparável à filtragem pelo valor do rótulo quando o espaço de pesquisa também é comparável. Em vez disso, a estratégia de vários rótulos oferece mais flexibilidade.  A estratégia de vários rótulos fornece desempenho equivalente à estratégia de prefixo-rótulo para ou para o rótulo. label=T3 T3-Item A estratégia de vários rótulos fornece desempenho equivalente à estratégia de propriedade para. label=Item O benefício é oferecer suporte a uma variedade de padrões de acesso.