Ich muss viele Dateien auf S3 hochladen, es würde Stunden dauern, diesen Job sequenziell abzuschließen. Das ist genau das, was Kotlins neue Coroutines auszeichnen, also wollte ich ihnen einen ersten Versuch geben, anstatt wieder mit einem Thread-basierten Ausführungsdienst herumzuspielen.Gleichzeitiger S3-Datei-Upload über Kotlin Coroutinen
Hier ist meine (vereinfacht) Code:
fun upload(superTiles: Map<Int, Map<Int, SuperTile>>) = runBlocking {
val s3 = AmazonS3ClientBuilder.standard().withRegion("eu-west-1").build()
for ((x, ys) in superTiles) {
val jobs = mutableListOf<Deferred<Any>>()
for ((y, superTile) in ys) {
val job = async(CommonPool) {
uploadTile(s3, x, y, superTile)
}
jobs.add(job)
}
jobs.map { it.await() }
}
}
suspend fun uploadTile(s3: AmazonS3, x: Int, y: Int, superTile: SuperTile) {
val json: String = "{}"
val key = "$s3Prefix/x4/$z/$x/$y.json"
s3.putObject(PutObjectRequest("my_bucket", ByteArrayInputStream(json.toByteArray()), metadata))
}
Das Problem: Der Code ist immer noch sehr langsam ist und die Protokollierung zeigt, dass Anfragen noch sequentiell ausgeführt werden: ein Auftrag abgeschlossen ist, bevor die nächste erstellt wird. Nur in sehr wenigen Fällen (1 von 10) werden Jobs gleichzeitig ausgeführt.
Warum läuft der Code nicht viel schneller/gleichzeitig? Was kann ich tun?
Ungereimt raten: move 'val s3 = AmazonS3ClientBuilder ...' innerhalb der asynchronen Abschnitt, so dass Sie mehrere Clients haben? –
das hat auch nicht funktioniert. Meine ungebildete Vermutung ist nun, dass 'putObject' die Anfrage blockiert, etwas, was sich nicht ändern kann. – linqu
Genau. Es sieht so aus, als ob das S3 SDK nicht-blockierende IO (über NIO) nicht unterstützt, so dass Sie pro Upload einen Thread benötigen. Sie können immer noch mehrere parallel laufen lassen, aber es ist wahrscheinlich nicht ratsam, _all_ parallel zu machen. Irgendwann werden Sie auch nur durch Ihre Netzwerkbandbreite begrenzt sein. – diesieben07