es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Spring Batch mejora el rendimiento mediante la partición.

Necesito convertir el proyecto existente a un trabajo de Spring Batch para mejorar la velocidad del trabajo. Supongamos que tengo la primera tarea para recuperar una lista de datos de la base de datos y enviarla al listener. Por lo tanto, el siguiente paso puede recuperarla desde @BeforeStep y realizar algunas condiciones para obtener otra lista (10k-20k registros) y luego proceder a la lógica de negocios múltiple para cada registro.

Pero estoy atascado en cómo implementar este paso por partición en Spring Batch. Encontré todos los tutoriales que utilizan consultas directas en el lector e inyectadas por ExecutionContext en rangePartitioner. Pero no puedo seguir ese camino.

<job id="testJob" xmlns="http://www.springframework.org/schema/batch">
    <step id="step1"  next="step2">
        <tasklet ref="driver"/>
        <listeners>
            <listener ref="promotionListener">
            </listener>
        </listeners>
    </step>
    <step id="step2"> 
      <tasklet >
        <chunk reader="bmtbBillGenReqReader"
            processor="bmtbBillGenReqProcessor"
            writer="bmtbBillGenReqWriter"
            commit-interval="1">                      
        </chunk>
      </tasklet>
    </step>
</job>
<bean id="promotionListener"
    class="org.springframework.batch.core.listener.ExecutionContextPromotionListener">
    <property name="keys">
        <util:list>
            <value>billGenRequests</value>
        </util:list>
    </property>
</bean>

Por favor, aconseje cómo puedo implementar la partición desde el paso2. ¿Quizás almacenar la nueva lista del paso2 en un archivo CSV o algo similar primero?

Tags:  

Answer

  1. Avatar for davy.ai

    Para implementar la partición en Spring Batch, puedes utilizar la interfaz Partitioner para definir cómo se particiona los datos. Aquí te mostramos cómo puedes modificar tu configuración para implementar la partición:

    1. Crea un nuevo paso llamado “partitionStep” que contendrá la lógica de partición.
    <step id="partitionStep">
        <partition step="businessStep" partitioner="rangePartitioner">
            <handler grid-size="10"></handler>
        </partition>
    </step>
    
    1. Define tu particionador personalizado implementando la interfaz Partitioner.
    public class MyPartitioner implements Partitioner {
        @Override
        public Map<string, executioncontext=""> partition(int gridSize) {
            Map<string, executioncontext=""> partitions = new HashMap<>();
            // Obtén la lista de datos de la base de datos
            List<mydata> dataList = retrieveData();
            // Divide los datos en particiones de tamaño aproximadamente igual
            List<><mydata>> partitionList = ListUtils.partition(dataList, gridSize);
            // Crea un ExecutionContext para cada partición
            for (int i = 0; i < partitionList.size(); i++) {
                ExecutionContext context = new ExecutionContext();
                context.put("partitionData", partitionList.get(i));
                partitions.put("partition" + i, context);
            }
            return partitions;
        }
    }
    
    1. Modifica tu “businessStep” para utilizar los datos particionados.
    <step id="businessStep">
        <tasklet>
            <chunk reader="partitionReader" processor="businessProcessor" writer="businessWriter" commit-interval="1"></chunk>
        </tasklet>
    </step>
    
    1. Define un lector de elementos Personalizado que lea los datos de la partición.
    public class PartitionReader implements ItemReader<mydata> {
        private List<mydata> partitionData;
        private int index = 0;
    
        @BeforeStep
        public void beforeStep(StepExecution stepExecution) {
            ExecutionContext context = stepExecution.getExecutionContext();
            this.partitionData = (List<mydata>) context.get("partitionData");
        }
    
        @Override
        public MyData read() {
            MyData item = null;
            if (index < partitionData.size()) {
                item = partitionData.get(index);
                index++;
            }
            return item;
        }
    }
    
    1. Ejecuta el trabajo y observa cómo la partición acelera el procesamiento de los datos.

    Ten en cuenta que este es solo un ejemplo de cómo implementar la partición en Spring Batch. Hay otras estrategias de partición que puedes utilizar, como utilizar particiones remotas o lógica de particionamiento personalizada basada en los propios datos.</string,></string,>

Comments are closed.