Весенний пакет: как быстро вставить 1 миллион сообщений из Kafka в таблицу

Вопрос или проблема

Я пишу вам это сообщение, потому что немного запутался и не знаю, как решить свою проблему.

Контекст

  • SimpleJob(SingleThread) в Spring Batch, который обрабатывает 1 миллион сообщений из темы (внутренний надежный источник) в 7 утра каждое утро
  • и вставляет их (по одному) в промежуточную таблицу (A)
  • Затем читает строки из A партиями по 1000 строк и вставляет эти строки (по одному) в целевую таблицу B

Технологии

JAVA 17, Spring Batch, MySQL

Проблема

Задание занимает 23 часа для завершения. Я хотел бы уменьшить время до менее чем 2 часов

Предложения по улучшению

  • Удаление промежуточной таблицы: Это позволит сократить количество SELECT/INSERT до 1 миллиона. Я спрашивал бывших разработчиков, есть ли причины для сохранения этой таблицы (не используется где-либо еще).
  • ИСПОЛЬЗОВАНИЕ МАССОВОЙ ВСТАВОКИ: Я читал, что это может помочь повысить производительность
  • Увеличение размера партии (интервал коммита): Партия из 1000 кажется слишком маленькой, и поэтому больше SELECT/INSERT. Размер чанка необходим для избежания ошибок OutOfMemory Java Heap Space. Но я не знаю, как определить правильный размер партии, кроме как случайным образом тестируя значения

Вопросы

  • Вы видите какие-либо обоснованные причины для сохранения промежуточной таблицы в данном случае?
  • Вы знаете, как мне следует proceder для определения правильного размера партии?
    • Существуют ли какие-либо стандарты по значениям?
    • Могу ли я просто пробовать случайные значения, пока не достигну приемлемого времени выполнения?
  • Думаете, что попытка разделенного задания/многопоточных заданий может быть полезной в моем случае? Или это будет излишне?
    • Поскольку все потоки будут записывать в одну и ту же базу данных (возможное узкое место?)

Большое спасибо заранее за вашу помощь!

Ответ или решение

Ответ на ваш вопрос о Spring Batch и вставке 1 миллиона сообщений в таблицу требует комплексного подхода. Давайте рассмотрим возможностии рекомендации по улучшению производительности вашего процесса.

Контекст и проблемы

Вы используете Spring Batch для обработки 1 миллиона сообщений из Kafka, и вся ваша задача делится на два основных этапа:

  1. Вставка сообщений в промежуточную таблицу (A)
  2. Чтение из промежуточной таблицы и вставка в целевую таблицу (B)

Занимаемое время в 23 часа — это очень долго, и есть несколько путей для его сокращения.

Рекомендуемые улучшения

1. Удаление промежуточной таблицы

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

2. Использование массовой вставки (Bulk Insert)

Массированные вставки значительно увеличивают производительность. Вместо вставки одной строки каждый раз, вы можете использовать расширенные функции MySQL, такие как INSERT ... VALUES, чтобы вставить десятки или сотни строк сразу.

Пример:

INSERT INTO table_name (column1, column2) VALUES (value1, value2), (value3, value4), ...;

В Spring Batch это можно реализовать с помощью JdbcBatchItemWriter, который поддерживает эти возможности.

3. Увеличение размера пачки

Увеличение размера пакета (chunk size) также может привести к снижению времени выполнения. Размер 1000 кажется небольшим для вашего случая. Вы можете начать с увеличения до 5000 или 10000 и поэкспериментировать с различными значениями, чтобы найти оптимальное.

Как определить оптимальный размер пачки?
  • Тестирование: Запускайте тесты на выборках данных с различными размерами пакетов и фиксируйте время выполнения.
  • Мониторинг: Обратите внимание на использование памяти. Если программа начинает вызывать ошибки OutOfMemory, это может быть знаком, что вы превышаете разумные пределы.
  • Стандартные значения: Обычно размер пакета от 1000 до 10000 считается нормой для большинства приложений, но это всегда зависит от вашей конкретной системы и ее конфигурации.

4. Параллелизация задания

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

Возможные проблемы:
  • Боттленки ввода-вывода: Если все потоки пытаются записывать информацию одновременно, это может стать узким местом. Протестируйте свою архитектуру, чтобы проверить, насколько она справляется с параллельными операциями.

Заключение

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

Надеюсь, эти советы помогут вам резко сократить время выполнения вашего задания. Если у вас возникнут дополнительные вопросы или нужна помощь, пожалуйста, дайте знать!

Оцените материал
Добавить комментарий

Капча загружается...