У меня есть набор данных за 1 минуту по 1000 акций с 1998 года, всего около (2012-1998)*(365*24*60)*1000 = 7.3 Billion
строк.
В большинстве случаев (99,9%) я буду выполнять только чтение запросы на .
Как лучше всего хранить эти данные в БД?
- 1 большая таблица с 7,3 млрд строк?
- 1000 таблиц (по одной для каждого символа акций) с 7,3 млн строк в каждой?
- какие-либо рекомендации по движку базы данных? (Я планирую использовать MySQL Amazon RDS)
Я не привык иметь дело с такими большими наборами данных, так что это отличная возможность для меня учиться. Буду очень признателен за вашу помощь и совет.
Редактировать:
Это образец строки:
'XX', 20041208, 938, 43.7444, 43.7541, 43.735, 43.7444, 35116.7, 1, 0, 0
Столбец 1 - это символ акции, столбец 2 - дата, столбец 3 - минуты, остальные - цены открытия-максимума-минимума-закрытия, объем и 3 целочисленных столбца.
Большинство запросов будут иметь вид «Назовите мне цены на AAPL с 12:15 12 апреля 2012 г. по 12:52 13 апреля 2012 г.»
Об оборудовании: я планирую использовать Amazon RDS, поэтому я могу гибко использовать это
Ответы:
Расскажите нам о запросах и вашей аппаратной среде.
Мне очень хотелось бы перейти на NoSQL , используя Hadoop или что-то подобное, если вы можете использовать преимущества параллелизма.
Обновить
А почему?
Прежде всего, обратите внимание на то, что я спросил о запросах. Вы не можете - и мы определенно не можем - ответить на эти вопросы, не зная, какова рабочая нагрузка. (Кстати, скоро у меня будет статья об этом, но я не могу связать ее сегодня.) Но масштаб проблемы заставляет меня задуматься о том, чтобы отказаться от большой старой базы данных, потому что
Мой опыт работы с подобными системами предполагает, что доступ будет либо большим, последовательным (вычисление какого-то типа анализа временных рядов), либо очень очень гибким интеллектуальным анализом данных (OLAP). Последовательные данные можно обрабатывать лучше и быстрее последовательно; OLAP означает вычисление большого количества индексов, что займет много времени или много места.
Тем не менее, если вы делаете то, что по сути является большим запуском множества данных в мире OLAP, лучше всего подойдет подход, ориентированный на столбцы.
Если вы хотите выполнять случайные запросы, особенно делать перекрестные сравнения, система Hadoop может оказаться эффективной. Почему? Потому как
Но дело в том, что, пока мы не узнаем о вашей загруженности, невозможно сказать что-либо окончательное.
источник
Таким образом, базы данных предназначены для ситуаций, когда у вас есть большая сложная схема, которая постоянно меняется. У вас есть только одна «таблица» с набором простых числовых полей. Я бы сделал это так:
Подготовьте структуру C / C ++ для хранения формата записи:
Затем вычислите sizeof (StockPrice [N]), где N - количество записей. (В 64-битной системе) Это должно быть всего несколько сотен гигабайт и поместиться на жесткий диск за 50 долларов.
Затем обрежьте файл до этого размера и mmap (в Linux или используйте CreateFileMapping в Windows) в память:
Приведите указатель mmaped к StockPrice * и передайте данные, заполнив массив. Закройте mmap, и теперь у вас будут данные в одном большом двоичном массиве в файле, который позже можно будет снова добавить mmap.
Теперь вы можете снова использовать mmap для чтения из любой программы, и ваши данные будут легко доступны:
Итак, теперь вы можете рассматривать его как массив структур в памяти. Вы можете создавать различные типы структур данных индекса в зависимости от ваших «запросов». Ядро будет иметь дело с переносом данных на диск и с диска прозрачно, поэтому это будет безумно быстро.
Если вы ожидаете иметь определенный шаблон доступа (например, непрерывную дату), лучше всего отсортировать массив в этом порядке, чтобы он последовательно попадал на диск.
источник
Одноразовое хранение и многократное считывание временных числовых данных - это вариант использования, называемый «временными рядами». Другими распространенными временными рядами являются данные датчиков в Интернете вещей, статистика мониторинга серверов, события приложений и т. Д.
Этот вопрос был задан в 2012 году, и с тех пор несколько движков баз данных разрабатывают функции специально для управления временными рядами. Я добился отличных результатов с InfluxDB , которая имеет открытый , написана на Go и лицензирована MIT.
InfluxDB был специально оптимизирован для хранения и запроса данных временных рядов. Намного больше, чем Кассандра , которую часто рекламируют как отличную для хранения временных рядов:
Оптимизация временных рядов требует определенных компромиссов. Например:
В открытых источниках тестов ,
Запросы тоже очень простые. Если ваши строки выглядят так
<symbol, timestamp, open, high, low, close, volume>
, с InfluxDB вы можете хранить только это, а затем легко запрашивать. Скажем, за последние 10 минут данных:Нет ни идентификаторов, ни ключей, ни объединений. Вы можете делать много интересных агрегатов . Вам не нужно вертикально разбивать таблицу, как в PostgreSQL , или преобразовывать вашу схему в массивы секунд, как в MongoDB . Кроме того, InfluxDB очень хорошо сжимает, в то время как PostgreSQL не сможет выполнить какое-либо сжатие для того типа данных, которые у вас есть .
источник
Хорошо, так что это несколько отличается от других ответов, но ... мне кажется, что если у вас есть данные в файловой системе (возможно, один запас на файл) с фиксированным размером записи, вы можете получить данные действительно легко: при запросе определенного запаса и временного диапазона вы можете найти нужное место, получить все необходимые данные (вы точно знаете, сколько байтов), преобразовать данные в нужный вам формат (который может будьте очень быстры в зависимости от вашего формата хранения), и вы далеко.
Я ничего не знаю о хранилище Amazon, но если у вас нет ничего похожего на прямой доступ к файлам, у вас могут быть большие двоичные объекты - вам нужно будет сбалансировать большие двоичные объекты (меньше записей, но, вероятно, читать больше данных, чем вам нужно каждый time) с небольшими каплями (большее количество записей дает больше накладных расходов и, вероятно, больше запросов для их получения, но каждый раз возвращается меньше бесполезных данных).
Затем вы добавляете кэширование - например, я предлагаю предоставить разным серверам разные запасы для обработки - и вы можете в значительной степени просто обслуживать из памяти. Если вы можете позволить себе достаточно памяти на достаточном количестве серверов, пропустите часть «загрузка по запросу» и просто загрузите все файлы при запуске. Это упростило бы задачу за счет более медленного запуска (что, очевидно, влияет на отработку отказа, если только вы не можете позволить себе всегда иметь два сервера для любого конкретного запаса, что было бы полезно).
Обратите внимание, что вам не нужно хранить биржевой символ, дату или минуту для каждой записи, потому что они неявны в загружаемом файле и позиции в файле. Вы также должны подумать, какая точность вам нужна для каждого значения и как ее эффективно хранить - вы указали 6SF в своем вопросе, который вы можете сохранить в 20 битах. Потенциально храните три 20-битных целых числа в 64-битном хранилище: прочтите его как
long
(или любое другое 64-битное целочисленное значение) и используйте маскировку / сдвиг, чтобы вернуть его к трем целым числам. Конечно, вам нужно знать, какой масштаб использовать - который вы, вероятно, могли бы закодировать в 4 запасных бита, если не можете сделать его постоянным.Вы не сказали, на что похожи другие три целочисленных столбца, но если бы вы могли обойтись и для этих трех 64 бита, вы могли бы сохранить всю запись в 16 байтах. Это всего лишь ~ 110 ГБ для всей базы данных, что на самом деле не очень много ...
РЕДАКТИРОВАТЬ: Еще одна вещь, которую следует учитывать, заключается в том, что, по-видимому, акции не меняются за выходные - или, действительно, за ночь. Если фондовый рынок открыт только 8 часов в день, 5 дней в неделю, тогда вам нужно всего 40 значений в неделю вместо 168. На этом этапе вы можете получить только около 28 ГБ данных в ваших файлах ... намного меньше, чем вы, вероятно, думали изначально. Наличие такого количества данных в памяти очень разумно.
РЕДАКТИРОВАТЬ: Я думаю, что пропустил объяснение того, почему этот подход подходит здесь: у вас есть очень предсказуемый аспект для большой части ваших данных - биржевой тикер, дата и время. Выражая тикер один раз (как имя файла) и оставляя дату / время полностью неявными в позиции данных, вы удаляете целую кучу работы. Это немного похоже на разницу между a
String[]
и aMap<Integer, String>
- знание того, что ваш индекс массива всегда начинается с 0 и увеличивается с шагом 1 до длины массива, обеспечивает быстрый доступ и более эффективное хранение.источник
Насколько я понимаю, HDF5 был разработан специально для хранения временных рядов складских данных в качестве одного из возможных приложений. Коллеги по укладке продемонстрировали, что HDF5 хорош для больших объемов данных: хромосом , физики .
источник
Вот попытка создать сервер рыночных данных поверх базы данных Microsoft SQL Server 2012, который должен быть хорош для анализа OLAP, бесплатного проекта с открытым исходным кодом:
http://github.com/kriasoft/market-data
источник
Во-первых, в году нет 365 торговых дней, а праздничные дни - 52 выходных (104) = скажем, 250 x фактическое количество часов дня, когда рынок открыт, как кто-то сказал, и использовать символ в качестве первичного ключа - не лучшая идея. поскольку символы меняются, используйте k_equity_id (числовой) с символом (char), поскольку символы могут быть такими, как этот A или GAC-DB-B.TO, тогда в ваших таблицах данных с информацией о ценах у вас есть, поэтому ваша оценка 7,3 миллиард сильно завышен, так как это всего 1,7 миллиона строк на символ за 14 лет.
k_equity_id k_date k_minute
и для таблицы EOD (которая будет просматриваться в 1000 раз больше других данных)
k_equity_id k_date
Во-вторых, не храните поминутные данные OHLC в той же таблице БД, что и таблица EOD (конец дня), поскольку любой, кто хочет посмотреть pnf или линейную диаграмму за год, не имеет никакого интереса к минутная информация.
источник
Позвольте мне порекомендовать вам взглянуть на apache solr , который, я думаю, идеально подходит для вашей конкретной проблемы. По сути, вы сначала должны проиндексировать свои данные (каждая строка является «документом»). Solr оптимизирован для поиска и изначально поддерживает запросы диапазона по датам. Ваш именной запрос,
"Give me the prices of AAPL between April 12 2012 12:15 and April 13 2012 12:52"
переводится примерно так:
Предположим, что «stock» - это название акции, а «date» - это «DateField», созданное из столбцов «дата» и «минута» ваших входных данных при индексации. Solr невероятно гибок, и я действительно не могу сказать о нем достаточно хороших слов. Так, например, если вам необходимо сохранить поля в исходных данных, вы, вероятно, сможете найти способ динамически создать «DateField» как часть запроса (или фильтра).
источник
Я думаю, что с этим справится любая крупная СУБД. На атомарном уровне одна таблица с правильным разделением кажется разумной (разделение основано на использовании ваших данных, если оно исправлено - это, вероятно, либо символ, либо дата).
Вы также можете изучить создание агрегированных таблиц для более быстрого доступа выше атомарного уровня. Например, если ваши данные на уровне дня, но вы часто получаете данные на уровне wekk или даже месяца, то это можно предварительно рассчитать в сводной таблице. В некоторых базах данных это можно сделать с помощью кэшированного представления (различные имена для разных решений БД, но в основном это представление атомарных данных, но после запуска представление кэшируется / закрепляется в фиксированной временной таблице, которая запрашивается для последующих запросов соответствия Это может быть сброшено с интервалом, чтобы освободить память / место на диске).
Я думаю, мы могли бы помочь вам с некоторыми идеями относительно использования данных.
источник
Следует сравнить медленные решения с простой оптимизированной по памяти моделью. В несжатом виде он помещается в RAM-сервер на 256 ГБ. Снимок умещается в 32 КБ, и вы просто индексируете его позиционно по datetime и stock. Затем вы можете делать специализированные снимки, так как открытие одного часто равносильно закрытию предыдущего.
[править] Как вы думаете, почему вообще имеет смысл использовать базу данных (rdbms или nosql)? Эти данные не меняются и помещаются в памяти. Это не тот случай использования, когда dbms могут добавить ценность.
источник
Если у вас есть оборудование, я рекомендую MySQL Cluster . Вы получаете интерфейс MySQL / RDBMS, с которым так хорошо знаком, и получаете быструю и параллельную запись. Чтение будет происходить медленнее, чем обычный MySQL, из-за задержки в сети, но у вас есть преимущество в возможности распараллеливать запросы и чтения из-за способа работы MySQL Cluster и механизма хранения NDB.
Убедитесь, что у вас достаточно машин MySQL Cluster и достаточно памяти / RAM для каждого из них - MySQL Cluster - это архитектура базы данных, в значительной степени ориентированная на память.
Или Redis , если вы не против использования интерфейса ключ-значение / NoSQL для чтения / записи. Убедитесь, что у Redis достаточно памяти - он сверхбыстрый для чтения и записи, с ним можно выполнять базовые запросы (хотя и не в РСУБД), но он также является базой данных в памяти.
Как уже говорили другие, знание запросов, которые вы будете выполнять, поможет.
источник
Вы захотите, чтобы данные хранились в столбчатой таблице / базе данных . Системы баз данных, такие как Vertica и Greenplum, представляют собой столбчатые базы данных, и я считаю, что SQL Server теперь позволяет использовать столбчатые таблицы. Они чрезвычайно эффективны для работы
SELECT
с очень большими наборами данных. Они также эффективны при импорте больших наборов данных.Бесплатная колоночная база данных - это MonetDB .
источник
Если ваш вариант использования заключается в простом чтении строк без агрегирования, вы можете использовать кластер Aerospike. Он находится в базе данных памяти с поддержкой файловой системы для сохранения. Он также оптимизирован для SSD.
Если вашему варианту использования нужны агрегированные данные, выберите кластер Mongo DB с сегментированием диапазона дат. Данные за год можно объединить в шарды.
источник