Arquitetura de alto desempenho Graphql para sql

O mecanismo Hasura GraphQL fornece uma interface de programação de aplicativo de protocolo de transferência de hipertexto para consultar o Postgres usando GraphQL de maneira segura com permissão.

Você pode usar restrições de chave estrangeira no Postgres para consultar dados hierárquicos em uma única solicitação. Por exemplo, você pode executar esta consulta para obter o "álbum" e todas as suas "faixas" (desde que a tabela "faixas" tenha uma chave estrangeira para a tabela "álbum"):


Como você deve ter adivinhado, a consulta pode percorrer a tabela em qualquer profundidade. Essa interface de consulta combinada com permissões permite que aplicativos front-end consultem o Postgres sem escrever nenhum código de back-end.

A interface de programação do aplicativo é projetada para ser rápida (tempo de resposta) e lidar com alto rendimento (solicitações por segundo) enquanto economiza recursos (baixo uso de CPU e memória). Discutimos as decisões arquitetônicas que nos permitiram atingir esse objetivo.

A consulta de microsserviços de dados passa pelas seguintes etapas:

  1. Resolução da sessão: a solicitação chega ao gateway, o gateway resolve a chave de autorização (se houver), adiciona o ID do usuário e o cabeçalho da função e, em seguida, encaminha a solicitação ao serviço de dados.
  2. Análise de consulta: o serviço de dados recebe uma solicitação, analisa o título para obter o ID do usuário e a função e analisa o assunto como GraphQL AST.
  3. Verificação da consulta: verifique se a consulta está semanticamente correta e aplique as permissões definidas para a função.
  4. Execução da consulta: a consulta verificada é convertida em uma instrução SQL e executada no Postgres.
  5. Geração de resposta: os resultados do Postgres são processados ​​e enviados ao cliente (o gateway adicionará compactação gzip se necessário).

Os requisitos são aproximadamente os seguintes:

  1. A pilha do protocolo de transferência de hipertexto deve adicionar pouca sobrecarga e deve ser capaz de lidar com um grande número de solicitações simultâneas para obter alto rendimento.
  2. Tradução de consulta rápida (GraphQL para SQL)
  3. A consulta SQL compilada deve ser eficiente no Postgres.
  4. Os resultados do Postgris devem ser efetivamente enviados de volta.

A seguir estão várias maneiras de obter os dados necessários para consultas GraphQL:

A execução da consulta GraphQL geralmente envolve a execução de um analisador para cada campo. Na consulta de exemplo, chamaremos uma função para obter os álbuns lançados em 2018 e, em seguida, para cada um desses álbuns, chamaremos uma função para obter a faixa, que é um problema clássico de consulta N + 1. O número de consultas aumenta exponencialmente com a profundidade da consulta.

A consulta executada no Postgres é a seguinte:

Esta será a soma de N + 1 consultas para obter todos os dados necessários.

Projetos como o Data Loader visam resolver o problema de consulta N + 1 por meio de consulta em lote. O número de solicitações não depende mais do tamanho do conjunto de resultados, mas do número de nós na consulta GraphQL. Nesse caso, a consulta de amostra requer duas consultas ao Postgres para obter os dados necessários.

A consulta executada no Postgres é a seguinte:

Isso nos deu todos os álbuns. Para obter todas as faixas do álbum desejado:

Isso é um total de 2 consultas. Evitamos fazer consultas para obter as informações da faixa de cada álbum, mas usamos a cláusula where para obter todas as faixas do álbum desejado em uma consulta.

O carregador de dados foi projetado para funcionar em diferentes fontes de dados e não pode tirar proveito da funcionalidade de uma única fonte de dados. Em nosso exemplo, nossa única fonte de dados é o Postgres. Como todos os bancos de dados relacionais, o Postgres fornece uma maneira de coletar dados de várias tabelas em uma única conexão ka de consulta. Podemos determinar as tabelas necessárias para uma consulta GraphQL e usar a conexão para gerar uma única consulta para obter todos os dados. Portanto, os dados necessários para qualquer consulta GraphQL podem ser obtidos a partir de uma única consulta. Antes de enviar ao cliente, esses dados devem ser convertidos de forma adequada.

A consulta é a seguinte:


Isso nos fornecerá os seguintes dados:

Id do álbum (_ d)

Título do álbum (_ t)

Track id

Título da faixa (_ t)

1

Albumina 1

1

Faixa 1

1 Albumina 1 2 track2
2 Albumina m2 ar ar

Esses dados devem ser convertidos em uma resposta JSON com a seguinte estrutura:


Descobrimos que a maior parte do tempo de processamento da solicitação é gasta na função de conversão (ela converte o resultado SQL em uma resposta JSON). Depois de tentar algumas maneiras de otimizar a função de conversão, decidimos remover esta função empurrando a conversão para o Postgres. Postgres 9.4 (lançado aproximadamente quando o primeiro microsserviço de dados foi lançado) adicionou funções de agregação JSON, o que nos ajudou a avançar na conversão para Postgres. O SQL gerado se tornará semelhante a:


该查询的结果将有一列和一行,并且该值被发送到客户端,无需任何进一步的转换。 从我们的基准测试来看,这种方法大约比哈斯克尔的转换函数快3-6倍。

根据查询的嵌套级别和使用的条件,生成的SQL语句可能非常大而且复杂。 通常,任何前端应用程序都有一组用不同参数重复的查询。 例如,上述查询可以针对2017年而不是2018年执行。 准备好的语句最适合这些用例。当你有复杂的SQL语句时,这些语句会随着一些参数的改变而重复。

因此,第一次执行这个GraphQL查询时:


我们准备了SQL语句,而不是直接执行它,所以生成的SQL将是(注意$1):

接下来执行这个准备好的语句:

当GraphQL查询更改为2017年时,我们只需直接执行准备好的语句:

根据GraphQL查询的复杂程度,这大致可以使我们提高10-20% .

Haskell非常适合各种原因:

  • 具有出色性能的编译语言(本)
  • 高效能的HTTP堆栈(warp,warp的体系结构)
  • 我们之前使用该语言的经验

高效能的HTTP堆栈(翘曲,翘曲的体系结构(
这是Hasura的建筑与Prisma和Postgraphile的比较。

数据库实时同步

我们之前使用该语言的经验

  1. 8GB RAM,i7笔记本电脑
  2. Postgres在同一台机器上运行
  3. wrk被用作基准测试工具,并且针对不同类型的查询,我们尝试“每秒”最大化请求
  4. 查询Hasura GraphQL引擎的单个实例
  5. 连接池大小:50
  6. 数据集:chinook

查询1:tracks_media_some


  • 每秒请求数:1375 req / s
  • 5毫秒
  • 30%
  • 30MB(Hasura)+ 90MB(Postgres)

查询2:tracks_media_all


  • 每秒请求数:410 req / s
  • 延迟时间:59毫秒
  • 查询1:轨道_媒体_部分100%
  • 每秒请求数:1375次请求/秒每秒请求数:410次请求/秒

查询3:album_tracks_genre_some


  • 每秒请求数:1029 req / s
  • 延迟时间:24ms
  • 30%
  • 30%30MB(Hasura)+ 90MB(Postgres)

查询4:album_tracks_genre_all


  • 每秒请求数:328 req / s
  • CPU:100%
  • 30MB(Hasura)+ 130MB(Postgres)

Acho que você gosta

Origin blog.csdn.net/weixin_49470452/article/details/107506394
Recomendado
Clasificación