Conjunto de dados geoespaciais grandes (> 22 trilhões de itens) com desempenho de consulta rápida (<1s)

20

Estou no processo de projetar um novo sistema para um grande conjunto de dados geoespaciais que exigirá um desempenho rápido da consulta de leitura. Portanto, quero ver se alguém pensa que é possível ou tem experiência / aconselhamento sobre DBMSs, estrutura de dados ou métodos alternativos adequados para obter o desempenho necessário na seguinte situação:

Os dados serão produzidos continuamente a partir de dados de radar de satélite processados, que terão cobertura global. Com base na resolução de satélites e cobertura terrestre do mundo, eu estimo o conjunto completo de dados para produzir valores em 75 bilhões de locais distintos no mundo. Durante a vida útil de um único satélite, a saída produzirá até 300 valores em cada um desses locais (portanto, um conjunto de dados total de> 22 trilhões de valores). Isto é para um satélite, e já existe um segundo em órbita, com outros dois planejados nos próximos anos. Portanto, haverá muitos dados! Um único item de dados é muito simples e consistirá apenas em (longitude, latitude, valor), mas devido ao número de itens, estimo um único satélite para produzir até 100 TB.

Os dados escritos nunca precisam ser atualizados, pois só crescerão à medida que novas aquisições de satélite forem processadas. O desempenho de gravação não é importante, mas o desempenho de leitura é crucial. O objetivo deste projeto é poder visualizar os dados por meio de uma interface simples, como uma camada sobre o google maps, onde cada ponto tem um valor colorido com base em sua média, gradiente ou alguma função ao longo do tempo. (demonstração no final da postagem).

A partir desses requisitos, o banco de dados precisa ser escalável e é provável que procuremos soluções em nuvem. O sistema precisa ser capaz de lidar com consultas geoespaciais, como "pontos próximos (lat, lon)" e "pontos dentro (caixa)", e ter desempenho de leitura de <1s para localizar um único ponto e polígonos que contêm até 50.000 pontos (embora até 200.000 pontos sejam preferíveis).

Até agora, tenho um conjunto de dados de teste de ~ 750 milhões de itens de dados em 111 milhões de locais. Eu testei uma instância postgres / postGIS, que funcionou bem, mas sem a possibilidade de fragmentação, não será possível lidar com o aumento dos dados. Também tentei uma instância mongoDB, que novamente parece OK. até agora, e com o sharding, pode ser suficiente escalar com o volume de dados. Recentemente, aprendi um pouco sobre elasticsearch, portanto, qualquer comentário sobre isso seria útil, pois é novo para mim.

Aqui está uma rápida animação do que queremos alcançar com o conjunto completo de dados: Tileserver exibindo 750 milhões de itens de dados.

Este gif (do meu teste do postgres) está servindo (6x3) blocos raster pré-computados, cada um contendo ~ 200.000 pontos e ~ 17s para gerar cada um. Ao clicar em um ponto, o gráfico é elaborado puxando todos os valores históricos no local mais próximo em <1s.

Desculpas pelo longo post, todos os comentários / conselhos são bem-vindos.

Azwok
fonte

Respostas:

4

Você pode fragmentar por localização. Particione o globo em uma grade e tenha cada quadrado nessa grade em um servidor. Como você mencionou a nuvem, isso seria adequado para a nuvem. É claro que você precisará mesclar manualmente os resultados de vários servidores.

Dessa forma, você pode usar qualquer solução de banco de dados que desejar. Não precisa ser escalável por si só.

Os quadrados individuais terão diferentes quantidades de dados. Você pode usar máquinas de tamanhos diferentes para elas (já que isso é nuvem) ou colocar vários pequenos fragmentos na mesma máquina.

Esse esquema de sharding é ótimo para o tipo de consultas que você executa, pois cada consulta precisará apenas tocar em muito poucos shards. O sharding por tempo é pior porque todos os shards de tempo devem ser tocados para cada consulta. A fragmentação aleatória tem o mesmo problema.

Em resumo, esse é um caso fácil de compartilhamento, porque o padrão de consulta se encaixa muito bem no esquema de compartilhamento.

