2015년 4월 27일 월요일

SparkSQL cacheTable 메소드 사용 성능 비교 - default vs cacheTable vs cacheTable (with columnar Compression)


SparkSQL 을 사용하다 보면, 복잡한 Nested Query 를 사용하는 것보다, 최대한 쿼리들을 단순하게 쪼개고, 중간 결과물을 registerAsTable 로 Table 화 하여, 여러 Step 으로 나누어 하는 경우 훨씬 빠른 결과물을 얻을 수 있는 경우를 종종 접한다. 메모리 부족 에러 등도 이런경우 훨씬 덜하다.

그런데, 가끔 로그를 보다 보면, 앞부분에서 이미 수행했던 쿼리가 뒷부분에서 결과를 가지고 재 쿼리를 할때 앞에서 수행했던 쿼리를 다시 또 수행하는 현상을 목격한게 된다.

이런 경우를 막는 것이 cacheTable 메소드 인데... (sqlContext 안에 정의 되어 있음.) 메뉴얼에는 schemaRDD 의 경우 cache 메소드 보다 cacheTable 메소드를 강력히 추천한다고 되어 있다. (이유는 Columnar 압축 저장 방식 때문...)

RDD.cache() 처럼 이것도, 뒷부분에서 재사용이 많지 않을때는 약간의 overhead 만 더 주어 좀더 느려진다. 아래 실험 또한 재사용이 거의 없는 셈플을 가지고 수행했더니, 오히려 살짝 느려 졌다. 

특이한 점은 아래처럼 inMemoryColumnarStorage.compressed 옵션을 켰더니 또 더 빨라 졌다는 점..... 
물론 compressing 은 case 별로 빨라질때도, 느려질때도 있음을 잘 알고 있다. 아마도 아래 Job 에서는 Columnar compressing 으로 인하여, shuffle 되는 양이 줄었기 때문인 듯...

아래 실험에서는 2번과 3번이 큰 효율을 보이고 있지는 않지만, 재사용이 많은, 그리고 재사용하는 테이블이 복잡한 헤비 쿼리(혹은 헤비 데이타)인 경우, 이론적으로는 훨씬 급격한 성능 향상을 꽤 할 수 있으리라 기대해본다.

관련 메뉴얼 : https://spark.apache.org/docs/1.1.0/sql-programming-guide.html#caching-data-in-memory


1. Default 수행
-> 647초 소요.


2. cacheTable 메소드 사용.
-> 679초 소요.


3. cacheTable 및 Colmanar Compress 옵션 사용
-> .set("spark.sql.inMemoryColumnarStorage.compressed", "true")
-> 557초 소요


댓글 2개:

  1. 질문이 있는데요 .set("spark.sql.inMemoryColumnarStorage.compressed", "true") 이것을 어디에다가 적용해야 되나요? 자바를 통해서 프로그래밍 하고 있습니다

    답글삭제
  2. 저희는 Scala 에서 소스 코드 내에서 set 하고 있고, 물론 Java에서도 할 수 있습니다. 그러나, 실행스크립트에서 spark-submit 할때 옵션으로 저 값을 넣어 줄수도 있고, spark conf 에서 글로벌하게 옵션을 넣을 수도 있습니다. 총 3가지 방법이 있다 하겠네요.

    답글삭제