2016-06-24 3 views
0

범위가 데이터 프레임 및 스파크와 함께 작동하는 방식에 대해 궁금합니다. 아래 예제에서 파일 목록을 가지고 있습니다. 각각 데이터 프레임에로드되고 일부 작업이 수행 된 다음 디스크에 dfOutput을 씁니다.스파크 - 범위, 데이터 프레임 및 메모리 관리

val files = getListOfFiles("outputs/emailsSplit") 

for (file <- files){ 

    val df = sqlContext.read 
     .format("com.databricks.spark.csv") 
     .option("delimiter","\t")   // Delimiter is tab 
     .option("parserLib", "UNIVOCITY") // Parser, which deals better with the email formatting 
     .schema(customSchema)    // Schema of the table 
     .load(file.toString)      // Input file 


    val dfOutput = df.[stuff happens] 

    dfOutput.write.format("com.databricks.spark.csv").mode("overwrite").option("header", "true").save("outputs/sentSplit/sentiment"+file.toString+".csv") 

} 
  1. 루프가 완료되면 폐기 for loop 내부의 각 데이터 프레임, 또는 메모리에 남아 있습니까?
  2. 폐기되지 않은 경우 현재 메모리 관리를 수행하는 더 좋은 방법은 무엇입니까?

답변

1

DataFrame 개체가 작습니다. 그러나 Spark 집행자의 캐시에서 데이터를 참조 할 수 있으며 Spark 집행자의 셔플 파일을 참조 할 수 있습니다. DataFrame가 가비지 수집되면 캐시 및 셔플 파일이 실행 프로그램에서 삭제됩니다.

코드에는 루프를 지나친 DataFrames에 대한 참조가 없습니다. 그래서 그들은 가비지 수집 자격이 있습니다. 가비지 수집은 일반적으로 메모리 부족에 대응하여 발생합니다. 디스크를 가득 채우는 파일을 뒤섞어 걱정할 필요가 없다면 명시 적 GC를 트리거하여 더 이상 참조되지 않는 DataFrames에 대한 파일이 삭제되도록하십시오.

DataFrame ([stuff happens])을 사용하여 수행 한 작업에 따라 메모리에 데이터가 저장되지 않을 수도 있습니다. 이것이 스파크의 기본 작동 모드입니다. 일부 데이터를 읽고 변환하고 다시 작성하려는 경우 모든 데이터가 한 줄씩 저장되며 메모리에 저장되지 않습니다. (캐싱은 명시 적으로 요청할 때만 발생합니다.)

이 모든 것을 고려해 볼 때 문제가 발생할 때까지 메모리 관리에 대해 걱정할 필요가 없습니다.

+0

감사합니다. 매우 유익한 답변입니다! –

+0

df에 대한 선형 변환 과정이 주어지면 df1 = df0.bla(); df2 = df1.blabla(); df3 = df2.blablabla(), 언제 df1가 garbaged? 스코프가 끝나거나 프로그램이 깨달을 때 더 이상 줄을 사용하지 않을 것입니다 (df1을 더 이상 호출 할 필요가 없기 때문에 df2가 기본적으로 만들어집니다). –

+1

하위의 RDD ('df2'의 경우와 유사)는 부모 ('df1'의 부모)를 참조합니다. 따라서 'df1'은 범위를 벗어난 경우에만 수집되며 모든 자손은 가비지 수집됩니다. 이는 RDD가 게으르기 때문입니다. 'df1'의 명령 (예 : "이 파일 읽기")은 작업 (예 : "행 계산")이 수행 될 때만 즉시 실행되지 않습니다. 따라서 참조는 조상 RDD에 보관되어야합니다. –