Стратегии для разработки базы данных (доступ к которой осуществляется из спящего режима), которая будет содержать много архивных данных - PullRequest
2 голосов
/ 23 января 2010

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

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

Редактировать: датчики тупые, и с полки. Их невозможно продлить. В случае отключения сети вся информация теряется. Поскольку датчики работают на GPRS, этот сценарий будет несколько маловероятным (поскольку провайдер GPRS довольно хорош здесь, в Швеции, но да, он может выйти из строя и с этим ничего не поделать).

Был рассмотрен механизм организации очередей, и Spring Roo позволяет легко работать с прототипом кода на основе ACTIVEMQ.

Ответы [ 4 ]

4 голосов
/ 23 января 2010

У меня есть пара проблем по поводу этого дизайна:

  1. Hibernate - это инструмент ORM.Требуется объектная модель с одной стороны и реляционная с другой.У вас есть объектное представление?Если нет, я бы сказал, что Hibernate - не тот путь.Если это простой механизм отображения таблиц, у вас все будет в порядке.
  2. Ваша ситуация звучит как война: длительные периоды скуки, окруженные моментами явного террора.Я не знаю, использует ли ваш проект асинхронные механизмы между получением данных датчика и серверной частью, но я хотел бы иметь какой-то постоянный механизм организации очередей, чтобы гарантировать доставку всех данных и упорядоченную линию, пока они былиожидая упорства.Пока вам не требуется доступ к данным в режиме реального времени, очередь гарантирует доставку и гарантирует, что у вас не будет тысяч запросов, одновременно появляющихся в узком месте.
  3. КакВы штампуете элементы датчика по мере их поступления?Возможно, вы захотите использовать столбец, который уменьшается до наносекунд, чтобы получить правильные значения.

Датчики управляются событиями или синхронизированы?

Звучит как большая проблема.Удачи.

2 голосов
/ 23 января 2010

Это означает, что вы получите примерно 1 запись / секунду, умноженную на количество тысяч датчиков, или примерно 2,5 миллиона строк / месяц, умноженную на количество тысяч датчиков.

Postgres имеет наследование и разбиение. Это сделало бы практичным иметь такие таблицы:

  • sensordata_current
  • sensordata_2010_01
  • sensordata_2009_12
  • sensordata_2009_11
  • sensordata_2009_10
  • .
  • .
  • .

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

Когда завершится месяц (скажем, 2010 янв. Только что исполнился 2010 г.), вы переименуете sensordata_current в только что завершившийся месяц (2010_01), создадите новый sensordata_current, переместите все строки из 2010_01 во вновь созданный sensordata_current, которые имеют отметка времени в феврале, добавьте, наконец, ограничение к 2010_01, которое выражает, что оно имеет данные только в январе 2010 года. Также удалите ненужные индексы на 2010_01. В Postgres все это можно сделать атомарным, заключив его в транзакцию.

В качестве альтернативы вам может потребоваться оставить _current в покое, создать новый 2010_01 и переместить в него все январские строки из _current (а затем опционально пропустить _current, чтобы сразу же освободить пространство - хотя, если ваши строки имеют одинаковый размер, с последними Postgres версий нет особого смысла в этом). Ваш ход (SELECT INTO / DELETE) в этом случае займет больше времени, но вам не придется писать код для воссоздания индексов, и это также сохранит другие детали (ссылочная целостность и т. Д.).

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

Подробнее см. Разделение данных Postgres .

2 голосов
/ 23 января 2010

Предположим, у вас есть 10 000 датчиков, отправляющих информацию каждые 15 минут. Чтобы повысить производительность на стороне базы данных, вам, возможно, придется разделить базу данных, возможно, по дате / времени, типу датчика или категории или некоторому другому фактору. Это также зависит от того, как вы будете запрашивать ваши данные.

http://en.wikipedia.org/wiki/Partition_(database)

Другим узким местом будет само ваше приложение Java / Java EE. Это зависит от вашего бизнеса, например, все ли 150 000 датчиков будут отправлять информацию одновременно? и какая архитектура будет следовать вашему Java-приложению. Вам придется читать статьи о высокой масштабируемости и производительности.

Вот моя рекомендация для решения Java / Java EE.

Вместо одного, создайте кластер приложений, получающих данные.

Наличие приложения контроллера, которое управляет связью между тем, какой датчик отправляет данные в какой экземпляр приложения в кластере. Экземпляр приложения может извлекать данные из датчика, или датчик может передавать данные в экземпляр приложения, но контроллер - это тот, кто будет контролировать, какой экземпляр приложения связан с каким набором датчиков. Этот контроллер должен быть динамическим, чтобы датчики можно было добавлять, удалять или обновлять, а также экземпляры приложений могут присоединяться или выходить из кластера в любое время. Убедитесь, что в вашем контроллере есть возможность переключения при сбое.

Таким образом, если у вас есть 10 000 датчиков и 10 экземпляров приложения в кластере, у вас есть 1000 датчиков, связанных с приложением в любой момент времени. Если вам все еще нужна более высокая производительность, вы можете иметь, например, 20 экземпляров приложения в кластере, и у вас будет 500 датчиков, связанных с экземпляром приложения.

Экземпляры приложений могут размещаться на одном или нескольких компьютерах, что позволяет добиться как вертикальной, так и горизонтальной масштабируемости. Каждый экземпляр приложения будет многопоточным и будет иметь локальное постоянство. Это позволит избежать узкого места на главном сервере базы данных и уменьшит время отклика транзакции. Эта локальная персистенция может быть файлом (ами) SAN или локальной СУБД (например, Java DB) или даже MQ. Если вы сохраняете локально в базе данных, то вы можете использовать Hibernate для того же.

Асинхронно перемещать данные из локального хранилища в основную базу данных. Это зависит от того, как вы сохранили данные локально. Если вы используете постоянство на основе файлов, вам нужен отдельный поток, который считывает данные из файла и вставляет их в основной репозиторий базы данных. Если вы используете локальную базу данных, тогда этот поток может использовать Hibernate для локального чтения данных и вставки их в основной репозиторий базы данных. Если вы используете MQ, вы можете создать поток или отдельное приложение для перемещения данных из очереди в основной репозиторий базы данных.

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

0 голосов
/ 23 января 2010

Требуется ли, чтобы эти датчики подключались напрямую к приложению для загрузки своих данных? А это приложение отвечает за запись данных в базу данных?

Я бы подумал о том, чтобы датчики записывали данные в очередь сообщений , а ваше приложение "запись в БД" отвечало бы за сбор новых данных из очереди и их запись в базу данных. Это похоже на довольно классический пример «производителей сообщений» и «потребителей сообщений», то есть датчиков и приложения, соответственно.

Таким образом, датчики не будут затронуты, если ваше приложение «запись в БД» имеет какое-либо время простоя, или если у него есть какие-либо проблемы с производительностью или замедление работы базы данных и т. Д. Это также позволит вам увеличить количество сообщений потребители в будущем, не влияя на датчики вообще.

Может показаться, что решение такого типа просто перемещает возможную точку отказа из приложения-потребителя в очередь сообщений, но есть несколько вариантов сделать очередь отказоустойчивой - кластеризация, постоянное хранение сообщений и т. Д.

Apache MQ - популярная система очереди сообщений в мире Java.

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