Quais são as minhas opções para armazenar e consulta enormes quantidades de dados, onde um monte de que está se repetindo?

StackOverflow https://stackoverflow.com/questions/416432

Pergunta

Estou avaliando opções para armazenamento de dados eficiente em Java. O conjunto de dados são os valores de dados em tempo carimbado com uma chave primária chamada. por exemplo.

Name: A|B|C:D
Value: 124
TimeStamp: 01/06/2009 08:24:39,223

Pode ser um preço das ações em um determinado ponto no tempo, por isso é, suponho, um padrão de dados de séries temporais clássico. No entanto, eu realmente preciso de uma solução RDBMS genérico que irá trabalhar com qualquer banco de dados compatível razoável JDBC como eu gostaria de usar Hibernate. Consequentemente, as extensões de séries temporais para bancos de dados como Oracle não são realmente uma opção como gostaria que o implementador de ser capaz de usar seu próprio banco de dados capaz JDBC / Hibernate.

O desafio aqui é simplesmente o enorme volume de dados que podem se acumular em um curto período de tempo. Até agora, meus implementações estão focados em torno de definir horários cumulativos e purga periódicas onde os dados brutos são agregadas em dia, semana, mês, etc tabelas, mas a desvantagem é a perda precoce de granularidade ea ligeira inconveniência de incompatibilidades período entre períodos armazenados em diferentes agregados.

O desafio tem opções limitadas uma vez que há um limite absoluto para a quantidade de dados pode ser fisicamente comprimido, mantendo a granularidade original dos dados, e este limite é exacerbado pela directiva de usar um banco de dados relacional e um JDBC genérico capaz naquele.

Emprestando um conceito teórico de algoritmos de compressão de dados clássicos, e aproveitando o fato de que muitos valores consecutivos para a mesma chave chamada pode esperado para ser idênticos, eu estou querendo saber se existe maneira que eu possa reduzir facilmente o número de registros armazenados por conflating repetindo valores em uma linha lógica, enquanto também armazenar um contador que indica, de forma eficaz "a próxima n registros têm o mesmo valor". A implementação de apenas que parece bastante simples, mas o off trade é que o modelo de dados é agora terrivelmente complicado para consulta contra o uso de SQL padrão, especialmente quando se usa qualquer tipo de funções SQL agregadas. Isto reduz significativamente a utilidade do armazenamento de dados uma vez que apenas código personalizado complexo pode restaurar a parte de trás de dados para um estado "descomprimido" resultando em uma diferença de impedância com centenas de ferramentas que não será capaz de tornar esses dados corretamente.

Eu considerei a possibilidade de definir personalizados tipos Hibernate que seria basicamente "entender" o conjunto de dados compactados e explodi-lo de volta e os resultados da consulta de retorno com as linhas sintéticos criados dinamicamente. (A base de dados vai ser lido apenas para todos os clientes, excepto o fluxo de entrada bem controlada). Várias das ferramentas que eu tinha em mente irá se integrar com Hibernate / POJOs Além de matérias-JDBC (eg. JasperReports) Mas isso realmente não abordar as funções de agregação emitir e, provavelmente, tem um monte de outras questões também.

Então, eu sou parte maneira de me resignar, possivelmente, ter que usar um mais proprietária armazenamento de dados [possivelmente não-SQL] (todas as sugestões apreciado) e, em seguida, concentrar-se na possivelmente menos complexa tarefa de escrever um driver JDBC pseudo a pelo menos facilitar a integração com ferramentas externas.

Eu ouvi referência a algo chamado de " mordeu arquivo compactado " como um mecanismo para alcançar este compressão de dados, mas eu não sei de qualquer banco de dados que fornecem este ea última coisa que eu quero fazer (ou pode fazer, realmente ....) é escrever o meu próprio banco de dados.

Qualquer sugestão ou insight?

Foi útil?

Solução

Eu olhava para um orientada coluna de banco de dados . Seria ótimo para esse tipo de aplicação

Outras dicas

Hibernate (ou qualquer solução JPA) é a ferramenta errada para este trabalho.

JPA / Hibernate não é uma solução leve. Em aplicações de alto volume, a sobrecarga é não só significativo, mas proibitivo. Você realmente precisa olhar para soluções de redes e clusters . Não vou repetir a visão geral das diversas tecnologias aqui.

Eu tenho um monte de experiência em sistemas de informação sobre o mercado financeiro. A algumas das coisas que você disse presos para mim:

  • Você tem um monte de dados brutos;
  • Você deseja aplicar várias agregações para que os dados (por exemplo, aberto / Alto / Baixo / fechar resumos diários);
  • A alta disponibilidade é provavelmente um problema (que é sempre nestes tipos de sistemas); e
  • Baixa latência é provavelmente um problema (idem).

Agora, para soluções tipo grade / cluster eu dividi-los livremente em duas categorias:

  1. soluções como Coerência ou Terracotta Mapa baseada-; e
  2. JavaSpaces baseada em soluções como GigaSpaces.

Eu usei Coerência muito e a solução Mapa pode ser bom, mas pode ser problemático também. mapas de coerência pode ter ouvintes sobre eles e você pode usar esse tipo de coisa para fazer coisas como:

  • Mercado alertas de preços (os usuários podem querer uma notificação quando um preço atinge um determinado nível);
  • preços Derivative (por exemplo, um sistema de precificação de opções negociados em bolsa vai querer Reprice quando um segurança subjacente muda último preço negociado);
  • A troca de correspondência / sistema de reserva pode querer corresponder notificações comerciais recebidos para fins de reconciliação;
  • etc.

