✅ RDD 재사용
스파크는 RDD 재사용을 위해 몇 가지 옵션을 제공한다.
→ persistence
, caching
, checkpointing
RDD 재사용을 통해 퍼포먼스를 향상시킬 수 있는 경우는 아래와 같다.
-
반복적인 연산
매번 연산할 때마다 데이터 세트가 메모리 내에 존재하고 있는 것이 보장되므로 성능 향상을 기대할 수 있다.
-
동일 RDD에 대해 여러 번의 액션 호출
-
각 파티션의 연산 비용이 너무 큰 경우
중간 결과를 저장하여 실패 시의 비용을 줄일 수 있다.
✅ 재연산 비용 효율성 판단
- 메모리 영속화(memory persist)는
- 메모리 공간과
- 직렬화와 역직렬화를 위한 시간이 필요하다.
- 메모리 영속화는 spark executor JVM 안에서 이루어진다. 따라서 메모리를 많이 차지하는 메모리 영속화는 메모리 오류의 위험도를 올릴 수 있다. 또는 가비지 컬렉션 비용이 더 높아질 수도 있다.
- 디스크 영속화나 checkpointing은 읽기와 쓰기 비용이 높아져 맵리듀스의 단점을 갖게 된다.
- 연산 규모가 클러스터나 작업 규모에 비해 클 때 재연산보다 RDD의 재사용이 더 효율적이다.
- 작업이 GC나 메모리 부족 오류로 실패하거나 클러스터에 다른 잡들도 많다면, checkpointing이나 off_heap 영속화가 도움이 될 수 있다.
✅ Persist and Cache
- persist와 cache는 RDD를 스파크 잡 동안 유지하여 재연산을 피하거나 긴 lineage를 가진 RDD를 끊을 수 있다.
- persist 함수는 RDD를 저장하는
StorageLevel
을 인자로 받는다.
- userDisk: 메모리에 들어가지 않는 파티션은 디스크에 기록된다. 디스크 IO 비용이 크기 때문에 재연산 비용이 큰 경우 사용된다.
- useMemory: 메모리에 저장되거나 직접 디스크에 기록된다.
- useOffHeap: executor 밖의 외부 시스템에 저장된다. 메모리 이슈가 심각하거나 클러스터가 혼잡할 때 사용된다.
- deserialized: 직렬화되지 않은 Java 객체로 저장된다.
- replication: 영속화 데이터의 복사본 개수를 정수로 지정한다.
✅ Checkpointing
- 잡의 중간 결과를 저장함으로써 실패에 따른 고비용 재연산을 막을 수 있다.
- RDD를 HDFS나 S3와 같은 외부 저장 시스템에 저장한다.
- 영속화와 달리 RDD의 lineage를 저장하지 않는다.
- RDD가 스파크 외부에 저장되므로 스파크 애플리케이션이 종료된 이후에도 데이터가 유효하다.
- 스파크의 메모리를 전혀 사용하지 않으며 스파크의 워커 노드에 문제가 생기더라도 재연산이 필요하지 않다는 장점이 있다.
- 실패나 재연산의 비용에 대한 우려가 클 때 사용한다.
중복 작업으로 느린 Job → persist
중간 실패가 우려되는 Job → checkpointing
✅ LRU Caching
- 익스큐터의 메모리가 부족할 때 제거할 파티션을 결정하기 위해 Least Recently Used caching 방식을 사용한다.
- 즉, 사용된지 가장 오래된 데이터를 제거한다.
✅ Shuffle files
- 셔플하는 동안 디스크에 데이터를 저장한다.
- 애플리케이션이 실행되는 동안 워커 노드의 디렉토리에 남아있으며, 드라이버 프로그램이 셔플된 RDD를 재사용한다면 해당 지점까지는 재연산을 피할 수 있다.
[출처]
https://jaemunbro.medium.com/apache-spark-rdd-재사용을-위한-영속화-persist-cache-checkpoint-12c121dac8b6