Estoy refactorizando un trabajo que carga ~1,2 millones de archivos pequeños en AWS; anteriormente esta subida se hacía archivo por archivo en una máquina de 64 CPUs con procesos. Cambié a un enfoque asíncrono + multiproceso siguiendo los límites de velocidad de S3 y las mejores prácticas y pautas de rendimiento para hacerlo más rápido. Con datos de muestra, puedo lograr tiempos de ejecución tan bajos como 1/10. Con cargas de producción, S3 devuelve errores "SlowDown".
En realidad, la lógica comercial hace que la estructura de carpetas sea así:
s3://bucket/this/will/not/change/<shard-key>/<items>Los objetos se dividirán por igual en ~30 claves fragmentadas, lo que hará que cada prefijo contenga ~40k elementos.
Tenemos cada proceso escribiendo en su propio prefijo y lanzando lotes de solicitudes PUT de 3k en asíncrono hasta su finalización. Hay una suspensión después de la operación de escritura por lotes para garantizar que no enviemos otro lote antes de que haya pasado 1,1 segundos, por lo que respetaremos las 3500 solicitudes PUT por segundo.
El problema es que recibimos errores de SlowDown durante ~1 hora y luego el trabajo escribe todos los archivos en ~15 minutos. Si bajamos el límite a 1k/seg esto empeora aún más, funcionando durante horas y sin terminar nunca.
Esta es la distribución de los errores en el tiempo para el límite de 3k/seg: 
Estamos usando Python 3.6 con aiobotocore para ejecutar async.
Hacer algún tipo de prueba y error para tratar de entender cómo mitigar esto lleva una eternidad en los datos de producción y las pruebas con una menor cantidad de datos nos dan resultados diferentes (funciona perfectamente).
¿Me perdí alguna documentación sobre cómo hacer que el sistema se amplíe correctamente?