Лучшее хранилище данных для миллиардов строк


87

Мне нужно хранить небольшие биты данных (примерно 50-75 байтов) для миллиардов записей (~ 3 миллиарда в месяц в течение года).

Единственное требование - это быстрая вставка и быстрый поиск всех записей с одинаковым GUID и возможность доступа к хранилищу данных из .net.

Я специалист по SQL-серверу, и я думаю, что SQL Server может это сделать, но, несмотря на все разговоры о BigTable, CouchDB и других решениях nosql, это все больше и больше похоже на альтернативу традиционной RDBS, возможно, лучше всего из-за оптимизации для распределенные запросы и масштабирование. Я пробовал cassandra, и библиотеки .net в настоящее время не компилируются или все могут быть изменены (вместе с самой cassandra).

Я просмотрел множество доступных хранилищ данных nosql, но не могу найти ни одного, которое удовлетворяет моим потребностям в качестве надежной готовой к работе платформы.

Если бы вам пришлось хранить 36 миллиардов небольших плоских записей, чтобы они были доступны из .net, что бы вы выбрали и почему?


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

Вы задали несколько хороших вопросов. Ответы таковы: достаточно 95% времени работы - данные уже задерживаются на переменное количество, поэтому мне в любом случае нужно будет синхронизировать их постфактум, поэтому кратковременное отключение не является нарушением сделки. Потеря пластин или даже тысячи пластин - это не конец света. Однако потерять дневные данные было бы очень плохо. Последовательность тоже не так важна. В основном после вставки 30 миллионов строк в день мне нужно получить все строки с одинаковым GUID (возможно, 20 строк) и быть разумно уверенным, что я верну их все обратно.
Джоди Паулетт

Вы сбрасываете 30 миллионов строк в день в ежедневных / ежечасных запланированных пакетных заданиях, или они поступают постоянно, по одной?
Ремус Русану

Данные поступают с FTP-сайта ... файлы поступают непрерывно, и у меня есть процесс, который анализирует файлы, и в настоящее время он генерирует агрегированные данные и вставляет агрегированные значения (возможно, 1000 строк) в качестве транзакции. Новый процесс должен будет вставить сотни тысяч строк из каждого поступающего файла, вероятно, использование массовой вставки будет наиболее эффективным способом сделать это.
Джоди Паулетт,

Это похоже на задание ETL для SSIS и SQL Server. Они установили мировой рекорд для ETL со скоростью загрузки более 2 ТБ / час: blogs.msdn.com/sqlperf/archive/2008/02/27/etl-world-record.aspx
Ремус Русану,

Ответы:


103

Хранение ~ 3,5 ТБ данных и вставка около 1 КБ / сек 24x7, а также выполнение запросов с не указанной скоростью, это возможно с SQL Server, но есть и другие вопросы:

  • какие у вас требования к доступности для этого? 99,999% времени безотказной работы или 95% достаточно?
  • какие у вас требования к надежности? Отсутствие вставки обходится вам в 1 миллион долларов?
  • какие у вас требования к восстанавливаемости? Имеет ли это значение, если вы потеряете данные за один день?
  • какое у вас требование согласованности? Нужно ли гарантировать, что запись будет видна при следующем чтении?

Если вам нужны все эти требования, которые я выделил, предлагаемая вами нагрузка будет стоить миллионы аппаратных средств и лицензий на реляционную систему, любую систему, независимо от того, какие уловки вы пробуете (сегментирование, разбиение на разделы и т. Д.). Система nosql по самому своему определению не удовлетворяет всем этим требованиям.

Очевидно, вы уже ослабили некоторые из этих требований. В Visual Guide to NoSQL Systems есть хорошее визуальное руководство, в котором сравниваются предложения nosql на основе парадигмы «выберите 2 из 3» :

сравнение nosql

После обновления комментария OP