Na verdade, eu me pergunto se você precisa de um banco de dados para isso. Talvez você possa particionar o globo em blocos de 1000 x 1000 ou menores e ter um arquivo simples no armazenamento de blob para cada bloco. O armazenamento de blobs não se importa com 1 milhão de blobs.

A execução de uma consulta é conceitualmente muito fácil com esse esquema de armazenamento. Você também pode armazenar os dados de forma redundante em várias resoluções de grade.

usr
fonte
O sharding por região é a abordagem que eu tenho observado com o MongoDB e, com o lançamento oportuno do MongoDB Atlas, atualmente estou inclinado nessa direção (usando valores agregados pré-calculados). No momento, não tenho certeza de quantos servidores de réplica / shard eu precisaria, portanto, o custo pode se tornar um problema. Sua proposta de usar o armazenamento BLOB também é interessante e você é a segunda pessoa a propor. No entanto, o uso de BLOBs é completamente novo para mim; portanto, preciso ler mais sobre isso, todas as fontes úteis que você conhece? Obrigado pela resposta.
Azwok
Blobs são triviais de usar. A complexidade surgirá da necessidade de implementar recursos do banco de dados, como serialização, consultas, transações, backups, HA, DA. Tudo isso é possível, mas talvez não seja sensato. Talvez você possa armazenar os blobs em uma tabela do Postgres. Isso automatiza tudo isso, exceto serialização e consulta. O Perf pode ser melhor que o armazenamento de blob e talvez seja ainda mais barato. Blobs e VMs não são cobrados pelo custo, eles têm uma boa margem (prova: meu webhoster local cobra 3-5x menos pela mesma energia de computação que a nuvem. Isso implica em altas margens de nuvem).
usr
Observe que você pode executar vários shards na mesma instância do mongo. Você pode "exagerar". Dessa forma, você pode equilibrar os servidores.
usr
11
Não sei se você precisa de recursos espaciais. Você pode calcular tudo isso no aplicativo. Você só precisa consultar todos os dados para um retângulo. Isso pode ser feito dividindo manualmente o globo em uma grade (ou várias grades de resolução). Seu banco de dados não precisa suportar espacial, eu acho.
usr
8

Qual é a atualização das suas consultas de leitura?

Você pode particionar o banco de dados por tempo, se o mapa precisar apenas mostrar a medida mais recente. Isso reduziria sua carga de consulta para o mapa.

Para a história de um determinado ponto, você pode armazenar uma segunda loja por xey mostrando a história. Isso pode ser feito com uma atualização / atualização noturna, pois os dados históricos não serão alterados.

Em seguida, você pode pré-calcular médias em resoluções mais grosseiras para integrar com mapas em diferentes níveis de zoom. Isso reduziria o número de pontos a serem recuperados para grandes áreas do mapa (menos zoom). Resoluções mais finas seriam usadas para mapas mais ampliados que estavam consultando áreas menores. Se você realmente precisar acelerar isso, poderá calcular blocos como blobs e interpretá-los em seu aplicativo.

Como isso envolveria uma nova computação de informações agregadas, haveria alguma latência nos resultados da consulta. Dependendo da latência aceitável, você pode usar esse tipo de abordagem para otimizar suas leituras.

OK, então seus pontos precisam ser calculados como médias ao longo do tempo. Com esse cálculo, acho que suas consultas reais diminuem bastante de 22 trilhões de itens, pois os valores rasterizados podem ser pré-calculados para consulta.

