Mysql: работа с 192 триллионами записей ... (да, 192 триллиона)

39

Вот вопрос ...

Учитывая мои 192 триллиона записей, какими должны быть мои соображения?

Моя главная забота - скорость.

Вот таблица ...

    CREATE TABLE `ref` (
  `id` INTEGER(13) AUTO_INCREMENT DEFAULT NOT NULL,
  `rel_id` INTEGER(13) NOT NULL,
  `p1` INTEGER(13) NOT NULL,
  `p2` INTEGER(13) DEFAULT NULL,
  `p3` INTEGER(13) DEFAULT NULL,
  `s` INTEGER(13) NOT NULL,
  `p4` INTEGER(13) DEFAULT NULL,
  `p5` INTEGER(13) DEFAULT NULL,
  `p6` INTEGER(13) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY (`s`),
  KEY (`rel_id`),
  KEY (`p3`),
  KEY (`p4`)
    );

Вот вопросы ...

SELECT id, s FROM ref WHERE red_id="$rel_id" AND p3="$p3" AND p4="$p4"

SELECT rel_id, p1, p2, p3, p4, p5, p6 FROM ref WHERE id="$id"

INSERT INTO rel (rel_id, p1, p2, p3, s, p4, p5, p6)
VALUES ("$rel_id", "$p1", "$p2", "$p3", "$s", "$p4", "$p5", "$p6")

Вот несколько заметок ...

  • ВЫБОР будет выполняться гораздо чаще, чем ВСТАВКА. Однако иногда я хочу добавить несколько сотен записей одновременно.
  • Что касается нагрузки, то в течение нескольких часов не будет ничего, а может быть, несколько тысяч запросов одновременно.
  • Не думаю, что я могу нормализовать больше (нужно, чтобы значения p в комбинации)
  • База данных в целом очень реляционная.
  • Это будет самая большая таблица на данный момент (следующая по величине - около 900 тыс.)

ОБНОВЛЕНИЕ (08/11/2010)

Интересно, что мне дали второй вариант ...

Вместо 192 триллионов я мог бы хранить 2,6 * 10 ^ 16 (15 нулей, что означает 26 квадриллионов) ...

Но во втором варианте мне нужно будет хранить только один bigint (18) в качестве индекса в таблице. Вот и все - только один столбец. Поэтому я бы просто проверил наличие значения. Время от времени добавляя записи, никогда не удаляя их.

Это заставляет меня думать, что должно быть лучшее решение, чем mysql для простого хранения чисел ...

Учитывая этот второй вариант, я должен взять его или придерживаться первого ...

[edit] Только что получили новости о каком-то тестировании, которое было выполнено - 100 миллионов строк с этой настройкой возвращают запрос за 0,0004 секунды [/ edit]

Сара
источник
7
Насколько вы настроены на использование MySQL для этого? Можете ли вы быть уверены, что переключитесь на другую базу данных, если кто-то предоставит веские аргументы для этого?
WheresAlice
3
Триллион как в 10 ^ 12 или как в 10 ^ 18?
андол
15
При 192 триллионах записей у вас должен быть бюджет, позволяющий задавать вопросы коммиттерам MySQL, а не некоторым дискуссионным форумам.
Ремус Русану
5
С такой большой базой данных (и, очевидно, приличным бюджетом), почему бы не использовать решение oracle или sql serer, которое, как было доказано, легко обрабатывает большие БД?
Джим Б
5
Будьте уверены, чтобы держать нас в курсе, когда вы реализуете это. Я конечно был бы заинтересован. Вы также можете написать это для highscalability.com
Том О'Коннор

Ответы:

30

Оценка pQd в 7PB кажется разумной, и это много данных для RDBMS. Я не уверен, что когда-либо слышал о том, чтобы кто-то делал 7PB с любой системой с общим диском, не говоря уже о MySQL. Запрашивать этот объем данных с любой общей дисковой системой будет необычайно медленно. Самое быстрое оборудование SAN достигает максимальной скорости 20 ГБ / с даже при настройке для больших потоковых запросов. Если вы можете позволить себе оборудование SAN этой спецификации, вы можете использовать что-то более подходящее для работы, чем MySQL.