Tudo isso pode ser feito com os ouvintes, mas em coerência por exemplo ouvintes tem que ser barato, o que leva a coisas como um mapa em que um ouvinte do que escritas de algo para outra Mapa e esta cadeia lata por algum tempo. Além disso, modificando a entrada de cache pode ser problemático (embora existam mecanismos para lidar com esse tipo de problema também, eu estou falando sobre situações como desligar o alerta de preço de mercado para que ele não desencadear uma segunda vez).

Eu encontrei soluções de redes tipo GigaSpaces ser muito mais convincente para este tipo de aplicação. A operação de leitura (ou leitura destrutiva) é uma solução altamente elegante e escalável e você pode obter atualizações de grade transacionais com desempenho sub-milissegundo.

Considere as duas arquiteturas filas clássicas:

  • Request / Response: uma mensagem ruim pode bloquear a fila e enquanto puder muitos emissores e receptores (para escalabilidade) Ampliação do número de tubos nem sempre é simples; e
  • Publicação / Assinatura:. Este desacopla o emissor eo receptor, mas carece de escalabilidade em que se você tiver vários assinantes vão receber cada mensagem (não necessariamente o que você quer dizer com um sistema de reserva)

Em GigaSpaces, uma leitura destrutiva é como um sistema de publicação-assinatura escalável e uma operação de leitura é como o tradicional modelo de publicação-assinatura. Há um mapa e JMS aplicação construída em cima da grade e pode fazer FIFO ordenação.

Agora whaqt sobre persistência eu ouço você perguntar? A persistência é uma consequência de decidir todas as outras coisas. Para este tipo de aplicação, eu como a Persistência as a Service modelo (ironicamente escrito sobre Hibernate mas aplica-se a qualquer coisa).

Basicamente, isto significa a sua data de lojas sucessos são assíncronas e ele funciona muito bem com a realização de dados de resumo. Como você pode ter uma escuta serviço para notificações comerciais e persistem apenas os que está interessado em (agregando na memória se necessário). Você pode fazer aberto / alto / baixo / preços próximos desta forma.

Para dados de alto volume que você realmente não quer escrever tudo à base de dados.Não síncrona de qualquer maneira. Um armazenamento persistente além de um armazém de dados é provavelmente mais a rota que você quer ir, mas novamente isso depende de requisitos, volumes, etc.

É um assunto complicado e eu só realmente touche vesti-lo. Espero que ajude você.

Você provavelmente vai achar que é interessante ouvir a apresentação Michael Stonebraker em dinheiro: Tech . Ele bate em um número de coisas que você menciona que necessitam e ele ilustra como as três grandes elefantes (SQL Server, Oracle e DB2) nunca será capaz de acordo com as necessidades de lojas de carrapatos (que parece que você está construindo). Ele cava além lojas de coluna, que eu concordo é a direção certa. Ele ainda discute compressão e velocidade, que são ambos problemas para você.

Aqui estão alguns links que você pode achar interessante:

Muitos sistemas de gerenciamento de banco de dados JDBC-capable (por exemplo, Oracle) oferecem compressão no motor de armazenamento físico. Oracle, por exemplo, tem a noção de uma mesa "comprimido", sem sobrecarga de descompressão:

http: //www.ardentperf .com / wp-content / uploads / 2007/07 / avançado de compressão datasheet.pdf

Obrigado pelas respostas.

Cletus, eu aprecio o contorno, mas uma das compensações não posso fazer é abandonar DB flexibilidade e compatibilidade com JDBC / Hibernate para permitir o uso de todas as ferramentas disponíveis. Além disso, embora eu não indicar claramente isso, eu não quero forçar meus usuários a adotar uma solução comercial [possivelmente caro]. Se eles têm banco de dados Brand X, deixá-los usá-lo. Se eles não se importam, recomendamos open source de banco de dados Marca Y. Basicamente, a aplicação tem várias faces, um deles sendo um repositório de dados de entrada, mas uma outra face é uma fonte de informação e eu realmente don 't quer entrar no negócio de escrever geradores de relatório.

Enquanto eu realmente não carregue testado ainda, estou muito impressionado com LucidDB . É um banco de dados orientado coluna e fornece bom desempenho de consulta e aparentemente boa compressão de dados. Ele tem um driver JDBC que não existe nenhum dialeto Hibernate para isso ainda, tanto quanto eu posso dizer. Ele também suporta transformações definidas pelo usuário, que em suma, eu acho que vai permitir-me a implementar perfeitamente a minha ideia de comprimir repetindo e valores consecutivos em uma "linha", mas explodi-los de volta para várias linhas "sintéticos" na consulta tempo, tudo feito de forma invisível para o chamador consulta. Por fim, ele suporta esse recurso bacana de tabelas estrangeiras onde outras tabelas do banco de dados de suporte JDBC pode ser fachada em LucidDB. Acho que isso pode ser inestimável para fornecer algum nível de suporte para outros bancos de dados.

Obrigado pelo ponteiro, Javaman. Ele me zoneada dentro em LucidDB.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top