Ответы ...
Есть ли лучший план раздела завершить в приведенном выше примере?
Да, есть. См. Ответ 4 ...
Могу ли я рассмотреть: разделы - очередь для потребления, а потоки потребляют эту очередь?
То, что точно происходит!
В общем, сколько потоков я/должен использовать? Это то же самое количество ядер процессора?
Это зависит. Этот вопрос имеет много точек зрения ... Из JSR-352 Спецификации Вида «нитей»:
Задает максимальное количество потоков, на которых для выполнения Перегородки этого шага. Обратите внимание, что время выполнения пакета не может гарантировать требуемое количество потоков; он будет использовать столько, сколько может, до требуемого максимума. Это необязательный атрибут. По умолчанию используется количество разделов.
Таким образом, на основе только с этой точки зрения, вы должны установить это значение выше, чем вы хотите (партия во время выполнения будет установлен реальный предел, в соответствии с его ресурсами!).
С точки зрения исполнения Runtime (реализация JSR352): Любая достойная реализация будет использовать пул потоков для выполнения секционированных шагов. Таким образом, если у такого пула есть фиксированный размер N, независимо от того, насколько велика вы установили номер своего потока, вы никогда не будете выполнять больше N разделов одновременно.
JBeret - это реализация спецификации JSR352, используемая сервером wildfly (это реализация, которую я использовал). В Wildfly у него есть настройка потока потоков по умолчанию, равная 10 потокам. Этот пул не только разделяется между секционированными шагами, но и распределяется между пакетными заданиями. Таким образом, если вы одновременно выполняете 2 задания, у вас будет 2 потока меньше для использования. Кроме того, при разделении один поток выполняет роль координатора, назначая разделы другим потокам и ожидая результатов ... поэтому, если в вашем плане разделов указано, что он использует 2 потока, он фактически использует 3! (два в качестве рабочих, один в качестве координатора) ... и все эти ресурсы (потоки) берутся из одного пула !!
В любом случае, важная вещь: исследовать, какую реализацию JSR325 вы используете, и настроить ее соответственно.
Из аппаратного обеспечения ваш процессор имеет максимальный предел потока. В соответствии с этой перспективой (и в качестве эмпирического правила) установите значение «threads» равным такому значению.
Из обзора производительности проанализируйте работу, которую вы выполняете. Если вы обращаетесь к общему ресурсу (например, к БД) между многими потоками, вы можете создать узкое место, вызывающее блокирование потоков. Если вы сталкиваетесь с такой проблемой, вы должны думать о снижении значения «theads».
В сводке установите значение «threads» с максимальным пределом потока процессора. Затем проверьте, не вызывает ли это значение проблемы блокировки; если это так, уменьшите значение. Кроме того, убедитесь, что пакетное время выполнения настроено соответствующим образом, и оно позволяет вам выполнять столько потоков, сколько пожелаете.
В целом, как дать оцененный план разделения, чтобы каждый поток был занят и обеспечивал баланс ЦП?
Избегайте использования статических планов разделов (по крайней мере, для вас).Вместо этого используйте Partition Mapper. Partition Mapper - это класс, реализующий интерфейс javax.batch.api.partition.PartitionMapper
и позволяющий программно определить план раздела (сколько разделов, сколько потоков, свойства каждого раздела). Поэтому для вашего случая возьмите свои таблицы (A, B, C) и разделите их на блоки из N (где N = 1000) ... каждый блок будет разделом. Вы должны начать с раздела типа С и делать круговой между вашими разделами сущностей (таблиц): C0
, B0
, A0
, B1
, A1
, ..., B999
, A999
, A1000
, ..., A999999
... используя эта схема, объект C завершит сначала, оставив один поток открытым, чтобы разрешить больше разделов A и B. Позже B закончит, оставив больше ресурсов, чтобы атаковать оставшиеся разделы A.
Надеюсь, что эта помощь ...
Как правило, на многораздельном этапе вы используете одну и ту же точную логику для каждого раздела. Позвольте мне сначала спросить, для ваших «табличных типов» A, B и C вы предполагаете, что они настолько похожи, что они хорошо вписываются в один шаг, используя ту же логику для чтения/обработки/записи для всех трех? (Если это не так, то лучше будет разбить их на три последовательных этапа, некоторые из которых могут быть разделены и/или, возможно, разделены для одновременного запуска разных шагов). –
Привет @ScottKurz, да, они хорошо подходят для работы на одном шаге. На самом деле, [мой обработчик товаров] (https://github.com/mincong-h/gsoc-hsearch/blob/2b3831e0769dbc2c959d2d5a90d89d61699d4796/core/src/main/java/org/hibernate/search/jsr352/internal/steps/lucene/ ItemProcessor.java) преобразует JPA-модель в документ Lucene для полнотекстового поиска. Это та же самая точная логика для таблиц A, B и C. –