С SQL Server это будет прямая реализация:

  • один кластерный ключ для одной таблицы (GUID, время). Да, будет фрагментироваться , но эта фрагментация влияет на упреждающее чтение, и упреждающее чтение необходимо только для сканирования значительного диапазона. Поскольку вы запрашиваете только определенный GUID и диапазон дат, фрагментация не имеет большого значения. Да, это широкий ключ, поэтому у нелистовых страниц будет низкая плотность ключа. Да, это приведет к плохому коэффициенту заполнения. И да, страницы могут разбиваться. Несмотря на эти проблемы, с учетом требований, кластерный ключ остается лучшим выбором.
  • разделите таблицу по времени, чтобы вы могли эффективно удалять просроченные записи с помощью автоматического скользящего окна . Дополните это перестроением раздела индекса в оперативном режиме за последний месяц, чтобы устранить недостаточный коэффициент заполнения и фрагментацию, вызванную кластеризацией GUID.
  • включить сжатие страницы. Поскольку кластеризованные ключи сначала группируются по GUID, все записи GUID будут располагаться рядом друг с другом, что дает сжатию страницы хороший шанс развернуть сжатие словаря.
  • вам понадобится быстрый путь ввода-вывода для файла журнала. Вы заинтересованы в высокой пропускной способности, а не в низкой задержке, чтобы журнал не отставал от 1 КБ вставок в секунду, поэтому удаление данных является обязательным.

Для секционирования и сжатия страниц требуется SQL Server Enterprise Edition, они не будут работать в Standard Edition, и оба они очень важны для удовлетворения требований.

В качестве побочного примечания, если записи поступают из фермы интерфейсных веб-серверов, я бы поставил Express на каждый веб-сервер и вместо INSERT на задней стороне я бы отправил SENDинформацию на задний конец, используя локальное соединение / транзакцию на Express, совмещенном с веб-сервером. Это дает намного лучшую историю доступности решения.

Вот как я бы сделал это в SQL Server. Хорошая новость заключается в том, что проблемы, с которыми вы столкнетесь, хорошо изучены, а решения известны. это не обязательно означает, что это лучше, чем то, чего вы могли бы достичь с помощью Cassandra, BigTable или Dynamo. Я позволю кому-нибудь более разбирающемуся в вещах, не относящихся к SQL, аргументировать свою позицию.

Обратите внимание, что я никогда не упоминал модель программирования, поддержку .Net и тому подобное. Я честно считаю, что они неуместны в крупных развертываниях. Они имеют огромное значение в процессе разработки, но после развертывания не имеет значения, насколько быстрой была разработка, если накладные расходы ORM убивают производительность :)


Я дал ссылку на сайт Натана, но это не первая страница Slashdot;)
Ремус Русану

@RemusRusanu: смотрю на миграцию dba.se. Просто чтобы подготовить вас :-) И +1
gbn 03

Начиная с Microsoft SQL Server 2016, выпуск Enterprise больше не требуется для секционирования таблиц, поскольку секционирование таблиц теперь доступно практически во всех выпусках SQL Server 2016.
TChadwick

17

Вопреки распространенному мнению, NoSQL не касается производительности или даже масштабируемости. В основном речь идет о минимизации так называемого несоответствия объектно-реляционного импеданса, но также о горизонтальной масштабируемости по сравнению с более типичной вертикальной масштабируемостью СУБД.

Для простого требования быстрой вставки и быстрого поиска подойдет практически любой продукт для баз данных. Если вы хотите добавить реляционные данные или объединения, или иметь какую-либо сложную транзакционную логику или ограничения, которые вам необходимо наложить, тогда вам нужна реляционная база данных. Никакой продукт NoSQL не может сравниться.

Если вам нужны данные без схемы, вы захотите использовать базу данных, ориентированную на документы, такую ​​как MongoDB или CouchDB. Свободная схема - главная их черта; Мне лично нравится MongoDB, и я использую его в нескольких пользовательских системах отчетности. Я считаю это очень полезным, когда требования к данным постоянно меняются.

