Дизайн базы данных для больших наборов данных - PullRequest
1 голос
/ 23 марта 2019

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

Поскольку наши данные более актуальны, чем новее, мы можем разделить их на короткий промежуток времени (например, за последние 30 дней)и старый набор данных (старше, чем последние 30 дней).Для этого я вижу две возможности:

Разделение его на два раздела, текущий раздел и старый раздел данных

Преимущества:

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

Недостатки:

  • Сценарии миграции (измените таблицу, мы можем использовать онлайн, но это не работает с каждым вариантом использования, если я правильно понял) занимает много времени, так как они по-прежнему работают с обоими разделами.Решением этой проблемы было бы отключить старый раздел данных для пользователя и запустить его в фоновом режиме.Таким образом, пользователь не будет иметь доступа в течение этого времени к старым данным, но это будет нормально.Возможно ли что-то подобное?

Разделение вручную на две таблицы и перемещение данных с ночной работой.На вершине мы помещаем представление для выбора данных

Преимущества:

  • Мы можем отключить старую таблицу данных, не включая ее в представление, и запустить сценарии изменения таблицы.Как только это будет сделано, верните его в поле зрения.Поскольку пользователь больше не сможет найти данные, он также не сможет их изменить
  • Восстановление таблицы будет быстрым, поскольку мы сначала восстановим текущую таблицу, обновим представление и позволим пользователю использовать ееснова.Восстановление старой таблицы данных займет некоторое время, но это нормально

Недостатки:

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

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

Спасибо

Ответы [ 2 ]

1 голос
/ 23 марта 2019

Немного сотен миллионов - это много, но на сегодня не большой набор данных .Большие наборы данных имеют миллиарды записей.Вопрос здесь в том, я думаю, как быстро растут ваши данные? и какой тип запроса вы выполняете против него? Если ваши данные растут очень медленно, любое программное обеспечение базы данных может справиться с этимсумма достаточно быстро, даже без раздела.Если он быстро растет, неплохо было бы создать несколько разделов.

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

Если недавний означает очень короткий период, например 1 месяц, тоМетод не достаточно, хотя все еще полезно.Итак, вы можете создать еще одну таблицу горячих данных поверх нее.Теперь у вас есть большая таблица данных, разделенная по годам (в которой всегда есть все данные), и небольшая таблица, в которой есть последние данные.Чтобы преодолеть недостатки, вы можете сделать это:

  • ОБНОВЛЕНИЕ / ВСТАВИТЬ / УДАЛИТЬ
  • Все запросы идут в основную таблицу;триггер для каждой операции будет дублировать операцию в таблице горячих данных, если это необходимо.(логика уровня базы данных)
  • Или вы можете отправить соответствующие запросы в обе таблицы и убедиться, что они согласованы на уровне приложения (логика уровня приложения).Этот может быть более производительным, так как триггеры mysql могут еще больше замедлить работу базы данных.

  • Запросы SELECT будут переходить в новую таблицу в зависимости от запроса, в противном случае основная таблица (здесь помогает разбиение по годам дляспектакль).Разделение запросов также может быть выполнено с помощью прокси, если вы хотите быть гибкими. Proxysql справится с этим легко.У него есть и другие преимущества, такие как кэширование и мультиплексирование соединений.

  • Чтобы отбросить более старые данные из таблицы горячих данных, вы можете каждый день выполнять событие для удаления записей старше 1 месяца.Если вам нужно удалить десятки тысяч, вы должны удалить их небольшими порциями, чтобы избежать таких проблем, как блокировка, отставание и большое потребление ресурсов.Другим способом может быть использование столбца is_deleted для идентификации устаревших записей и разбиения по ним.Удаление раздела в любое время происходит мгновенно.

Для неблокирующих операций DDL существуют инструменты с открытым исходным кодом для миграции вашей схемы в режиме онлайн без значительного снижения производительности.Проверьте pt-schema-change и ghost .

0 голосов
/ 07 мая 2019

(Фокус на старых и новых данных)

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

Обязательно используйте InnoDB и пусть PRIMARY KEY будет AUTO_INCREMENT (или начинаться с DATETIME).

Давайте запустим несколько чисел. Если в таблице 300 миллионов строк, и каждая строка занимает 100 байтов (простое правило), то данные таблицы занимают 30 ГБ. Там будет еще несколько для индексов и других таблиц. Если вы работаете на сервере с 64 ГБ ОЗУ (вполне разумно сегодня ), то все может уместиться в ОЗУ и не требует большого количества операций ввода-вывода.

Если вместо этого у вас было только 8 ГБ ОЗУ и большая часть активности была в последних 10% таблицы, то, опять же, она будет хорошо кэширована.

(Примечание: I / O является самым большим аппаратным компонентом производительности.)

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

Вы упомянули грубый, ручной способ разбиения таблицы. Есть что-то встроенное: PARTITIONing. Но это , а не , вероятно, поможет вставить, обновить или выбрать, поэтому я не рекомендую это делать без дальнейшего обсуждения.

Если вы в конечном итоге очистите «старые» данные (скажем, через год), то PARTITIONing - это хорошая идея. Я бы использовал еженедельные разделы, если таблица будет содержать данные только за 1 год. Мы можем обсудить это дальше, если вам это нужно. Но обратите внимание, что единственным преимуществом является удаление старых данных с помощью DROP PARTITION; разметка есть.

SUBPARTITIONs не помогают никому.

...