Carga de Archivos Grandes en MinIO con Fragmentación y Continuación de Puntos de Interrupción

Necesidad de Fragmentación y Continuación en Transferencias

La carga tradicional de archivos grandes presenta riesgos significativos: interrupciones de red o cierre del navegador pueden invalidar transferencias casi completas. La carga fragmentada resuelve esto dividiendo archivos en bloques pequeños (ej. 5MB), permitiendo transferencias paralelas independientes. La continuación de puntos de interrupción registra bloques transferidos exitosamente, evitando reprocesamiento tras fallos.

Arquitectura del Proceso: Componnetes y Flujo

El núcleo del sistema es el uploadId, identificador único generado por MinIO para cada operación. El flujo consta de cinco etapas:

  1. Inicialización: Cliente calcula fragmentos, servidor solicita uploadId a MinIO y registra metadatos en Redis
  2. Transferencia: Cliente obtiene URLs pre-firmadas para enviar fragmentos directamente a MinIO
  3. Seguimiento: Servdior consulta Redis para reportar progreso
  4. Consolidación: Validación de fragmentos antes de unificación en MinIO
  5. Cancelación: Limpieza de fragmentos temporales y registros

Implementación Backend: Inicialización y Transferencia

Inicialización de Operación

@PostMapping("/iniciarCargaFragmentada")
public Respuesta iniciarCargaFragmentada(@RequestParam String nombreArchivo,
                                        @RequestParam Long tamanoArchivo,
                                        @RequestParam String nombreCubo) {
    try {
        DTOInicioCarga dto = servicioMinio.prepararCargaFragmentada(nombreArchivo, 
                                                                   tamanoArchivo,
                                                                   nombreCubo);
        
        servicioProgreso.registrarProgreso(dto);
        List<Integer> fragmentosExistentes = servicioMinio.obtenerFragmentosRegistrados(dto.getIdCarga(), 
                                                                                      nombreCubo);
        dto.setFragmentosTransferidos(fragmentosExistentes);
        servicioProgreso.actualizarFragmentos(dto.getIdCarga(), fragmentosExistentes);
        
        return Respuesta.exito(dto);
    } catch (Exception ex) {
        return Respuesta.error("Error inicialización: " + ex.getMessage());
    }
}

Generación de Identificador

public DTOInicioCarga prepararCargaFragmentada(String nombreArchivo, 
                                             Long tamanoArchivo,
                                             String nombreCubo) throws Exception {
    verificarCubo(nombreCubo);
    String idCarga = clienteMinio.iniciarCargaMultiparte(nombreCubo, nombreArchivo).idCarga();
    
    int totalFragmentos = (int) Math.ceil((double) tamanoArchivo / TAMANO_FRAGMENTO);
    
    DTOInicioCarga dto = new DTOInicioCarga();
    dto.setIdCarga(idCarga);
    dto.setNombreArchivo(nombreArchivo);
    dto.setTotalFragmentos(totalFragmentos);
    dto.setEstado("INICIADA");
    
    return dto;
}

Transferencia Directa de Fragmentos

El cliente solicita URLs pre-firmadas para cada fragmento, enviándolos directamente a MinIO. Cada transferencia exitosa actualiza el estado en Redis mediante:

servicioProgreso.marcarFragmentoCompletado(idCarga, numeroFragmento);

Etiquetas: minio spring-boot java Multipart-Upload Resumable-Upload

Publicado el 6-23 19:39