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:
- Inicialización: Cliente calcula fragmentos, servidor solicita
uploadIda MinIO y registra metadatos en Redis - Transferencia: Cliente obtiene URLs pre-firmadas para enviar fragmentos directamente a MinIO
- Seguimiento: Servdior consulta Redis para reportar progreso
- Consolidación: Validación de fragmentos antes de unificación en MinIO
- 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);