Фактически, я изо всех сил пытаюсь придумать сценарий, в котором вы могли бы иметь бюджет для дисковой подсистемы этой спецификации, но не для лучшей платформы СУБД. Даже при использовании 600-Гбайт дисков (самый большой из имеющихся на рынке 15 тыс. Накопителей корпоративного уровня) вы можете получить около 12 000 физических дисков для хранения 7PB. Диски SATA будут дешевле (а с дисками объемом 2 ТБ вам потребуется около 1/3 от их количества), но немного медленнее.

SAN этой спецификации от крупного поставщика, такого как EMC или Hitachi, обойдется во многие миллионы долларов. В прошлый раз, когда я работал с оборудованием SAN от крупного поставщика, стоимость передачи пространства на IBM DS8000 составляла более 10 тыс. Фунтов стерлингов / ТБ, не включая капитальные надбавки на контроллеры.

Для такого большого количества данных вам действительно нужна система без совместного использования, например Teradata или Netezza. Разделение базы данных MySQL может работать, но я бы порекомендовал специально созданную платформу VLDB. Система без доступа к общим ресурсам также позволяет вам использовать гораздо более дешевый диск прямого подключения к узлам - посмотрите на платформу Sun X4550 (thumper) для одной возможности.

Вы также должны подумать о своих требованиях к производительности.

  • Какова приемлемая продолжительность выполнения запроса?
  • Как часто вы будете запрашивать ваш набор данных?
  • Может ли большинство запросов быть решено с использованием индекса (то есть, они собираются посмотреть на небольшую часть - скажем, менее 1% - данных), или им нужно выполнить полное сканирование таблицы?
  • Как быстро данные будут загружены в базу данных?
  • Ваши запросы нуждаются в актуальных данных или вы можете использовать периодически обновляемую таблицу отчетов?

Короче говоря, самым сильным аргументом против MySQL является то, что вы будете делать backflips, чтобы получить приличную производительность запросов свыше 7PB данных, если это вообще возможно. Этот объем данных действительно ставит вас в область без общего доступа, чтобы создать что-то, что будет запрашивать его достаточно быстро, и вам, вероятно, понадобится платформа, которая с самого начала была разработана для работы без общего доступа. Одни только диски значительно уменьшат стоимость любой разумной платформы СУБД.

Примечание. Если вы разделяете свои операционные и отчетные базы данных, вам не обязательно использовать одну и ту же платформу СУБД для обеих. Получение быстрых вставок и отчетов за доли секунды из одной таблицы 7PB будет, по крайней мере, технической задачей.

Исходя из ваших комментариев о том, что вы можете жить с некоторой задержкой в ​​отчетности, вы можете рассмотреть отдельные системы сбора и отчетности, и вам может не потребоваться хранить все 7PB данных в вашей операционной системе захвата. Рассмотрим операционную платформу, такую ​​как Oracle (MySQL может сделать это с InnoDB) для захвата данных (опять же, стоимость одних только дисков приведет к снижению стоимости СУБД, если у вас нет большого количества пользователей) и платформы VLDB, такой как Teradata, Sybase IQ, RedBrick, Netezza (примечание: проприетарное оборудование) или Greenplum для отчетности

