Como lidar com consultas de mais de 500 milhões de itens

8

A estrutura dos meus dados é a seguinte:

date: <timestamp>
filter_a: <integer> -> range [0, 1000]
filter_b: <integer> -> range [0, 1000]
filter_c: <integer> -> range [0, 86400]
filter_d: <integer> -> range [0, 6]
group: <string>
second_group: <integer>
variable_a: <float>
variable_b: <float>
variable_c: <float>
a couple more no very important

Preciso executar as seguintes consultas:

Primeiro:

  • Filtrar dados date, filter_a, filter_b, filter_ce outros

Segundo, com os dados filtrados:

  • conte todos os registros
  • obter média de variable_a, variable_bevariable_c
  • obter desvio padrão de variable_a, variable_bevariable_c
  • obter quartis de variable_a, variable_bevariable_c
  • agrupar dados por groupou second_groupagregados (Contagem, Média, Padrão, ..)

O número de usuários do sistema é cerca de 10 ou 15, mas o número de itens é enorme, agora é 70M mas será 500M em um par de semanas e será 1000M em cerca de um ano.

O número de consultas é pequeno, não mais que 10 usuários simultaneamente, meu problema é como lidar com essas consultas com essa enorme quantidade de dados.

O que eu tentei até agora?

  • Comecei com mongodb, no início, era rápido, mas ficou lento ao calcular quartis com 10M +. Melhorou quando adicionei índices, mas não ajudou muito quando tive que consultar todos os dados. Comecei a usar o mongodb porque os dados eram muito dinâmicos, mas felizmente o formato dos dados "não muda mais".

  • Como filter_ae filter_bpoderia ser visto como nós, tentei neo4j. Eu gostei muito do neo4j, mas meu gráfico tinha muitas arestas para que as consultas não fossem muito rápidas.

  • Finalmente, como o formato dos dados não vai mudar e é apenas uma coleção / tabela, portanto não precisa de junções no SQL, verifiquei o postgresql. Meus testes foram mais rápidos com o postgresql, mas estou com medo de que não possa ser dimensionado adequadamente no futuro.

O que eu preciso?

  • O postgresql é uma boa escolha para este caso?
  • Existe outro tipo de banco de dados que eu poderia usar? qual é o melhor para este caso?
  • O que mais eu poderia fazer para melhorar isso?

Editar

  • Cerca de 1 milhão de elementos são inseridos todos os dias e "não devem mudar" ao longo do tempo.
  • Velocidade de gravação não é importante
  • O requisito difícil é ler / agregar rapidamente

Obrigado!

Andres
fonte
11
Que tal exibições indexadas no SQL Server / exibições metastizadas no Oracle? Esses são um agregado em execução da tabela base. Assim, conforme a tabela base é modificada, o índice também é modificado em tempo real. Em seguida, você sempre pode consultar agregados já calculados para você.
Ali Razeghi
As visualizações indexadas do @AliRazeghi são uma boa ideia. Enfim primeiro quero escolher o melhor banco de dados / design antes de otimizar consultas em si
Andres
11
Por otimizar puramente no Postgres, quero dizer que os índices BRIN podem ajudar aqui, mas não fiz nada além de ler sobre eles. postgresql.org/docs/9.5/static/brin-intro.html
Erik Darling
11
Pessoalmente, herdei um banco de dados de relatórios de várias bilhões de linhas em um servidor OLTP sem muita quantidade de memória. Felizmente, as partes mais consultadas foram as "últimas 3 semanas", mas as varreduras de tabela não eram inéditas. Honestamente, usando muito boa compactação, particionamento, eliminação de partições, esquema de particionamento, otimizações de cache da SAN e remoção de índices não utilizados, obtivemos um desempenho muito bom no MS SQL 2008 Ent. 1 bilhão não será muito difícil para o PGSQL. Qual a largura de cada linha ou aproximadamente quanto espaço você acha que cada linha terá e quantos índices haverá por tabela ou processo de entrada?
Ali Razeghi 29/08/16
2
@Andres bem, isso depende de qual mecanismo db está e qual é o tamanho máximo de cada linha para que possamos calcular. Por exemplo, o PostgreSQL possui varchar e apenas char, char é fácil de calcular, varchar teríamos que adivinhar o tamanho médio. Se pudéssemos saber quais são os tipos de campos (a menos que seja Mongo ou algo que os armazene em um documento com seu próprio formato), aproximadamente quantos caracteres esperamos em cada um e número de índices com as colunas. Parece que 8 GB de RAM seria muito baixo para retirá-lo da memória com eficiência, especialmente se essa RAM for compartilhada com outras tabelas e recursos no servidor.
Ali Razeghi

