2016-07-30 2 views
4

JSR 352 - Пакетные приложения для платформы Java обеспечивает функцию параллелизма с использованием разделов. Пакетное время выполнения может выполнять шаг в разных разделах, чтобы ускорить ход. JSR 352 также вводит threads определения: мы можем определить количество используемых потоков, такие какКак определить хороший план разделов для обеспечения баланса процессора в JSR 352?

<step id="Step1"> 
    <chunk .../> 
     <partition> 
      <plan partitions="3" threads="2"/> 
     </partition> 
    </chunk> 
</step> 

Тогда я чувствую замешательство: как дать оценил план раздела, так что каждый поток занят и обеспечить баланс центрального процессора ?

Например, есть таблица A, B, C, и их ряды составляют соответственно 1 миллиард, 1 миллион, 1 тысяча. Цель состоит в том, чтобы обрабатывать эти объекты в документах, одна организация переходила к одному документу. Порядок изготовления документов не важен. Время CPU для данных этих объектов составляет соответственно 1 с, 2 с, 5 с. Число нитей 4.

Если вы 3 разделов, один за тип таблицы, то шаг займет 1 * 10^9 секунд, чтобы закончить, потому что:

  • Partition будет принимать 1 * 10^9 * 1s = 1 * 10^9s, работать на нить 2
  • раздела Б будет принимать 1 * 10^6 * 2s = 2 * 10^6s, работать на нити 3
  • раздела C будет принимать 1 * 10^3 * 5s = 5 * 10^3s, работать на нить 4

Тем не менее, в то время как поток 2 занят, поток 3 свободна, так как 2 * 10^6s и нить 4 свободна, так как 5 * 10^3s. Очевидно, что это не хороший план разделов.

Мои вопросы:

  • Есть ли лучший план раздела завершить в приведенном выше примере?
  • Могу ли я считать: разделов является очередью потребления и нит. потребляют эту очередь?
  • В общем, сколько потоков я/должен использовать? Это то же самое количество ядер процессора?
  • В целом, как дать оцененный план разбивки так, чтобы каждый поток занят и обеспечивал баланс ЦП?
+0

Как правило, на многораздельном этапе вы используете одну и ту же точную логику для каждого раздела. Позвольте мне сначала спросить, для ваших «табличных типов» A, B и C вы предполагаете, что они настолько похожи, что они хорошо вписываются в один шаг, используя ту же логику для чтения/обработки/записи для всех трех? (Если это не так, то лучше будет разбить их на три последовательных этапа, некоторые из которых могут быть разделены и/или, возможно, разделены для одновременного запуска разных шагов). –

+0

Привет @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. –

ответ

2

Ответы ...

Есть ли лучший план раздела завершить в приведенном выше примере?

Да, есть. См. Ответ 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.

Надеюсь, что эта помощь ...

+0

В моих тестах используется JBeret как реализация, но сама фреймворк позволяет пользователю выбирать свою собственную реализацию (пакетное время выполнения, встроенное в целевой контейнер Java EE). Поэтому я рассмотрю настройку пула потоков для всех реализаций. Вы упоминали, что параллелизм нескольких заданий и производительность по разным точкам, это ценно. Решение, которое вы предложили в резюме, велико, я соглашусь с ним. Спасибо за этот очень подробный и полезный ответ @CarlitosWay. –

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