2016-07-15 134 views
5

Sto facendo funzionare questo codice su EMR 4.6.0 + Spark 1.6.1:Spark SQL fallisce perché "pool costante è cresciuto passato limite JVM di 0xFFFF"

val sqlContext = SQLContext.getOrCreate(sc) 
val inputRDD = sqlContext.read.json(input) 

try { 
    inputRDD.filter("`first_field` is not null OR `second_field` is not null").toJSON.coalesce(10).saveAsTextFile(output) 
    logger.info("DONE!") 
} catch { 
    case e : Throwable => logger.error("ERROR" + e.getMessage) 
} 

Nell'ultima fase della saveAsTextFile, fallisce con questo errore:

16/07/15 08:27:45 ERROR codegen.GenerateUnsafeProjection: failed to compile: org.codehaus.janino.JaninoRuntimeException: Constant pool has grown past JVM limit of 0xFFFF 
/* 001 */ 
/* 002 */ public java.lang.Object generate(org.apache.spark.sql.catalyst.expressions.Expression[] exprs) { 
/* 003 */ return new SpecificUnsafeProjection(exprs); 
/* 004 */ } 
(...) 

Quale potrebbe essere la causa? Grazie

+1

Interessante. Ogni classe java ha un pool costante per mantenere tutto costante, includendo anche i nomi dei metodi. 'u2 constant_pool_count', quindi il numero massimo di costanti è 0xFFFF. Io uso JSON semplice per testare che non genera un'eccezione. Perché questo codice genera così tanti costanti? Sarà possibile pubblicare parte dei dati JSON? –

+0

@RockieYang non è possibile caricare il mio json ma consiste di circa 90 campi stringa/numero. –

+0

Hai solo bisogno di aggiungere un json. E hai testato se è relativo numero di righe? –

risposta

3

Risolto questo problema facendo cadere tutte le colonne non utilizzate nel Dataframe o semplicemente filtrando le colonne effettivamente necessarie.

Spegni Dataframe non è in grado di gestire schemi super ampi. Non esiste un numero specifico di colonne in cui Spark potrebbe rompere con "Il pool costante è passato oltre il limite JVM di 0xFFFF" - dipende dal tipo di query, ma la riduzione del numero di colonne può aiutare a risolvere questo problema.

La causa principale sottostante è in 64kb di JVM per le classi Java generate - vedere anche la risposta di Andrew.

+1

Ho appena fatto un test, scintilla funziona su 100 colonne se è solo semplice colonna. Se è una colonna complessa con molte strutture incorporate, quando la quantità totale di campo supera un certo numero, alla fine fallirà. Quanti campi in totale nel tuo json? –

+0

Circa 90 in generale e alcuni dei campi sono nidificati, quindi nel complesso direi oltre 100. –

+0

Deve essere qualcosa di speciale nella tua struttura JSON. Ho provato con 4000 colonne semplici e funziona. Comunque è buono che tu lo risolvi. –

3

Ciò è dovuto alla limitazione nota di Java affinché le classi generate superino 64 KB.

Questa limitazione è stata risolta in SPARK-18016, che è stato risolto in Spark 2.3 - sarà rilasciato nel gennaio/2018.