it-swarm.dev

Come posso trovare la dimensione di un RDD

Ho RDD[Row], che deve essere persistente in un repository di terze parti . Ma questo repository di terze parti accetta massimo 5 MB in una singola chiamata.

Quindi voglio creare partizioni in base alla dimensione dei dati presenti in RDD e non in base al numero di righe presenti in RDD.

Come posso trovare la dimensione di RDD e creare partizioni basate su di essa?

22
sag

Come ha detto Justin e Wang, non è semplice ottenere la dimensione di RDD. Possiamo solo fare una stima.

Possiamo campionare un RDD e quindi usare SizeEstimator per ottenere la dimensione del campione. Come Wang e Justin hanno menzionato, In base alla dimensione dei dati campionati offline, ad esempio, le righe X utilizzate Y GB non in linea, le righe Z in fase di esecuzione potrebbero richiedere Z * Y/X GB

Ecco il codice scala di esempio per ottenere la dimensione/stima di un RDD. 

Sono nuovo di scala e scintilla. Sotto il campione può essere scritto in un modo migliore

def getTotalSize(rdd: RDD[Row]): Long = {
  // This can be a parameter
  val NO_OF_SAMPLE_ROWS = 10l;
  val totalRows = rdd.count();
  var totalSize = 0l
  if (totalRows > NO_OF_SAMPLE_ROWS) {
    val sampleRDD = rdd.sample(true, NO_OF_SAMPLE_ROWS)
    val sampleRDDSize = getRDDSize(sampleRDD)
    totalSize = sampleRDDSize.*(totalRows)./(NO_OF_SAMPLE_ROWS)
  } else {
    // As the RDD is smaller than sample rows count, we can just calculate the total RDD size
    totalSize = getRDDSize(rdd)
  }

  totalSize
}

def getRDDSize(rdd: RDD[Row]) : Long = {
    var rddSize = 0l
    val rows = rdd.collect()
    for (i <- 0 until rows.length) {
       rddSize += SizeEstimator.estimate(rows.apply(i).toSeq.map { value => value.asInstanceOf[AnyRef] })
    }

    rddSize
}
10
sag

Un modo semplice è quello di chiamare seguendo, a seconda se si desidera memorizzare i dati in forma serializzata o meno, quindi andare a scintillare la pagina "Storage" dell'interfaccia utente, si dovrebbe essere in grado di capire la dimensione totale del RDD (memoria + disco):

rdd.persist(StorageLevel.MEMORY_AND_DISK)

or

rdd.persist(StorageLevel.MEMORY_AND_DISK_SER)

Non è facile calcolare la dimensione accurata della memoria in fase di esecuzione. Puoi provare a fare una stima in fase di esecuzione: basandoti sulla dimensione dei dati campionati offline, ad esempio, le righe X utilizzate da Y GB offline, le file Z in fase di esecuzione potrebbero richiedere Z * Y/X GB; questo è simile a Justin suggerito in precedenza.

Spero che questo possa aiutare.

6
Haiying Wang

Penso che RDD.count () ti darà il numero di elementi nel RDD

5
Yiying Wang

Questo dipenderà da fattori come la serializzazione, quindi non è tagliato e asciutto. Tuttavia, è possibile eseguire un campionamento ed eseguire alcuni esperimenti su tali dati di esempio, estrapolandoli da lì.

3
Justin Pihony

Questa è la versione da utilizzare se si sta effettivamente lavorando con i big data su un cluster, cioè elimina la raccolta.

def calcRDDSize(rdd: RDD[Row]): Long = {
  rdd.map(_.mkString(",").getBytes("UTF-8").length.toLong)
     .reduce(_+_) //add the sizes together
}

def estimateRDDSize( rdd: RDD[Row], fraction: Double ) : Long = {
  val sampleRDD = rdd.sample(true,fraction)
  val sampleRDDsize = calcRDDSize(sampleRDD)
  println(s"sampleRDDsize is ${sampleRDDsize/(1024*1024)} MB")

  val sampleAvgRowSize = sampleRDDsize / sampleRDD.count()
  println(s"sampleAvgRowSize is $sampleAvgRowSize")

  val totalRows = rdd.count()
  println(s"totalRows is $totalRows")

  val estimatedTotalSize = totalRows * sampleAvgRowSize
  val formatter = Java.text.NumberFormat.getIntegerInstance
  val estimateInMB = formatter.format(estimatedTotalSize/(1024*1024))
  println(s"estimatedTotalSize is ${estimateInMB} MB")

  return estimatedTotalSize
}

// estimate using 15% of data
val size = estimateRDDSize(df.rdd,0.15)
0
warrens