Назад | Перейти на главную страницу

Массовый импорт в AWS Aurora - экспоненциальное время вставки

Мы пытаемся загрузить в aurora файл большой таблицы (358M записей, 160GB без сжатия). Мы пробовали несколько комбинаций, но похоже, что она не дает того, что мы хотим.

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

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

Таблица

Таблица клиентов с customer_id в качестве первичного ключа, большое целое число. У нас есть еще четыре внешних ключа - назовем их fk1, fk2, fk3, fk4 - все большие целые числа. Нам нужны только эти столбцы, а не фактические внешние ключи.

Кроме того, у нас есть еще 40 столбцов - в основном varchars и некоторые временные метки.

Подход №1: без первичных ключей / индексов

Сервер - db.r3.large Клиент - m4.large, экземпляр Amazon linux

Мы создали схему таблицы БЕЗ первичного ключа или индексов. Мы запустили mysqlimport для всего файла размером 160 ГБ. На загрузку базы данных ушло около 3 часов.

После этого мы запустили таблицу изменений для создания первичного ключа. Ошибка с сообщением об ошибке «ОШИБКА 1114 (HY000): таблица заполнена».

Мы полагали, что это произошло потому, что эфемерный диск был заполнен (см. https://forums.aws.amazon.com/message.jspa?messageID=691512#691512), поэтому мы обновили сервер базы данных до db.r3.xlarge. Мы снова столкнулись с той же ошибкой и отказались от попыток создать первичный ключ после вставки записей.

Подход №2: разделение и предварительная сортировка данных

Затем мы решили разделить таблицу клиентов, надеясь, что это поможет. Мы хотим разделить на FK1, поэтому в итоге мы переопределили наши первичные ключи как (FK1, customer_id), чтобы учесть правила разделения MySQL.

Затем мы отсортировали наши входные файлы в соответствии с FK1, customer_id, а затем разделили файлы на фрагменты по 10 миллионов записей на файл.

Мы создали схему с первичным ключом (FK1, customer_id) и разделом на FK1.

Наконец, мы импортировали 36 файлов в однопоточном цикле. Мы устанавливаем следующие свойства подключения -

SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET SESSION tx_isolation='READ-UNCOMMITTED';

Изначально каждый файл завершается за 10 минут (то есть со скоростью 1 млн вставок в минуту). Однако где-то после 100 миллионов записей время обработки каждого файла продолжало расти экспоненциально. 13-й файл занял 16 минут, 20-й файл - 175 минут, а 21-й файл - около 280 минут. В тот момент мы сдались.

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

Текущее состояние

Мы отказались от попыток создать первичный ключ и многораздельные таблицы. Вместо этого мы просто создали неуникальный индекс для customer_id.

Есть какие-нибудь подсказки о том, что мы можем сделать, чтобы вставить записи вместе с первичным ключом?