page rank 와 matrix product 와 같이 스테이지가 여러 개인 것은 맵리듀스로 작성하기 쉽지가 않음
쿼리들이 점점 복잡해지고 ad-hoc(그때그때 달라짐)해짐
근본적인 접근의 분산 framework -> spark
✅ Data Sharing 도구
맵리듀스는 매 단계마다 disk IO가 발생. 이런 disk IO가 많아지면 overhead가 생길 수 있음
스파크는 이 disk IO를 미니마이즈하는 것이 목표
iteration과 iteration 사이에 hdfs에 저장하는 것이 아니라 램에 저장하는 것
맵리듀스는 오퍼레이터가 맵과 리듀스만 있음.
스파크는 오퍼레이터의 종류가 굉장히 많음
join, sum, count
spark : 쿼리 할 때마다 처음부터 읽어오지 않음. 한 번 ram에 올려두고, 그 다음에 쿼리
✅ Challenge
1️⃣ fault-tolerant & efficient RAM storage
결함 내성
결함이 발생했을 때 어떻게 처리를 해야 될 것이냐.
램은 업데이트를 지원 -> fault-tolerant하기가 어려움.
checkpointing : 처음의 스냅샷
logging : 연산을 기록하는 것
매 연산마다 로깅하고 스냅샷을 기록하는 것은 오버헤드가 크게 보이게 됨
checkpointing -> disk IO -> 전체 시스템을 엄청 느리게 만듦
스파크는 위의 문제를 해결하기 위해 HDFS와 비슷한 컨셉을 도입함
hdfs는 file을 modify하려면 파일을 delete하고 다시 write해야 함. : write once, read many -> 빅데이터 처리를 하는 워크로드에서 보이는 전형적인 워크로드
🌟 스파크에서도 dram을 read-only로만 함 -> RDD(Resilient Distributed Datasets)
✅ RDD(Resilient Distributed Datasets)
1️⃣ 특성
Immutable : 변경 불가
partitioned collections of records : 레코드 조합을 분산해서 관리
storage -> RDD , RDD -> 연산 -> RDD : 이런 형식만 허용
2️⃣ 장점
한번 만들어진 이후로 고쳐진 적이 없음 : immutable = read-only
🌟 어떻게 만들어졌는 지만 기록해 두면 또 만들 수 있음. 오퍼레이션의 순서만 기억하면 이 RDD를 다시 복구할 수 있다는 의미
오퍼레이션의 형태를 리니지(lineage)라고 함
리니지만 기록하면 fault-tolerant함
✅ Implementation
transformation -> spark로 프로그래밍
disk에 쓰는 것이 액션임
lineage -> 그래프의 형태로 표현이 가능하다.
실제 계산은 액션이 일어날 때 가능
transformation은 RDD를 다른 RDD로 만드는 operator의 총합
✅ lazy-execution
성능을 위한 기법
save를 하게되면 그제서야 모든 transformation이 실행이 됨.
대충의 실행 플랜
자원이 배치된, 배치될 상황을 미리 고혀해서 최적의 코스로 돌 수 있음
✅ Narrow Dependencies & Wide Dependencies
한 자리에서 다 처리할 수 있는 일은 모아서 -> Narrow dependency ex)map
여기저기 다 훑어와야 하는 것은 느림 -> Wide dependency ex)reduce
1️⃣ Narrow
해당 작업이 한 노드에서 다 돌 수 있음
네트워크를 타지 않음
아주 빠르다
파티션이 고장 나도 해당 노드에서 다 복원 가능
2️⃣ Wide
shuffle이 일어나야 하는 일들
네트워크를 타야 함
상대적으로 느리다
부서지면 큰 overhead
추가적으로 checkpointing 해주는 게 좋을 수도 있음
✅ Job Scheduling
DAG에 따라 계산해 나감
이미 계산해 둔 파티션은 pass
필요하지만 없는 파티션을 lineage를 이용해 만들어가며 결과를 내놓음
파티션이 수행될 노드는 data-locality를 고려해 결정
✅ spark runtime
worker들은 기존과 비슷하게 돌아감
데이터 덩어리는 파티션으로 쪼개어져서 머신에 배분되어 있음 : ex)hdfs
드라이버에서 내려온 transform들이 각 파티션마다 수행
필요에 따라 (shuffle...) 파티션 내용이 다른 머신으로 전달됨
🌟 수행하다가 메모리가 부족하다면 ? LRU를 사용해서 가장 쓰지 않을 것 같은 파티션을 날림. 캐시와 비슷
🌟 수행 중 fault가 나면 recovery영향은 ? fail이 나는 경우와 나지 않는 경우의 수행시간이 크게 차이가 없음.
✅ checkpointing
fault가 나도 lineage로 복원 가능 -> wide dependency의 경우 느림 : 모든 파티션을 다 훑어야 하므로
재계산을 통한 구축 비용이 디스크에 checkpointing을 해놨다가 읽는 것보다 오래 걸릴 수 있음
병렬로 백그라운드에서 비동기로 돌리면 성능 패널티가 덜 하다.
여러 곳에서 받게 된 경우 체크포인트 해두는 것이 좋음.
✅ Evaluation
스파크의 성능이 압도적으로 빠르다
하둡의 첫 이터레이션과 마지막 이터레이션의 수행시간이 차이가 없는 이유 : 매번 disk IO가 발생하기 때문에
✅ spark vs in memory hadoop
hadoop의 코스트가 비쌈
✅ spark의 표현 영역
모든 요구 사항 거의 처리 가능
✅ conclusion
ram을 rom처럼 쓰는 것 -> RDD
lazy-execution
immutable
fault tolerant &b efficient 한 ram storage -> 계산에 활용