Учебник об использовании многопоточности в jdbc - PullRequest
15 голосов
/ 25 августа 2011

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

В этом приложении определено более 20 задач, каждая из которыхможет зависит от других или нет.Приложение выполняет задачи одну за другой, все приложение выполняется в одном потоке.

Для выполнения всех задач требуется от 3 до 7 часов.Я думаю, что это слишком долго, поэтому я думаю, что, возможно, я смогу улучшить производительность с помощью многопоточности.

Я думаю, поскольку существует зависимость между задачами, не очень хорошо (или это нелегко) заставить задачи выполняться параллельно,но, возможно, я могу использовать многопоточность для повышения производительности внутри задачи.

например: у нас есть задача, определенная как «ImportBizData», которая копирует данные в таблицу базы данных из файла данных (обычно содержит 100,0000+ строк).Интересно, стоит ли использовать многопоточность?

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

Ответы [ 7 ]

21 голосов
/ 25 августа 2011

Многопоточность улучшит вашу производительность, но есть несколько вещей, которые вам нужно знать:

  1. Каждый поток требует своего собственного соединения JDBC.Соединения нельзя разделить между потоками, поскольку каждое соединение также является транзакцией.
  2. Загружайте данные порциями и commit время от времени, чтобы избежать накопления огромных таблиц отката / отмены.
  3. Разбейте задачи на несколько рабочих блоков, где каждый блок выполняет одну работу.

Чтобы проработать последний пункт: В настоящее время у вас есть задача, которая читает файл, анализирует его, открывает соединение JDBC, выполняет некоторые вычисленияотправляет данные в базу данных и т. д.

Что нужно сделать:

  1. Один (!) поток, чтобы прочитать файл и создать из него «задания».Каждая работа должна содержать небольшую, но не слишком маленькую «единицу работы».Поместите их в очередь
  2. Следующие потоки ожидают задания в очереди и выполняют вычисления.Это может произойти, пока потоки на шаге 1 ждут, когда медленный жесткий диск вернет новые строки данных.Результат этого шага преобразования переходит в следующую очередь
  3. Один или несколько потоков для загрузки данных через JDBC.

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

Использование различных рабочих потоков дает множество преимуществ:

  1. Это легкопроверить каждую нить отдельно.Поскольку они не обмениваются данными, вам не нужна синхронизация.Очереди сделают это за вас
  2. Вы можете быстро изменить количество потоков для каждого шага, чтобы настроить производительность
5 голосов
/ 25 августа 2011

Многопоточность может помочь, если строки не коррелированы, вы можете запустить два процесса: одно чтение четных строк, другое - неровные строки, а также получить соединение db из пула соединений (dbcp) и проанализировать производительность.Но сначала я бы выяснил, является ли jdbc лучшим подходом, обычно базы данных имеют оптимизированные решения для импорта, подобные этому.Эти решения также могут временно отключить проверку ограничений вашей таблицы и включить ее позже, что также очень важно для производительности.Как всегда в зависимости от ваших требований.

Также вы можете оформить заказ на подпружиненный пакет, предназначенный для пакетной обработки.

0 голосов
/ 17 января 2017

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

  1. Создайте файл java для чтения файлов, целью которого является чтение файла biz и помещение сообщений в очередь JMS на сервере. Это может быть обычная Java со статическим void main ()
  2. Использование сообщений JMS в компонентах, управляемых сообщениями (вы можете установить ограничение на количество компонентов, создаваемых в пуле, 50 или 100 в зависимости от необходимости), если у вас есть несколько серверов, и ваша работа теперь разделен на несколько серверов.
    1. Каждая строка данных асинхронно распределяется между 2 серверами и 50 компонентами на каждом сервере.

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

Кроме того, весна предоставляет пружинную партию, которая может помочь вам. http://docs.spring.io/spring-batch/reference/html/spring-batch-intro.html#springBatchUsageScenarios

0 голосов
/ 23 августа 2013

Самый быстрый способ вставки большого количества записей в Oracle - это операции с массивами. См. Метод setExecuteBatch, который специфичен для OraclePreparedStatement. Это описано в одном из примеров здесь: http://betteratoracle.com/posts/25-array-batch-inserts-with-jdbc

0 голосов
/ 18 января 2013

У меня было похожее задание . Но в моем случае все таблицы не были связаны друг с другом.

STEP1: Использование SQL Loader (Oracle) для загрузки данных в базу данных (очень быстро) ИЛИ аналогичные инструменты массового обновления для вашей базы данных.

STEP2: Запуск каждого процесса загрузки в отдельном потоке (для не связанных задач) и в одном потоке для связанных задач.

P.S. Вы можете определить различные взаимосвязанные задания в вашем приложении и распределить их по группам; и запуск каждой группы в разных потоках.

Ссылки для вас:

JAVA Threading следуйте последнему примеру в приведенной выше ссылке (пример: разбиение большой задачи на несколько потоков)

SQL Loader может значительно повысить производительность

0 голосов
/ 25 августа 2011

Я не так уж хорошо знаком с JDBC, но в отношении многопоточности вашего вопроса вам следует иметь в виду, что параллельная обработка основана на эффективном разделении вашей проблемы на биты, которые не зависят друг от друга, и в некотором роде их размещенииобратно вместе (их вывод, который есть).Если вы не знаете основных зависимостей между задачами, в вашем коде могут возникнуть действительно странные ошибки / исключения.Хуже того, все может выполняться без проблем, но результаты могут отличаться от истинных значений.Многопоточность - дело сложное, в некотором смысле забавное обучение (по крайней мере, я так думаю), но боль в шее, когда дела идут на юг.

Вот несколько ссылок, которые могут быть полезны:

Если вы серьезно относитесь к тому, чтобы приложить усилия для перехода в многопоточность, я могу порекомендоватьГЕТЦ, БРИАН: JAVA CONCURRENCY, удивительная книга действительно ..

Удачи

0 голосов
/ 25 августа 2011

Насколько я знаю, в JDBC Bridge используются синхронизированные методы для сериализации всех вызовов ODBC, поэтому использование потоков с несколькими переменными не даст вам никакого повышения производительности, если только оно не повысит само ваше приложение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...