ConcernedOfTunbridgeWells
источник
1
@ConcernedOfTunbridgeW - они всегда могут пойти по этому пути: blog.backblaze.com/2009/09/01/… - гораздо веселее, чем SAN, нужно всего ~ 120-130 коробок 4U ... но я не уверен, что бизнес был бы счастлив ....
pQd
По сути, это Sun Thumper с ограниченным бюджетом и действительно пример варианта для узла в системе без совместного использования ресурсов. Я уверен, что я видел другие варианты для этого, но я не могу думать о том, где. Вопрос не столько в том, какое оборудование, сколько в платформе базы данных.
ConcernedOfTunbridgeWells
Тем не менее, проницательные наблюдатели заметят, что любой вид коробки на основе прямого присоединения, такой как этот, намного, намного дешевле на ТБ, чем что-либо на основе SAN, что является по крайней мере одним существенным аргументом в пользу чего-то, предназначенного для работы на платформе без общего доступа ,
ConcernedOfTunbridgeWells
@ConcernedOfTunbridgeWells, и вы можете запускать все эти запросы / обслуживание и все остальное параллельно на нескольких [иначе потребляющих энергию] блоках.
2010 г.,
1
@ConcernedOfTunbridgeWells - чтобы ответить на ваши вопросы ... Мне нужно около 500 запросов, чтобы вернуться за секунду, если это возможно. Я буду делать это только несколько сотен раз в день. Однако при выполнении запроса необходимо проверить всю таблицу. Кроме того, INSERT имеют более низкий приоритет, чем SELECT, поэтому он не должен быть где-то близко к мгновению. Я могу подождать несколько часов, пока «новые» данные попадут в базу данных.
Сара
16

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

простая обратная сторона вычисления конверта - предполагается, что 32-битные целые числа для всех столбцов, кроме 64-битного идентификатора; индексы не включены:

8 * 4B + 8B = 40B на строку [и это очень оптимистично]

192 триллиона строк по 40В каждый дает нам почти 7 ПБ

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

вопросы для ответа:

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

случайные ссылки - скорость вставок:

PQD
источник
Я согласен - 7PB довольно тяжелый. Я бы с удовольствием переосмыслил это и нашел бы более легкое решение, но мне нужно найти и найти существование (или небытие) определенной комбинации полей p. Разделение таблиц пришло мне в голову - это более разумно, но тогда это просто означает, что я получил запрос к каждой таблице по очереди. Из интереса, сколько таблиц вы бы порекомендовали разбить на здесь?
Сара
5
@ Сара - я бы порекомендовал не только разбивать на таблицы, но и машины. Вы можете выполнять свои запросы параллельно, чтобы повысить производительность [я делаю это в меньшем масштабе]. как насчет повреждений файловой системы или даже обычной проверки после перезагрузки сервера? я не уверен, что вы имеете в виду, находя определенную комбинацию ... может быть, простое хранилище значений ключей поможет? размер таблицы - не более нескольких десятков ГБ; данные на одном сервере - не более нескольких ТБ. посмотрите на stackoverflow.com/questions/654594, чтобы узнать, какую головную боль ожидать в гораздо меньшем масштабе; используйте innodb_file_per_table
2010 г.,
2

Может быть и другой способ, вместо того, чтобы хранить квадриллионы чисел, если все, что вы хотите сделать, это посмотреть, есть ли они в наборе. Фильтры Блума - вероятностный метод, хеширующий несколькими способами. Также возможны ложные срабатывания, а ложные - нет. (Таким образом, он может сказать, что номер в наборе - и ошибаться, но он не скажет, что его нет, если он действительно был). Существует также проблема огромного количества предметов для хранения, но, по крайней мере, это может несколько уменьшить размер рабочего набора данных.

Алистер Булман
источник
Звучит интересно, хотя я мог бы жить с ложными негативами - но не с ложными позитивами :)
Сара
2

Изменить: На самом деле, если это просто наличие или отсутствие «записи» в расположении X в диапазоне целых чисел, вы можете удалить хранилище данных и просто использовать растровое изображение ... Итак, 10 или около того машин с 100 ТБ дискового пространства (таким образом, у вас есть 10 копий вашего растрового изображения для повышения производительности и резервного копирования), и если бы вы использовали 128 ГБ ОЗУ на сервер, вы могли бы поместить в память индекс блочной группы верхнего уровня с высоким разрешением, чтобы выполнить первую проверку перед загрузкой диска на бит Х из 26 квадриллионов. ,

Я бы пошел на вариант № 2, если вы берете:

