Какие есть варианты для хранения и запроса огромных объемов данных, где их многократно повторяется? - PullRequest
4 голосов
/ 06 января 2009

Я оцениваю варианты эффективного хранения данных в Java. Набор данных представляет собой значения данных с меткой времени и именованным первичным ключом. например,

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

Может быть цена акций в определенный момент времени, так что, я полагаю, это классический шаблон данных временных рядов. Однако мне действительно нужно общее решение для СУБД, которое будет работать с любой разумной JDBC-совместимой базой данных, поскольку я хотел бы использовать Hibernate. Следовательно, расширения временных рядов для таких баз данных, как Oracle, на самом деле не вариант, так как я бы хотел, чтобы разработчик мог использовать свою собственную базу данных с поддержкой JDBC / Hibernate.

Проблема здесь заключается в огромном объеме данных, которые могут накапливаться за короткий промежуток времени. До сих пор мои реализации были сосредоточены на определении периодических сводных и чистящих графиков, где необработанные данные агрегируются в таблицы DAY, WEEK, MONTH и т. Д., Но недостатком является ранняя потеря гранулярности и небольшое неудобство несовпадений периодов между периодами, хранящимися в разных агрегаты.

Задача имеет ограниченные возможности, поскольку существует абсолютный предел того, сколько данных может быть физически сжато при сохранении исходной гранулярности данных, и этот предел усугубляется директивой об использовании реляционной базы данных и универсального JDBC, способного один в этом.

Заимствуя концептуальную концепцию из классических алгоритмов сжатия данных и используя тот факт, что многие последовательные значения для одного и того же именованного ключа могут быть идентичными, мне интересно, если есть способ, которым я могу плавно уменьшить количество хранимых записей путем объединения повторяя значения в одну логическую строку, сохраняя при этом счетчик, который фактически указывает, что «следующие n записи имеют одинаковое значение». Реализация всего этого кажется достаточно простой, но компромисс в том, что модель данных теперь ужасно сложна для запроса с использованием стандартного SQL, особенно при использовании любого вида агрегатных функций SQL. Это значительно снижает полезность хранилища данных, поскольку только сложный пользовательский код может восстановить данные обратно в «распакованное» состояние, что приводит к несоответствию импеданса сотням инструментов, которые не смогут правильно обработать эти данные.

Я рассмотрел возможность определения пользовательских типов Hibernate, которые в основном "понимали бы" сжатый набор данных, создавали его и возвращали результаты запроса с динамически созданными синтетическими строками. (База данных будет доступна только для всех клиентов, кроме строго контролируемого потока ввода). Некоторые из инструментов, которые я имел в виду, будут интегрироваться с Hibernate / POJOS в дополнение к сырому JDBC (например, JasperReports), но это на самом деле не решает проблему с агрегатными функциями и, вероятно, также имеет кучу других проблем.

Таким образом, я отчасти смиряюсь с тем, что мне, возможно, придется использовать более проприетарное хранилище данных [возможно, не-SQL] (любые предложения приветствуются), а затем сосредоточиться на, возможно, менее сложной задаче написания псевдо-драйвера JDBC, по крайней мере, облегчить интеграцию с внешними инструментами.

Я слышал ссылку на нечто, называемое " битовый файл ", в качестве механизма для достижения этого сжатия данных, но я не знаю ни одной базы данных, которая обеспечивает это, и последнее, что я хочу сделать ( или может сделать, действительно ....) это написать свою собственную базу данных.

Есть предложения или идеи?

Ответы [ 5 ]

4 голосов
/ 06 января 2009

Hibernate (или любое решение JPA) является неправильным инструментом для этой работы.

JPA / Hibernate не является легким решением. В приложениях большого объема накладные расходы не только значительны, но и чрезмерны. Вам действительно нужно изучить сетку и кластерные решения . Я не буду повторять обзор различных технологий здесь.

У меня большой опыт работы с информационными системами финансового рынка. Несколько вещей, которые ты сказал, показались мне:

  • У вас много необработанных данных;
  • Вы хотите применить различные агрегации к этим данным (например, открыть / максимум / минимум / закрыть дневные сводки);
  • Высокая доступность, вероятно, является проблемой (она всегда есть в таких системах); и
  • Низкая задержка, вероятно, является проблемой (так же).

Теперь для решений типа сетки / кластера я делю их свободно на две категории:

  1. Решения на основе карт, такие как Coherence или Terracotta; и
  2. Решения на основе Javaspaces, такие как GigaSpaces.

Я часто использовал Coherence, и решение Map может быть хорошим, но оно также может быть проблематичным. На картах когерентности могут присутствовать слушатели, и вы можете использовать такие вещи, как:

  • оповещения о рыночной цене (пользователям может потребоваться уведомление, когда цена достигнет определенного уровня);
  • Производное ценообразование (например, система ценообразования на биржевых опционах захочет сделать переоценку при изменении базовой ценной бумаги последней торгуемой цены);
  • Система сопоставления сделок / бронирования может захотеть сопоставлять полученные торговые уведомления для целей сверки;
  • и т.д.