ConcernedOfTunbridgeWells
fonte
As consultas de leitura podem ter um pouco de atraso (um dia ou dois), portanto, o processamento em lote é uma opção válida. Em qualquer local, um novo valor será adicionado apenas a cada 6 dias o mais rápido (o próximo passe por satélite). A saída no mapa não é apenas o valor mais recente, é calculada com base em todo o histórico de valores nesse local, por exemplo, é média, gradiente ou uma função personalizada. Para níveis com menos zoom, já estou trabalhando em uma estrutura de cluster / pirâmide para que eu tenha uma tabela / coleção com valores médios para que nenhum bloco (consulta) tenha> 200.000 (ou 50.000) itens de localização.
Azwok
Eu acho que o pré-cálculo de agregados é a chave - seus cálculos temporais ainda podem ser agrupados. É assim que os sistemas OLAP obtêm desempenho rápido de consulta e você provavelmente precisará adotar esse tipo de abordagem. Especialmente relevante se você pode conviver com dados com um dia de duração para suas consultas.
ConcernedOfTunbridgeWells
Se você estiver consultando valores médios calculados, em quais locais distintos você está colhendo amostras - ou seja, qual é a resolução do bitmap real no nível mais alto de zoom?
ConcernedOfTunbridgeWells
Concordo que agregados pré-calculados parecem muito provavelmente o caminho a percorrer. As médias calculadas com o zoom mais alto não são calculadas sobre uma área, é a média dos valores ao longo do tempo em 1 local. Somente à medida que diminui o zoom, terei tabelas / coleções separadas que calcularão áreas médias para garantir que nenhuma consulta / bloco possua muitos pontos de localização (no máximo 50.000-200.000). A resolução máxima de qualquer bloco é 256x256 pixels.
Azwok
3

Parece que existem duas classes de consulta - uma para entender quais locais estão na janela de exibição atual e uma segunda para fornecer a estatística desejada para esses pontos. Minha sugestão é usar ferramentas especializadas e separadas para cada um.

Estou assumindo que todas as medições estão relacionadas ao mesmo conjunto de pontos de 75Bn. Esses lat / longs, uma vez estabelecidos, são, portanto, estáticos. Eles podem ser agrupados, agregados e indexados a um custo único. Portanto, eu sugeriria sharding por região e nível de zoom. O tamanho de cada shard será determinado pelo desempenho que pode ser alcançado em cada instância do GIS.

O GIS retornará um conjunto de pontos que são passados ​​para um banco de dados de séries temporais. Isso mantém os valores medidos e executa agregados. O KDB é um que eu conheço. Ele tem como alvo a negociação de valores mobiliários, que terá menos chaves, mas mais pontos de dados por chave do que o seu cenário.

Haverá um custo para transferir os valores-chave do servidor GIS para o banco de dados de séries temporais. Minha hipótese é que esse custo será pago pelo processamento mais rápido no banco de dados de séries temporais específicas da tarefa. Pela redação da pergunta, parece que uma única instância não será capaz de armazenar todos os dados; portanto, algum tráfego entre servidores parece inevitável. Dada a velocidade relativa dos componentes, parece provável que o envio de um conjunto de chaves para um servidor remoto com os dados armazenados em cache seja mais rápido do que a leitura dos dados no disco local.

Se as partes para encontrar pontos e calcular valores podem ser locais entre si, é claro que eu esperaria que a resposta fosse mais rápida. Meu entendimento (limitado) é que encontrar os N vizinhos mais próximos de um determinado ponto é uma tarefa não trivial. É por isso que sugeri usar software específico para executá-lo. Se a descoberta de pontos puder ser reduzida para

where latitude between x1 and x2
and logitude between y1 and y2

então essa parte poderia ser tratada pelo software de armazenamento de valor e o GIS eliminado da arquitetura.

Eu não implementei esse sistema. Estou realmente pensando alto aqui. Na escala de petabytes, não existem soluções prontas para uso. No entanto, existem muitos provedores de dados via satélite, portanto seu problema é tratável. Boa sorte.

Michael Green
fonte
Concordado, existem duas classes. 1) faça uma imagem dos valores únicos de muitos locais, 2) obtenha todos os valores históricos em um local. Todas as medidas estão relacionadas aos mesmos bilhões de locais, a única alteração será o número de valores históricos em cada ponto. A fragmentação por região é a abordagem que estou adotando, pelas razões que você declarou. Eu não tinha pensado em passar os valores retornados para um banco de dados separado da série temporal. Eu pensaria que a seleção e a transferência para um banco de dados de séries temporais adicionariam muito tempo para tornar essa opção viável, a menos que eu não entendesse sua proposta.
Azwok