375 машин с 64 ТБ (32 диска по 2 ТБ) каждая (реально 400 машин для сбоев) затем просто отображают записи на ZVOL, каждый по 2 ТБ. Затем на одном или нескольких индексных серверах сохраните их в массиве Джуди или в массиве критических битов, или просто в растровом изображении, отображающем, добавили ли вы запись в 1 из 26 квадриллионных местоположений. Индекс будет между 50 и 100 ТБ, и вы даже можете иметь индекс второго уровня, указывающий, что есть записи, записанные в определенный блок адресов 64 КБ, которые поместятся в менее чем 64 ГБ ОЗУ и обеспечат быстрый уровень начальной проверки. был ли определенный "район" пустым или нет.

Затем, чтобы прочитать эту запись, вы сначала проверите, есть ли запись для поиска, посмотрев на индекс. Если есть, то перейдите к машине # (X) / ZOL # (Y) на этой машине / месте записи # (Z) в этом двоичном объекте размером 2 ТБ на основе простого вычисления индекса. Поиск по одной записи был бы чрезвычайно быстрым, и вы могли бы протестировать загрузку некоторых частей хранилища данных в разные базы данных (пока вы используете хранилище данных для реальной работы) и провести тестирование производительности, чтобы увидеть, способны ли они поддерживать всю вашу базу данных - или нет, просто используйте хранилище данных таким образом.

ZOL - это ZFS, который можно рассматривать как разреженный файл в других файловых системах, поэтому применимы аналогичные вещи. Или вы можете просто индексировать до определенного числа байтов на диске, но это становится сложнее, если диски имеют разные размеры, если вы не ограничиваете количество байтов, используемых на диск, на уровне, который работает для всех дисков - то есть 1,75 ТБ на диск 2 ТБ. , Или создайте метаустройства фиксированного размера и т. Д.


источник
Привет Сара - не уверен, что вы все еще работаете над этим, но если вам нужна помощь, я мог бы прототипировать вашу идею для вас на компьютере объемом 100 ТБ, а также был бы готов разместить (в крупном центре обработки данных в США) и управлять полным производственным кластером 400-500 машин по мере необходимости. Кстати, ты когда-нибудь работал в CNET в SF?
1

Помимо настройки параметров вашей БД как сумасшедших (используйте mysqltuner, чтобы помочь), чтобы попытаться сохранить кэширование SELECT настолько, насколько это возможно, вы можете исследовать одну вещь - START TRANSACTION / CoMMIT (при условии InnoDB) при вставке ваших нескольких сотен записей, чтобы избежать ряд за строкой накладные расходы и сократить время вставки на огромный фактор. Я бы также создал таблицу как MyISAM и InnoDB и запустил на ней тесты, чтобы увидеть, что действительно быстрее, когда вы затянете кеширование - не всегда MyISAM будет быстрее для чтения - проверьте это:

http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/

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

Кроме того, если вы используете файл-таблицу MyISAM и / или InnoDB, вы можете исследовать создание другой точки монтирования файловой системы для / var / lib / mysql, которая была настроена на меньший размер блока и настроила параметры типа fs - то есть ext3 / ext4 / resiserfs вы можете использовать data = writeback для журнала и отключить обновление времени доступа в файловой системе для скорости ввода-вывода.

troyengel
источник
1
myisam, кажется, не подлежит обсуждению из-за требований транзакции.
2010 г.,
0

Для второго варианта, сколько номеров, вероятно, будет фактически размещено?

Если будет одна единица из тысячи, или 10 КБ, 100 КБ и т. Д., То сохранение диапазонов используемых (или неиспользованных) чисел может сэкономить триллионы записей. Например: хранение («бесплатно», 0,100000), («занято», 100000,100003), («свободно», 100004,584234) - разделение строк на две или три строки по мере необходимости и индексация по первому числу, ищем x <= {needle}, чтобы узнать, занят ли диапазон, содержащий искомый номер, или свободен.

Вам может даже не понадобиться оба статуса. Просто сохраните любой статус, который наименее вероятен.

Алистер Булман
источник