Другой основной вариант NoSQL - это распределенные хранилища ключей и значений, такие как BigTable или Cassandra. Это особенно полезно, если вы хотите масштабировать свою базу данных на многих машинах с обычным оборудованием. Очевидно, они также отлично работают на серверах, но не используют преимущества высокопроизводительного оборудования, а также SQL Server или Oracle или другой базы данных, предназначенной для вертикального масштабирования, и, очевидно, они не являются реляционными и не подходят для принудительной нормализации. или ограничения. Кроме того, как вы заметили, поддержка .NET имеет тенденцию в лучшем случае быть неоднородной.

Все продукты для реляционных баз данных поддерживают ограниченное разбиение. Они не так гибки, как BigTable или другие системы DKVS, их нелегко разделить на сотни серверов, но это действительно не похоже на то, что вы ищете. Они неплохо справляются с обработкой миллиардов записей, если вы правильно индексируете и нормализуете данные, запускаете базу данных на мощном оборудовании (особенно на твердотельных накопителях, если вы можете себе это позволить) и разбиваете на 2, 3 или 5 физических дисков, если необходимо.

Если вы соответствуете вышеуказанным критериям, если вы работаете в корпоративной среде и у вас есть деньги, которые можно потратить на достойное оборудование и оптимизацию базы данных, я бы пока остановился на SQL Server. Если вы жмете гроши и вам нужно запустить это на недорогом оборудовании для облачных вычислений Amazon EC2, вы, вероятно, захотите вместо этого выбрать Cassandra или Voldemort (при условии, что вы можете заставить работать с .NET).


11

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

36 миллиардов, 3 миллиарда в месяц, это примерно 100 миллионов в день, 4,16 миллиона в час, ~ 70 тысяч строк в минуту, 1,1 тысячи строк в секунду, поступающих в систему, непрерывно в течение 12 месяцев, без простоев.

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

С точки зрения хранения / извлечения и довольно критического аспекта, о котором вы не упомянули, является устаревание старых данных - удаление не является бесплатным.

Обычная технология, которую рассматривают, - это разбиение на разделы, однако поиск / извлечение на основе GUID приведет к низкой производительности, если вы должны получить каждое совпадающее значение за весь 12-месячный период. Вы можете поместить кластеризованные индексы в столбец GUID, чтобы связанные данные были сгруппированы для чтения / записи, но при таких количествах и скорости вставки фрагментация будет слишком высокой для поддержки, и она упадет на пол.

Я также хотел бы предположить, что вам понадобится очень приличный бюджет на оборудование, если это серьезное приложение со скоростью ответа типа OLTP, то есть по некоторым приблизительным предположениям, предполагая очень мало накладных расходов при индексации, около 2,7 ТБ данных.

В лагере SQL Server единственное, на что вы, возможно, захотите взглянуть, - это новая версия хранилища параллельных данных (Madison), которая больше предназначена для сегментирования данных и выполнения параллельных запросов к ним, чтобы обеспечить высокую скорость работы с большими массивами данных.


3
В биоинформатике наборы данных с миллиардами строк не редкость. Но они часто обрабатываются чисто потоковым способом из плоских файлов.
Эрик Гаррисон

3
@Erik: для потоковой обработки (т.е. просто необходимо определить определенные условия, но нет необходимости хранить данные для последующего запроса) что-то вроде StreamInsight лучше любой базы данных microsoft.com/sqlserver/2008/en/us/r2 -complex-event.aspx
Ремус Русану

2

«Мне нужно хранить небольшие биты данных (примерно 50-75 байт) для миллиардов записей (~ 3 миллиарда в месяц в течение года).

Единственное требование - это быстрые вставки и быстрый поиск всех записей с одинаковым GUID и возможность доступа к хранилищу данных из .net ».

Я могу сказать вам по опыту, что это возможно в SQL Server, потому что я сделал это в начале 2009 года ... и он все еще работает по сей день и довольно быстро.

Таблица была разбита на 256 разделов, имейте в виду, что это была версия SQL 2005 года ... и мы сделали именно то, что вы говорите, а именно, чтобы хранить биты информации по GUID и быстро получать по GUID.

Когда я ушел, у нас было около 2-3 миллиардов записей, и извлечение данных все еще было довольно хорошим (1-2 секунды, если проходил через пользовательский интерфейс, или меньше, если в РСУБД), даже несмотря на то, что политика хранения данных только что была создана.

