Один поток чтения, один поток записи, n рабочих потоков - PullRequest
2 голосов
/ 09 декабря 2010

Я пытаюсь разработать фрагмент кода на Java, который сможет обрабатывать большие объемы данных, извлекаемых драйвером JDBC из базы данных SQL, а затем сохраняться обратно в БД.

Я думал о создании менеджера, содержащего один поток чтения, один поток записи и настраиваемое количество рабочих потоков, обрабатывающих данные. Поток читателей считывает данные в DTO и передает их в очередь с надписью «готово к обработке». Рабочие потоки будут обрабатывать DTO и помещать обработанные объекты в другую очередь, помеченную как «готовая к сохранению». Поток записи будет сохранять данные обратно в БД. Является ли такой подход оптимальным? Или, возможно, я должен позволить больше читателей для получения данных? Есть ли в Java готовые библиотеки для таких вещей, о которых я не знаю?

Ответы [ 5 ]

3 голосов
/ 09 декабря 2010

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

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

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

2 голосов
/ 09 декабря 2010

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

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

Будет ли этоМожно ли временно вставить любые внешние данные, с которыми вам нужно работать, в базу данных и выполнить всю обработку внутри базы данных?Это дает следующие преимущества:

  1. Это устраняет необходимость извлечения больших объемов данных
  2. Это устраняет необходимость сохранения больших объемов данных
  3. Это позволяетобработка на основе множеств (которая превосходит процедурную)
  4. Если ваша база данных поддерживает ее, вы можете использовать параллельное выполнение
  5. Она дает вам основу (таблицы и SQL) для создания отчетов о любых ошибкахвы сталкиваетесь во время процесса.

Чтобы привести пример.Давным-давно я реализовал (java) программу, цель которой состояла в том, чтобы загружать покупки, платежи и связанные данные клиентов из файлов в центральную базу данных.В то время (и я глубоко сожалею об этом) я спроектировал нагрузку для обработки транзакций по одной и для каждого фрагмента данных выполнял несколько операций поиска в базе данных (sql) и, наконец, несколько вставок в соответствующие таблицы.Естественно, это не масштабировалось после увеличения громкости.

Затем я сделал еще одну ошибку.Я решил, что проблема была в базе данных (потому что я услышал , что SELECT работает медленно), поэтому я решил вытащить все данные из базы данных и выполнить ВСЕ обработки в Java.И, наконец, сохранить все данные обратно в базу данных.Я реализовал все виды слоев с механизмами обратного вызова, чтобы легко расширить процесс загрузки, но я просто не мог заставить его работать хорошо.

Глядя в зеркало заднего вида, я должен был вставить (смехотворно небольшое количество) 100 000 строк временно в таблице, и обработать их оттуда.На то, что заняло почти полдня, заняло бы самое большее несколько минут, если бы я использовал все технологии, которыми располагал.

1 голос
/ 17 июня 2011

Используйте Spring Batch! Это именно то, что вам нужно

1 голос
/ 09 декабря 2010

Вы описываете написание чего-то похожего на функциональность, которую предоставляет Spring Batch. Я бы проверил это на твоем месте. Мне очень повезло, когда я выполнял операции, подобные тем, что вы описываете, используя его. Предоставляется параллельная и многопоточная обработка, а также несколько различных устройств чтения / записи баз данных и целый ряд других вещей.

1 голос
/ 09 декабря 2010

Альтернативой использованию явной очереди является наличие ExecutorService и добавление в него задач. Таким образом вы позволяете Java-менеджеру управлять пулом потоков.

...