Рекомендации по структуре базы данных с огромным набором данных - PullRequest
4 голосов
/ 22 декабря 2010

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

Мы распределили сеть датчиков.Информация, собранная в одной базе данных и обработанная в дальнейшем.

Текущий дизайн БД состоит в том, чтобы разбивать одну огромную таблицу в месяц.Мы стараемся держать его на уровне 1 млрд. (Обычно 600–800 млн. Записей), поэтому скорость заполнения составляет 20–50 млн. Записей в день.

Сервер БД в настоящее время представляет собой MS SQL 2008 R2, но мы начали с 2005 года и выполняем обновлениево время разработки проекта.

В самой таблице содержатся поля SensorId, MessageTypeId, ReceiveDate и Data.Текущее решение состоит в том, чтобы сохранить данные датчика в поле данных (двоичные, 16-байтовой фиксированной длины) с частичным декодированием его типа и сохранить его в messageTypeId.

У нас есть другой тип сообщений, отправляемых датчиками (ток составляет около 200) и может быть дополнительно увеличено по требованию.

Основная обработка выполняется на сервере приложений, который извлекает записи по требованию (по типу, sensorId и диапазону дат), декодирует их и выполняет требуемую обработку.Для такого количества данных достаточно текущей скорости.

У нас есть запрос на увеличение емкости нашей системы в 10-20 раз, и мы беспокоимся, способно ли наше текущее решение к этому.

У нас естьтакже 2 идеи для «оптимизации» структуры, которые я хочу обсудить.

1 Данные датчика можно разбить на типы, для простоты я буду использовать 2 основных: данные уровня (значения) (аналоговые данные с диапазоном значенийзначения), данные состояния (фиксированное количество значений)

Таким образом, мы можем перестроить нашу таблицу в кучу маленьких, используя следующие правила:

  • для каждого значения фиксированного типа(тип состояния) создайте свою собственную таблицу с SensorId и ReceiveDate (поэтому мы избегаем типа хранилища и двоичного двоичного объекта), все зависимые (расширенные) состояния будут храниться в собственной таблице, аналогичной внешнему ключу, поэтому, если у нас есть State со значениями A и B, и зависимые (или дополнительные) состояния для него 1 и 2 заканчиваются таблицами StateA_1, StateA_2, StateB_1, StateB_2.Таким образом, имя таблицы состоит из фиксированных состояний, которые оно представляет.

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

Плюсы:

  • Храните только необходимый объем данных (в настоящее время наш двоичный двоичный объект Data содержит пространство до самого длинного значения) и уменьшенный размер БД;
  • Чтобы получить данные изДля конкретного типа мы получаем таблицу прав доступа вместо фильтра по типу;

Минусы:

  • AFAIK, это нарушает рекомендуемые методы;
  • Требуется разработка инфраструктуры дляавтоматизировать управление таблицами, так как администратор БД будет поддерживать его вручную;
  • Количество таблиц может быть значительно большим, поскольку требуется полный охват возможных значений;
  • Изменения схемы БД при введении новых данных датчикаили даже новое значение состояния для уже определенных состояний, таким образом, может потребовать комплексного изменения;
  • Комплексное управление приводит к склонности к ошибкам;
  • It может быть, черт возьми, движок БД для вставки значений в такую ​​организацию таблицы?
  • Структура БД не фиксирована (постоянно изменяется);

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

2 Может быть, просто разделить таблицу на датчик (это будет около 100 000 таблиц) или лучше по диапазону датчика и / илипереходить на разные базы данных с выделенными серверами, но мы хотим избежать аппаратного промежутка, если это возможно.

3 Оставить как есть.

4 Переключиться на другой тип СУБД, например, СУБД, ориентированные на столбцы (HBase ипохоже).

Что ты думаешь?Может быть, вы можете предложить ресурс для дальнейшего чтения?

Обновление: Природа системы в том, что некоторые данные с датчиков могут поступать даже с месячной задержкой (обычно с задержкой в ​​1-2 недели), некоторые всегда подключены к сети, какой-то датчик имеет встроенную память и в конечном итоге подключается к сети. Каждое сообщение датчика имеет связанную дату события и дату получения сервером, поэтому мы можем отличить последние данные от собранных некоторое время назад. Обработка включает в себя некоторые статистические вычисления, определение отклонения параметров и т. Д. Мы создали сводные отчеты для быстрого просмотра, но когда мы получаем данные от обновлений датчиков, старые данные (уже обработанные), мы должны перестроить некоторые отчеты с нуля, поскольку они зависят от всех доступных данные и агрегированные значения не могут быть использованы. Таким образом, мы обычно храним данные за 3 месяца для быстрого доступа и другие данные в архиве. Мы изо всех сил стараемся сократить объем данных, необходимых для хранения данных, но решили, что нам нужно все это для обеспечения точности результатов.