Итак, короче говоря, я взял 8-й символ (т.е. где-то посередине) из строки GUID, а SHA1 хэшировал его и преобразовал как крошечный int (0-255) и сохранил в соответствующем разделе и использовал тот же вызов функции при получении данные обратно.

напишите мне, если вам нужна дополнительная информация ...


2

В следующей статье обсуждается импорт и использование таблицы из 16 миллиардов строк в Microsoft SQL. http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table .

Из статьи:

Вот несколько полезных советов из моего опыта:

  • Чем больше данных у вас есть в таблице с определенным кластеризованным индексом, тем медленнее становится импортировать в нее несортированные записи. В какой-то момент это становится слишком медленным, чтобы быть практичным.
  • Если вы хотите экспортировать таблицу в файл наименьшего размера, сделайте ее собственным форматом. Это лучше всего работает с таблицами, содержащими в основном числовые столбцы, потому что они более компактно представлены в двоичных полях, чем символьные данные. Если все ваши данные являются буквенно-цифровыми, вы не получите многого, экспортируя их в собственном формате. Если не разрешать нули в числовых полях, это может привести к дальнейшему сжатию данных. Если вы разрешаете поле иметь значение NULL, двоичное представление поля будет содержать 1-байтовый префикс, указывающий, сколько байтов данных последует.
  • Вы не можете использовать BCP для более чем 2147483647 записей, потому что переменная счетчика BCP представляет собой 4-байтовое целое число. Мне не удалось найти упоминания об этом ни в MSDN, ни в Интернете. Если ваша таблица состоит из
    более чем 2147483647 записей, вам придется экспортировать ее по частям
    или написать свою собственную процедуру экспорта.
  • Определение кластеризованного индекса в предварительно заполненной таблице занимает много места на диске. В моем тесте мой журнал
    перед завершением увеличился в 10 раз по сравнению с исходным размером таблицы.
  • При импорте большого количества записей с помощью оператора BULK INSERT включите параметр BATCHSIZE и укажите, сколько
    записей фиксировать за раз. Если вы не включите этот параметр,
    весь ваш файл импортируется как одна транзакция, что
    требует много места в журнале.
  • Самый быстрый способ поместить данные в таблицу с кластеризованным индексом - предварительно отсортировать данные. Затем вы можете импортировать его с помощью
    оператора BULK INSERT с параметром ORDER.

1

Есть необычный факт, который, кажется, упускается из виду.

" Обычно после вставки 30 миллионов строк в день мне нужно получить все строки с одним и тем же идентификатором GUID (может быть, 20 строк) и быть достаточно уверенным, что я верну их все. »

Если требуется всего 20 столбцов, некластеризованный индекс для GUID будет работать нормально. Вы можете выполнить кластеризацию в другом столбце для распределения данных по разделам.

У меня вопрос по вставке данных: как они вставляются?

  • Это массовая вставка по определенному расписанию (за минуту, за час и т. Д.)?
  • Из какого источника берутся эти данные (плоские файлы, OLTP и т. Д.)?

Я думаю, что на эти вопросы нужно ответить, чтобы понять одну сторону уравнения.


1

Amazon Redshift - отличный сервис. Он не был доступен, когда вопрос был первоначально опубликован в 2010 году, но теперь он является основным игроком в 2017 году. Это база данных на основе столбцов, созданная на основе Postgres, поэтому стандартные библиотеки соединителей SQL и Postgres будут работать с ней.

Его лучше всего использовать для отчетов, особенно для агрегирования. Данные из одной таблицы хранятся на разных серверах в облаке Amazon, распределяются по определенным таблицам distkeys, поэтому вы полагаетесь на распределенную мощность ЦП.

Итак, SELECT и особенно агрегированные SELECT работают молниеносно. Загрузку больших данных желательно производить с помощью команды COPY из файлов CSV Amazon S3. Недостатки в том, что DELETE и UPDATE выполняются медленнее, чем обычно, но именно поэтому Redshift в первую очередь не транснациональная база данных, а скорее платформа хранилища данных.