Все это может быть сделано с помощью слушателей, но, например, в Coherence, слушатели должны быть дешевыми, что приводит к тому, что у таких объектов, как Map, есть слушатель, а не что-то записывается в другую Map, и это может цепляться некоторое время. Кроме того, изменение записи в кеше может быть проблематичным (хотя существуют механизмы для решения этой проблемы; я говорю о таких ситуациях, как отключение оповещения о рыночной цене, чтобы оно не срабатывало во второй раз).

Я обнаружил, что сеточные решения типа GigaSpaces гораздо более привлекательны для такого рода приложений. Операция чтения (или деструктивного чтения) является очень элегантным и масштабируемым решением, и вы можете получать транзакционные обновления сетки с производительностью менее миллисекунды.

Рассмотрим две классические архитектуры очередей:

  • Запрос / ответ: плохое сообщение может заблокировать очередь, и, хотя вы можете использовать много отправителей и получателей (для масштабируемости), увеличение количества каналов не всегда просто; и
  • Опубликовать / подписаться: это разъединяет отправителя и получателя, но ему не хватает масштабируемости, так как если у вас несколько подписчиков, каждый из них получит сообщение (не обязательно то, что вы хотите, скажем, с помощью системы бронирования).

В GigaSpaces деструктивное чтение похоже на масштабируемую систему публикации-подписки, а операция чтения - как традиционная модель публикации-подписки. Существует реализация Map и JMS, построенная поверх сетки, и она может выполнять упорядочивание FIFO.

Теперь о настойчивости, я слышал, вы спрашиваете? Упорство является следствием решения всех других вещей. Для такого рода приложений мне нравится модель Persistance as a Service (по иронии судьбы написанная о Hibernate, но она применима ко всему).

По сути, это означает, что ваши обращения к хранилищу данных являются асинхронными, и это прекрасно работает с сводными данными. Как и у вас может быть сервис, прослушивающий торговые уведомления и сохраняющий только те, которые ему интересны (агрегирование в памяти при необходимости). Вы можете делать цены открытия / максимума / минимума / закрытия таким образом.

Для больших объемов данных вы действительно не хотите записывать все это в базу данных. Во всяком случае, не синхронно. Постоянное хранилище плюс хранилище данных - это, вероятно, больше маршрут, по которому вы хотите идти, но, опять же, это зависит от требований, объемов и т. Д.

Это сложная тема, и я только касаюсь ее. Надеюсь, это поможет вам.

2 голосов
/ 18 марта 2009

Возможно, вам будет интересно послушать презентацию Майкла Стоунбрейкера на Money: Tech . Он затрагивает ряд вещей, о которых вы упомянули, что вам нужно, и иллюстрирует, как большие три слона (SQL Server, Oracle и DB2) никогда не смогут удовлетворить потребности хранилищ тиков (которые, похоже, вы создаете). Он копает за пределами колонных магазинов, что, я согласен, является правильным направлением Он даже обсуждает сжатие и скорость, и это для вас обе проблемы.

вот еще несколько ссылок, которые могут вас заинтересовать:

2 голосов
/ 06 января 2009

Я бы посмотрел на ориентированную на столбцы базу данных . Было бы здорово для такого рода приложений

1 голос
/ 07 января 2009

Многие JDBC-совместимые системы управления базами данных (например, Oracle) обеспечивают сжатие в физическом механизме хранения. В Oracle, например, существует понятие «сжатой» таблицы без дополнительных затрат на декомпрессию:

http://www.ardentperf.com/wp-content/uploads/2007/07/advanced-compression-datasheet.pdf

0 голосов
/ 07 января 2009

Спасибо за ответы.

Cletus, я ценю план, но один из компромиссов, которые я не могу сделать, - это отказ от гибкости и совместимости БД с JDBC / Hibernate, чтобы позволить использовать все доступные инструменты. Более того, хотя я четко не заявлял об этом, я не хочу заставлять своих пользователей принимать [возможно, дорогое] коммерческое решение. Если у них есть База данных Бренда X, пусть используют ее. Если им все равно, мы рекомендуем базу данных с брендом Y с открытым исходным кодом. По сути, приложение имеет несколько лиц, одно из которых является хранилищем для входящих данных, но другое лицо является источником отчетов, и я действительно не знаю не хочу заниматься написанием отчетов.

Хотя я еще не тестировал его под нагрузкой, я очень впечатлен LucidDB . Это база данных, ориентированная на столбцы, которая обеспечивает хорошую производительность запросов и, на первый взгляд, хорошее сжатие данных. У него есть драйвер JDBC, хотя для него пока нет диалекта Hibernate, насколько я могу судить. Он также поддерживает определяемые пользователем преобразования, которые, в общем, я думаю, позволят мне беспрепятственно реализовать мою идею сжатия повторяющихся и последовательных значений в одну «строку», но вынести их обратно в несколько «синтетических» строк во время запроса, причем все это делается незаметно. к вызывающей стороне запроса. Наконец, он поддерживает эту замечательную особенность сторонних таблиц, где другие таблицы поддержки баз данных JDBC могут быть найдены в LucidDB. Я думаю, что это может иметь неоценимое значение для обеспечения некоторого уровня поддержки других баз данных.

Спасибо за указатель, Javaman. Это объединило меня в LucidDB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...