Update2:

Здесь таблица с первичными данными. Как я упоминаю в комментариях, мы удаляем все зависимости и ограничения из него во время «потребности в скорости», поэтому он используется только для хранения.

CREATE TABLE [Messages](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [sourceId] [int] NOT NULL,
    [messageDate] [datetime] NOT NULL,
    [serverDate] [datetime] NOT NULL,
    [messageTypeId] [smallint] NOT NULL,
    [data] [binary](16) NOT NULL
)

Пример данных с одного из серверов:

id      sourceId    messageDate          serverDate messageTypeId   data
1591363304  54  2010-11-20 04:45:36.813 2010-11-20 04:45:39.813 257 0x00000000000000D2ED6F42DDA2F24100

1588602646  195 2010-11-19 10:07:21.247 2010-11-19 10:08:05.993 258 0x02C4ADFB080000CFD6AC00FBFBFBFB4D

1588607651  195 2010-11-19 10:09:43.150 2010-11-19 10:09:43.150 258 0x02E4AD1B280000CCD2A9001B1B1B1B77

Ответы [ 4 ]

1 голос
/ 22 декабря 2010

Один из методов, не столько связанных с базами данных, это переключение на запись изменения значений - при наличии как минимум n записей в минуту или около того.Так, например, если в качестве датчика № 1 отправляется что-то вроде:

Id  Date              Value
-----------------------------
1 2010-10-12 11:15:00 100
1 2010-10-12 11:15:02 100
1 2010-10-12 11:15:03 100
1 2010-10-12 11:15:04 105

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

Не уверен, поможет ли это, или это будет возможно в вашем приложении - просто идея.

РЕДАКТИРОВАТЬ

Можно ли архивировать данные в зависимости от вероятности доступа?Правильно ли будет сказать, что старые данные менее доступны, чем новые?Если это так, вы можете взглянуть на архитектуру DW 2.0 Билла Инмона для следующего поколения хранилищ данных , в которой он обсуждает модель перемещения данных через различные зоны DW (интерактивные, интегрированные, ближние линииАрхив) основано на вероятности доступа.Время доступа варьируется от очень быстрого (интерактивная зона) до очень медленного (архивное).Каждая зона имеет разные требования к оборудованию.Цель состоит в том, чтобы предотвратить засорение больших объемов данных DW.

1 голос
/ 22 декабря 2010

В отношении хранения у вас, вероятно, все будет хорошо. SQL Server справится с этим.

Что меня беспокоит, так это нагрузка, которую будет принимать ваш сервер. Если вы постоянно принимаете транзакции, сегодня у вас будет около 400 транзакций в секунду. Увеличьте это в 20 раз, и вы увидите ~ 8000 транзакций в секунду. Это не малое число, учитывая, что вы делаете отчеты по одним и тем же данным ...

Кстати, правильно ли я вас понимаю, что вы сбрасываете данные датчика, когда обрабатываете их? Таким образом, ваш общий набор данных будет составлять 1 миллиард строк? Или вы просто добавляете данные?

1 голос
/ 22 декабря 2010

Просто расскажу о некоторых идеях, надеюсь, что они будут полезны - это то, о чем я буду думать / думать / изучать.

Разделение - вы упоминаете, что таблица разбита по месяцам. Это разделено вручную, или вы используете функциональность разделения, доступную в Enterprise Edition? Если вы работаете в ручном режиме, рассмотрите возможность использования встроенной функции разделения, чтобы разделить ваши данные еще больше, что повысит масштабируемость / производительность. Эта статья " Секционированные таблицы и индексы " на MSDN, написанная Кимберли Триппом, великолепна - там много отличной информации, я не буду делать это несправедливо, перефразируя! Стоит подумать над созданием вручную 1 таблицы на датчик, что может быть сложнее в обслуживании / внедрении и, следовательно, добавляет сложность (просто = хорошо). Конечно, только если у вас есть Enterprise Edition.

Отфильтрованные индексы - ознакомьтесь с этой статьей MSDN

Конечно, есть аппаратный элемент - само собой разумеется, что мясистый сервер с множеством RAM / быстрых дисков и т. Д. Будет играть роль.

0 голосов
/ 12 января 2011

Вы можете хранить метки даты и времени как целые числа. Я считаю, что штампы даты и времени используют 8 байтов, а целые числа используют только 4 в SQL. Вы должны были бы пропустить год, но, поскольку вы разбиваете по месяцам, это может не быть проблемой.

Таким образом, '12 / 25/2010 23:22:59 'будет храниться как 1225232259 -MMDDHHMMSS

Просто мысль ...

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