2012-02-29 2 views
1

У меня есть пакет Java, который делает выбор с большим resulset (я обрабатываю элементы, используя Spring callbackhandler). Обработчик обратного вызова ставит задачу в фиксированном threadpool для обработки строки. My poolize фиксирован на 16 потоках. Resulset содержит около 100 тыс. Элементов. Весь код доступа db обрабатывается через JdbcTemplate или через Hibernate/Spring, при этом отсутствует управление ручным подключением. Я пробовал с Atomikos и с Commons DBCP в качестве пула соединений.java connection pool, сколько максимальных соединений в многопоточной партии?

Теперь, я думаю, что 17 максимальных соединений в моем соединении будет достаточно, чтобы завершить эту партию. Один для выбора и 16 для потоков в пуле соединений, которые обновляют некоторые строки. Однако это кажется слишком наивным, поскольку я должен указать максимальный размер пула на величину больше (не пробовал для точного значения), сначала я попытался 50, который работал на моей локальной машине Windows, но, похоже, достаточно для нашей тестовой среды Unix. Там я должен указать 128, чтобы заставить его работать (опять же, я даже не пытался использовать значение от 50 до 128, я сразу пошел на 128).

Это нормально? Есть ли какой-то фундаментальный механизм в объединении пула, который я пропускаю? Мне сложно отлаживать это, поскольку я не знаю, как узнать, что происходит с открытыми соединениями. Я пробовал различные настройки log4j, но не получил удовлетворительного результата.

Редактировать, дополнительная информация: когда размер соединительной линии кажется слишком низким, партия, кажется, висит. Если я выполняю jstat в процессе, я вижу, что все потоки ждут нового соединения. Сначала я не указывал свойство maxWait в пуле соединений dbcp, что заставляет потоки ждать бесконечно на новом соединении, и я заметил, что пакет продолжал висит. Поэтому никаких связей не было. Однако это произошло только после обработки + -70 тыс. Строк, что каким-то образом уклонилось от моей первоначальной догадки утечки.

edit2: Я забыл упомянуть, что я уже переписал часть обновления в своих задачах. Я qeueu мои обновления в ConcurrentLinkedQueue, я пустым, что на 1000 элементов. Так что я на самом деле только около 100 обновлений.

edit3: Я использую Oracle, и я использую параллельные утилиты. Так что у меня есть исполнитель, настроенный с фиксированным пулом размером 16. Я отправляю свои задания этому исполнителю. Я не использую связи вручную в своих задачах, я использую jdbctemplate, который является потокобезопасным, и запрашивает его соединения из connectionpool. Я полагаю, что Spring/DBCP обрабатывает проблему соединения/потока.

ответ

0

Я переключился на c3p0 вместо DBCP. В c3p0 вы можете указать несколько вспомогательных потоков. Я замечаю, что если я ставлю это число выше числа потоков, которые я использую, количество соединений остается очень низким (с помощью удобного jmx-компонента c3p0 для проверки активных подключений). Кроме того, у меня есть несколько зависимостей с каждым его собственным менеджером сущностей. По-видимому, для каждого менеджера сущностей требуется новое соединение, поэтому у меня есть около 4 сущ./Thread/thread, что объясняет большое количество подключений. Я думаю, что мои задачи настолько недолговечны, что DBCP не мог следовать с закрытием/выпуском соединений, поскольку c3p0 работает более асинхронно, и вы можете указать количество хелпертовиков, он может своевременно выпустить мои подключения.

Редакция:

Редактирование: но пакет держится при развертывании в тестовой среде, все потоки блокируются при отпускании соединения, блокировка находится в пуле. Точно так же, как и с DBPC :(

редактирования:. Все мои проблемы исчезли, когда я перешел на BoneCP, и я получил огромный прирост производительности в качестве бонуса слишком

1

Если вы используете linux, вы можете попробовать администратора MySql, чтобы графически отслеживать состояние подключения при условии, что вы используете MySQL.

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

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

То есть, как вы распространяете элементы 100k на 16 потоков? Если вы пытаетесь приобрести соединение каждый раз, когда вы читаете строку из общего местоположения (или буфера), тогда ожидается, что потребуется время.

Посмотрите, поможет ли это.

  1. GetConnection
  2. для каждого элемента до тех пор, пока размер буфера становится равным нулю
  3. обработать его.
  4. , если вам нужно обновить,
  5. открыть сделку
  6. обновление
  7. коммит/откатить транзакцию
  8. перейти к шагу 2
  9. разъединить соединение

вы можете синхронизировать буфер с использованием java.util.concurrent collections

Не используйте один Runnable/Callable для каждого элемента. Это ухудшит производительность. Также как вы создаете темы? используйте Executors для запуска runnable/callable. Также помните, что соединения DB не должны использоваться совместно для потоков. Поэтому используйте 1 соединение в 1 потоке за раз.

Для примера. создать Исполнителя и представить 16 runnalbles, каждый из которых имеет свою собственную связь.

+0

Я отредактировал мой вопрос с дополнительной информацией производительность на самом деле очень хорошо даже если я создаю Runnable/row. –

+0

Попробуйте профилировщик Netbeans. Он дает вам живую статистику о таких потоках, как ожидание процессора, ожидание блокировки, ожидание ввода-вывода и т. д. Если результат показывает, что потоки ждут соединения с БД, то полезно увеличить размер пула, иначе оптимизировать шейку бутылки. http://profiler.netbeans.org/ –

+0

Для этого я использовал jvisualvm. К сожалению, я не могу подключить профилировщик к unix env, где возникает проблема , это закрытая среда. Но я не очень заинтересованный в настройке размера моего пула, теперь он работает нормально с 128, а размер исходных данных постоянный, поэтому это должно быть хорошо. Мой вопрос, однако, не должен быть достаточным? А если нет, то почему? –

Смежные вопросы