Загрузка данных в YDB

В данном разделе предоставлены рекомендации по эффективной загрузке данных в YDB.

Существуют антипаттерны и неоптимальные настройки загрузки данных, при использовании которых не может гарантироваться приемлемая производительность загрузки данных в БД.
Для увеличения скорости загрузки данных нужно учесть следующие рекомендации:

  • Следует шардировать таблицу при её создании, чтобы сразу после начала загрузки данных эффективно использовать пропускную способность системы.

    По умолчанию созданная таблица состоит из одного шарда. YDB поддерживает автоматическое шардирование таблицы по объему данных, т.е. при достижении определенного размера шард таблицы разделяется на два шарда.
    Приемлемый размер для деления шарда таблицы — 2 ГБ. С увеличением количества шардов пропускная способность загрузки данных увеличивается, но некоторое время с начала пропускная способность будет низкой.
    Поэтому при первичной заливке большого объема данных рекомендуется создавать таблицу, сразу состоящую из желаемого количества шардов. Количество шардов можно подсчитать исходя из 1 ГБ данных на шард в результирующем наборе.

  • Вставка нескольких строк в каждой транзакции для уменьшения доли накладных расходов самих транзакций.

    Каждая транзакция в YDB имеет некоторые накладные расходы. Для уменьшения суммарных накладных расходов следует делать транзакции, вставляющие много строк. К хорошим показателям производительности приводит завершение транзакции при достижении объема в 1 МБ данных или 100000 строк.
    При загрузке данных избегайте транзакций, состоящих из вставки одной строки.

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

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

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

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

  • Следует избегать записи последовательно в порядке возрастания или убывания первичного ключа.

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

  • В некоторых сценариях требуется записать в таблицу первоначальные данные (зачастую большого объема) прежде чем включать OLTP-нагрузку. В таком случае не требуется транзакционность на уровне отдельных запросов и можно воспользоваться вызовом BulkUpsert в CLI, SDK и API. За счёт отказа от транзакционности такой подход имеет значительно меньшие накладные расходы по сравнению с YQL запросами. В случае успешного ответа на запрос, метод BulkUpsert гарантирует фиксацию всех данных, записанных в рамках данного запроса.

Важно

Метод BulkUpsert не поддерживается для таблиц с вторичными индексами.

Исходя из данных рекомендаций можно предложить следующий алгоритм действий для эффективной загрузки данных в YDB:

  1. Создайте таблицу, состоящую из желаемого количества шардов, исходя из 1 ГБ данных на шард.
  2. Отсортируйте исходный набор данных по предполагаемому первичному ключу.
  3. Разделите полученный набор данных на части по количеству шардов таблицы. Каждая часть будет состоять из набора последовательно расположенных строк.
  4. Полученные части загружайте в шарды таблицы параллельно.
  5. Делайте COMMIT после каждых 100000 строк или 1 МБ данных.