Respostas:

5

Em vez de recorrer a um banco de dados relacional para executar esses cálculos estatísticos em dados de séries temporais, sugiro que você mova esse trabalho de matemática e pós-processamento para fora do banco de dados em um aplicativo cliente.

Usando uma linguagem de script como Python ou Ruby, você pode resolver o problema de maneira incremental consultando "blocos" de dados por um período de largura fixa, calculando um resumo estatístico intermediário e combinando os resultados em vários blocos, conforme você executa o loop ao longo de toda a história. É difícil combinar algumas medidas estatísticas entre os pedaços, mas algo como Avg () só precisa de soma () e contagem () por pedaço, O (1) vs. O (tamanho do pedaço), portanto, a mesclagem de pedaços pode ser bem dimensionada.

Jpierc
fonte
Eu tentei algo assim usando python / pandas . o cálculo foi mais rápido (alguns segundos), mas a recuperação de todos os dados foi lenta. Talvez um melhor chunksizepoderia ajudar. +1
Andres
1

Como seus dados não mudam e são apenas anexados, eu os armazenaria onde você quiser; Amazon S3, por exemplo, mas qualquer banco de dados de leitura rápida estará ok. Sem índices. O banco de dados / FS escolhido deve ter a opção de ler os dados nos buckets: você pode ter, por exemplo, um arquivo por dia com seus registros de 1 milhão.

Então eu usaria o Spark para fazer a filtragem / análise. É baseado em cluster, você pode dimensioná-lo de acordo com suas necessidades.

Leo
fonte
Concordo, já tenho meu conjunto de dados separado por dia. Eu também estava pensando em HDFS e HBase
Andres
0

A resposta depende da maneira como você usará os dados depois disso. Se para processar melhor, use Cassandra, se para análise, use melhor o Hive.

Artemy Prototipagem
fonte
Entendi que a colméia não poderia ser a melhor escolha real time. Estou errado?
Andres
11
Sim, o HBase é para leitura / gravação em tempo real. Mas Cassandra também pode fazer o mesmo. Mas acho que o HBase é melhor.
Artemy Prototipagem
0

Esse tipo de situação é ideal para data warehousing, usando as técnicas aperfeiçoadas por Ralph Kimball e companhia, em plataformas como o SQL Server (aquela com a qual estou mais familiarizado). Eles foram projetados especificamente com esse tipo de cenário em mente: grandes quantidades de registros de dados relativamente estáticos, para os quais você precisa calcular agregados desse tipo. Nãoa técnica relacional corresponderá ao armazenamento de dados implementado adequadamente em aplicativos desse tipo, embora alguns certamente sejam melhores que outros se sua organização simplesmente não puder pagar as licenças dos pacotes de software (como o SQL Server Analysis Services) que os implementam. Há também uma curva de aprendizado para implementar linguagens como MDX, feitas sob medida para esse tipo de acesso a dados. Se o armazenamento de dados for uma opção viável para sua organização, não perca tempo procurando uma solução relacional; este não é um problema de banco de dados relacional. Posso postar algumas referências básicas ao Kimball etc., e links para SSAS e MDX (desculpe, não posso ajudar com a Oracle e outros concorrentes com os quais não estou familiarizado), se necessário. Espero que ajude.

SQLServerSteve
fonte