Я пишу приложение, которое должно хранить и анализировать большие объемы электрических и температурных данных.
По сути, мне нужно хранить большое количество почасовых измерений потребления электроэнергии за последние несколько лет и в течение многих последующих лет для десятков тысяч мест, а затем анализировать данные не очень сложным образом.
Информация, которую мне нужно сохранить (на данный момент) - это идентификатор местоположения, метка времени (дата и время), температура и использование электричества.
Что касается объема данных, которые необходимо сохранить, это приблизительное значение, но примерно так:
20 000+ местоположений, 720 записей в месяц (ежечасные измерения, приблизительно 720 часов в месяц), 120 месяцев (в течение 10 лет назад ) и много лет в будущее. Простые вычисления дают следующие результаты:
20 000 местоположений x 720 записей x 120 месяцев (10 лет назад) = 1 728 000 000 записей .
Это прошлые записи, новые записи будут импортироваться ежемесячно, то есть примерно 20 000 x 720 = 14 400 000 новых записей в месяц .
Общее количество мест будет неуклонно расти.
Над всеми этими данными должны быть выполнены следующие операции:
- Получить данные за определенную дату И период времени: все записи для определенного идентификатора местоположения в период с 01.01.2013 по 01.01.2017 и с 07:00 до 13:00.
- Простые математические операции для определенного диапазона даты и времени, например, MIN, MAX и AVG, температура и потребление электроэнергии для определенного идентификатора местоположения в течение 5 лет с 07:00 до 13:00.
Данные будут записываться ежемесячно, но будут прочитаны сотнями пользователей (по крайней мере) постоянно, поэтому скорость чтения имеет гораздо большее значение.
У меня нет опыта работы с базами данных NoSQL, но, как я понял, они являются лучшим решением для использования здесь. Я читал о самых популярных базах данных NoSQL, но, поскольку они сильно отличаются друг от друга и также допускают очень разную архитектуру таблиц, я не смог решить, какую базу данных лучше всего использовать.
Моим основным выбором были Cassandra и MongoDB, но у меня очень ограниченные знания и никакого реального опыта, когда дело касается больших данных и NoSQL, я не совсем уверен. Я также читал, что PostreSQL также хорошо обрабатывает такие объемы данных.
Мои вопросы следующие:
- Должен ли я использовать базу данных NoSQL для таких больших объемов данных. Если нет, могу ли я придерживаться MySQL?
- Какую базу данных я должен использовать?
- Должен ли я хранить дату и время в отдельных, проиндексированных (если это возможно) столбцах, чтобы быстро извлекать и обрабатывать данные в течение определенных периодов времени и даты, или это можно сделать, храня метку времени в одном столбце?
- Подходит ли здесь подход к моделированию данных временных рядов, и если нет, то не могли бы вы дать мне подсказки для хорошего дизайна таблицы?
Спасибо.
Ответы:
Это именно то, что я делаю каждый день, за исключением того, что вместо часовых данных я использую 5-минутные данные. Я загружаю около 200 миллионов записей каждый день, поэтому количество, о котором вы говорите, не является проблемой. 5-минутные данные имеют размер около 2 ТБ, и у меня есть данные о погоде за 50 лет на почасовом уровне в зависимости от местоположения. Итак, позвольте мне ответить на ваши вопросы, основываясь на моем опыте:
Общий совет: я храню большую часть данных между двумя базами данных, первая - это прямые данные временных рядов и нормализована. Моя вторая база данных очень ненормализована и содержит предварительно агрегированные данные. Как бы быстро ни работала моя система, я не закрываю глаза на тот факт, что пользователи даже не хотят ждать 30 секунд для загрузки отчета - даже если я лично считаю, что 30 секунд для обработки 2 ТБ данных чрезвычайно быстры.
Чтобы пояснить, почему я рекомендую хранить час отдельно от даты, вот несколько причин, почему я делаю это таким образом:
DATETIME
колонка.Как я уже говорил выше, все это основано на моем личном опыте, и позвольте мне сказать вам, что это были тяжелые несколько лет и много изменений, чтобы добраться туда, где я сейчас нахожусь. Не делайте того, что я сделал, учитесь на моих ошибках и убедитесь, что вы привлекаете конечных пользователей вашей системы (или разработчиков, авторов отчетов и т. Д.) К принятию решений относительно вашей базы данных.
источник
Индексы PostgreSQL и BRIN
Проверьте это сами. Это не проблема на 5-летнем ноутбуке с ssd.
Итак, создание таблицы заняло 22 минуты. Во многом потому, что таблица скромная 97ГБ. Далее мы создаем индексы,
Создание индексов также заняло много времени. Хотя, поскольку они BRIN, их всего 2-3 МБ, и они легко хранятся в оперативной памяти. Чтение 96 ГБ не происходит мгновенно, но это не проблема для моего ноутбука при вашей нагрузке.
Теперь мы запрашиваем это.
Обновление с отметками времени
Здесь мы генерируем таблицу с разными временными метками, чтобы удовлетворить запрос на индексирование и поиск по столбцу временных меток, создание занимает немного больше времени, потому что
to_timestamp(int)
оно существенно медленнее, чемnow()
(которое кэшируется для транзакции)Теперь мы можем вместо этого выполнить запрос к значению временной метки,
Результат:
Таким образом, за 83,321 мс мы можем объединить 86 401 запись в таблице с 1,7 млрд. Строк. Это должно быть разумно.
Часовое окончание
Вычисление окончания часа тоже довольно просто, обрежьте временные метки вниз и затем просто добавьте час.
Важно отметить, что он не использует индекс агрегации, хотя мог бы. Если это ваш типичный запрос, вы, вероятно, хотите, чтобы в
date_trunc('hour', tsin)
нем был BRIN , кроется небольшая проблема, котораяdate_trunc
не является неизменной, поэтому вам придется сначала ее обернуть, чтобы сделать так.Разметка
Другим важным моментом информации о PostgreSQL является то, что PG 10 обеспечивает разделение DDL . Так, например, вы можете легко создавать разделы для каждого года. Разбейте вашу скромную базу данных на второстепенные, крошечные. При этом вы должны иметь возможность использовать и поддерживать индексы btree, а не BRIN, что было бы еще быстрее.
Или что угодно.
источник
Меня удивляет, что никто здесь не упомянул бенчмаркинг - пока @EvanCarroll не получил свой отличный вклад!
Если бы я был вами, я бы потратил некоторое время (и да, я знаю, что это ценный товар!), Настраивая системы, выполняя то, что, как вы думаете, будет (получите ввод от конечного пользователя здесь!), Скажем, ваши 10 самых распространенных запросов.
Мои собственные мысли:
Решения NoSQL могут работать очень хорошо для конкретных случаев использования, но часто негибки для специальных запросов. Для забавного взгляда на NoSQL Брайана Акера - бывшего главного архитектора MySQL, смотрите здесь !
Я согласен с @ Mr.Brownstone, что ваши данные в высшей степени подходят для реляционного решения (и это мнение подтвердил Эван Кэрролл )!
Если бы я взял на себя какие-либо расходы, это было бы с моей дисковой технологией! Я бы потратил любые деньги, которые были в моем распоряжении, на NAS или SAN или, возможно, на некоторые SSD-диски, чтобы хранить мои редко записанные совокупные данные!
Сначала я бы посмотрел на то, что у меня есть сейчас . Запустите несколько тестов и покажите результаты лицам, принимающим решения. У вас уже есть прокси в виде работы EC ! Но один или два быстрых теста на вашем оборудовании были бы более убедительными!
Тогда подумайте о том, чтобы потратить деньги! Если вы собираетесь тратить деньги, сначала посмотрите на оборудование, а не на программное обеспечение. AFAIK, вы можете арендовать дисковую технологию на испытательный срок или, что еще лучше, раскрутить пару проверочных концепций в облаке.
Моим личным первым портом захода для такого проекта был бы PostgreSQL. Это не значит, что я бы исключил частное решение, но законы физики и дисков одинаковы для всех! "Я могу поменять законы физики Джима" :-)
источник
Если вы еще этого не сделали, взгляните на СУБД временных рядов, поскольку она оптимизирована для хранения и запроса данных, где основное внимание уделяется типу даты / времени. Обычно базы данных временных рядов используются для записи данных в диапазонах минут / секунд / субсекунд, поэтому я не уверен, подходит ли он для часовых приращений. Тем не менее, этот тип СУБД, кажется, стоит изучить. В настоящее время InfluxDB является наиболее авторитетной и широко используемой базой данных временных рядов.
источник
Ясно, что это не проблема NoSQL, но я хотел бы предположить, что, хотя решение СУБД будет работать, я думаю, что подход OLAP подойдет намного лучше, и учитывая очень ограниченные диапазоны данных, я настоятельно рекомендую исследовать использование БД на основе столбцов. а не на основе строк. Подумайте об этом так: у вас может быть 1,7 миллиарда фрагментов данных, но вам по-прежнему нужно всего 5 бит, чтобы индексировать каждое возможное значение часа или дня месяца.
У меня есть опыт работы с аналогичной проблемной областью, в которой Sybase IQ (сейчас SAP IQ) используется для хранения до 300 миллионов счетчиков в час данных управления производительностью телекоммуникационного оборудования, но я сомневаюсь, что у вас есть бюджет для такого решения. На открытой арене MariaDB ColumnStore является очень многообещающим кандидатом, но я бы порекомендовал также изучить MonetDB.
Поскольку производительность запросов является для вас основным фактором, подумайте над тем, как будут формулироваться запросы. Именно здесь OLAP и RDBMS демонстрируют свои самые большие различия: - с OLAP вы нормализуете производительность запросов, а не уменьшаете повторение, уменьшаете объем хранилища или даже применяете согласованность. Поэтому в дополнение к исходной метке времени (вы не забыли захватить ее часовой пояс, я надеюсь?) Есть отдельное поле для метки времени UTC, другие для даты и времени, и еще больше для года, месяца, дня, часа, минуты и смещение UTC. Если у вас есть дополнительная информация о местоположениях, не стесняйтесь хранить ее в отдельной таблице местоположений, которую можно искать по требованию, и не стесняйтесь хранить ключ к этой таблице в основной записи, но сохраняйте полное имя местоположения в основной таблице как ну, в конце концов,
В качестве окончательного предложения используйте отдельные таблицы для популярных агрегированных данных и используйте пакетные задания для их заполнения, чтобы вам не приходилось повторять упражнение для каждого отчета, который использует агрегированное значение и создает запросы, которые сравнивают текущие с историческими или от исторического к историческому намного проще и намного, намного быстрее.
источник