0

Вы можете попробовать использовать Cassandra или HBase, хотя вам нужно будет узнать, как создавать семейства столбцов в соответствии с вашим вариантом использования. Cassandra предоставляет собственный язык запросов, но вам необходимо использовать Java API HBase для прямого доступа к данным. Если вам нужно использовать Hbase, я рекомендую запрашивать данные с помощью Apache Drill из Map-R, который является проектом с открытым исходным кодом. Язык запросов Drill совместим с SQL (ключевые слова в Drill имеют то же значение, что и в SQL).


0

С таким количеством записей в год у вас в конечном итоге закончится место. Почему бы не использовать хранилище файловой системы, такое как xfs, которое поддерживает 2 ^ 64 файла и использует меньшие блоки. Независимо от того, насколько любопытные люди хотят получить или сколько денег они в конечном итоге потратят на получение системы с любой базой данных SQL NoSQL ... независимо от того, какое количество записей обычно делается электрическими компаниями и метеорологическими станциями / поставщиками, такими как министерство окружающей среды, которые контролируют меньшие станции по всей стране. Если вы делаете что-то вроде сохранения давления… температуры… скорости ветра… влажности и т. Д.… А guid - это местоположение… вы все равно можете разделить данные на год / месяц / день / час. Предполагая, что вы храните данные за 4 года на одном жестком диске. Затем вы можете запустить его на меньшем NAS с зеркалом, где он также обеспечит лучшую скорость чтения и будет иметь несколько точек монтирования. по году создания. Можно просто сделать веб-интерфейс для поиска Итак, выгрузка location1 / 2001/06/01 // температура и местоположение1 / 2002/06/01 // temperature будет сбрасывать только содержимое почасовой температуры для 1-го дня лета за эти 2 года (24 часа * 2) 48 небольших файлов по сравнению с поиском в базе данных с миллиардами записей и, возможно, миллионами потраченных. Простой способ взглянуть на вещи ... 1,5 миллиарда веб-сайтов в мире с Бог знает сколько страниц каждый. Если бы такой компании, как Google, пришлось бы тратить миллионы на 3 миллиарда поисков, чтобы платить за суперкомпьютеры, они бы разорились. Вместо этого у них есть счет за электроэнергию ... пара миллионов дерьмовых компьютеров. И индексация кофеина ... на будущее ... продолжайте добавлять. И да, там, где индексация с использованием SQL имеет смысл, тогда отлично. Создание суперкомпьютеров для дрянных задач с фиксированными вещами, такими как погода ... статистика и так далее, чтобы технические специалисты могли хвастаться, что их системы перехватывают xtb за x секунд ... трата денег, которая может быть провел в другом месте ..


-2

Хранить записи в простых двоичных файлах, по одному файлу на GUID, быстрее не будет.


5
Вы действительно ожидаете, что это будет хорошо?
ChaosPandion

3
Да, создание миллиардов файлов в файловой системе может быть разрушительным для некоторых файловых систем. Я совершил ошибку, сделав что-то вроде этого, но имея всего 1 миллион, я в значительной степени отключил систему, пытаясь открыть оболочку для одной из этих папок. Кроме того, как должен работать механизм запросов, если вы не ищете на основе guid?
Роб Гудвин

Трудно предположить, как это будет работать, не зная, сколько уникальных GUID ожидается :) Но нет ничего проще, чем просто запись в простые файлы. И единственным требованием были быстрые вставки и поиск по GUID.
Томас Кьёрнес,

Это может работать, но вы должны ограничить количество файлов в папке. Вам необходимо создать новую папку для n файлов. В качестве имени папки можно использовать подстроку guid.
TTT

1
да, существует ограничение на количество inodes для большого количества файловых систем, и я помню, что мы ограничились этим ограничением для файловой системы по умолчанию redhat .... ограничение составляло около 1 000 000 файлов или около того.
Дин Хиллер

-3

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

Шардинг в MongoDb еще не готов к производству.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.