최적화의 불꽃 포인트

배경은
왜 우리가 조정해야합니까? ?
프로그램의 작동 속도는 클러스터 또는 클러스터를 실행하지만, 또 다른 튜닝 사람들이있을 수 있습니다 당신은 몇 번이나 시간도 수십 될 수있는 코드를 작성

1. 개발 튜닝

1.1 원리 중 하나 : 피할 중복 RDD을 만드는
우리는 데이터, student.txt의 사본이
첫 번째 요구 사항 : 단어 수 발 stuRDD = sc.textFile ( " E : //sparkData//student.txt")
두 번째 수요 :이 계산 얼마나 많은 학생들이 발 stuRDD01 = sc.textFile ( "E : //sparkData//student.txt")를
사용하면 중복 성능을 낭비하고, 두 번로드됩니다 만드는 경우. 그러나 우리의 요구, 같은 연산자에 따라, 어떻게, 두 가지의 사용을 필요로? ?
지속성이 될 수 있습니다 :

sc.textFile("e://sparkData//student.txt").cache()

1.2 두 번째 원칙 : 가능한 한이 같은 RDD 사용으로
자주 읽고이 개발에 모두이다, 잊지 읽을
예 :
발 namesRDD = starsRDD.map (_._ 1)
발 name2LengthRDD = namesRDD.map (이름 = > (이름, name.length))

// 这两个map是可以合并的
val name2LengthRDD01 =  starsRDD.map(tuple => (tuple._1,tuple._1.length))
下面的这种方式写RDD性能更优,因为减少了一次RDD的计算

1.3 원리 III : 지속성에 대한 RDD 여러 사용

지속성 레벨을 선택하는 것이 주 :
1. 우선 순위 MEMORY_ONLY, D하지만 메모리가 충분히 큰 경우에만, 그것은 (메모리 이상에서) OOM이 발생할 수 있습니다
2. 메모리는 MEMORY_ONLY_SER 지속성 수준의 사용에 충분 MEMORY_ONLY, 순서 인 경우 기술 후, 데이터 메모리가 적은 의해 점령하지만, 직렬화 및 역 직렬화를 사용한 후 CPU에 의해 소비 된
3 위의 순수 메모리 지속성, 매우 빠르게,하지만 MEMORY_ONLY_SER 다음 MEMORY_AND_DISK_SER를 사용하여 충분한 메모리가없는 경우, 이 전략으로, 메모리에있는 데이터의 우선 순위, 디스크에 메모리가
4 사용으로보다 (스파크가 요구하는 내결함성을 스트리밍) 어떤 특별한 상황에서 _2,이 매우 느립니다 순수 디스크 프로그램을 사용하지 않는 것이 좋습니다, 그것은 일반적으로 권장되지 않습니다

1.4 원리 IV : 셔플 클래스 연산자를 사용하여 피하려고

감소 파티션
방송 +지도 + 필터에 가입 교체

조인 큰 테이블이 작은 테이블 조인 방송 데이터 맵 + 필터 연산에 의해 실행 프로그램에 작은 테이블로 간주 될 수있다 완료된 기능 합류

1.5 원리 V는 : 맵 측을 사용하여 셔플 동작 예비 중합
셔플 동작의 사용에 부여를 조작자가 클래스 맵을 대체 할 수없고, 그 예비 중합지도 측 연산자를 사용하는 것이 가능하다.
ReduceByKey 대신 GroupByKey에서의 사용하는 것입니다
더 나은 GroupByKey에서 많이보다 유사한 요구 성능 reduceByKey, 당신은 크게 네트워크 트래픽 데이터를 줄일 수있는 경우

1.6 원리 VI : 고성능 연산자를 사용하는
일부 수요가 많은 사업자는 사용할 수 있지만, 높은 성능 사업자와 동일하지 성능을 해결하는
등 :
reduceByKey / aggregateByKey 대안 GroupByKey에서 사용
사용 mapPartitions 보통지도가 대체, 사용 mapPartitions이 나타납니다 문제 (메모리의 출력) OOM
통상 유사한 mapPartitions가 상기 비교에 매핑하는 대신에, 대안의 foreach foreachPartitions를 이용하여, 그것은 운영자의 동작이며, 예 데이터베이스 쓰기
필터 병합하여 동작 후에 수행
재분할 및 병합 사용 비고 : 장면
셔플, 파티션 증가 일반적으로 수, 병렬 처리 수준 향상을 목적으로 송환
발 rdd02 = rdd01.filter (XXX)를 - > 일부는 많은 파티션 필터링, 일부 필터링은 거의 할 수
파티션은 일반적으로 유착 없다 숫자는 파티션의 수를 병합하는, 감소
병렬도가 감소되지만, rdd02.coalesce ()를, 그러나 더 높은 자원 활용하지만, 성능을 향상시킬 수있다

당신이 지방을 감소해야하는 경우 매우 드물게,
rdd01 20 개 파티션입니다 - "rdd02 : 5 창 발 rdd02 = rdd01.coalesce (5 사실 ) /rdd01.repartition (5) 파티션, 더 나은

1.7 세븐 원칙 : 큰 변수 방송
보너스 :
외부 변수가 비교적 큰 사용하는 경우는 사용 스파크 방송 기능, 변수 방송을 권장합니다. 방송 후 변수, 우리는 메모리의 각 집행자가되도록 할 것이다
변수의 비중이 집행자 집행자 작업 실행의 사본을 공유하면서, 변수 상주의 사본, 더 집행자보다가 있습니다. 이 경우
에는 크게, 따라서 네트워크 전송의 성능 오버 헤드를 줄이고, 변수의 매수를 줄일 수 있으며, GC의 빈도를 감소시키는 오버 헤드 메모리 점유 실행자를 감소시킨다.

1.8 원칙 8 : 사용 Kryo을 최적화 직렬화 성능

스파크의 직렬화? 자바 Kryo는
다음과 같은 구성을 수행합니다

//创建SparkConf对象。
val conf =new SparkConf().setMaster(...).setAppName(...)
//设置序列化器为KryoSerializer。
conf.set("spark.serializer","org.apache.spark.serializer.KryoSerializer")
//注册要序列化的自定义类型。
conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]))

1.9 원리 9 : 최적화 데이터 구조

개체 문자열은 메모리 세트이다
대신 대상 문자열
대신 집합의 배열
(예 INT, 장기 등) 기본 형태를 다르게 문자열

너무 사용하기 어려운, 아니 실제

2.0 자원 조정

실행 프로그램 내부에서, 메모리는 여러 부분으로 분할한다 :
첫 번째는 디폴트로 작성된 코드를 실행할 수있는 우리의 작업을 확인하는 데 사용되는 20 % 실행자 총 메모리를 차지하고,
제 태스크 셔플 당기는 과정을 차단하는 것이다 20 % 실행기 기본 차지 단계, 중합 등의 운용상의 태스크의 출력을 사용한 후 총 메모리이다 spark.shuffle.memoryFraction
spark.shuffle.memoryFraction
실행 프로그램을 조정하기위한, 상기 데이터 메모리 크기 셔플 점유 기본값은 0.2입니다

세 번째 블록은 60 % 실행자 기본 총 메모리를 차지 RDD 지속성을 확인하는 데 사용된다. spark.storage.memoryFraction
spark.storage.memoryFraction
실행기를 조정은, 데이터 메모리 크기의 지속성, 기본 0.6

2.1 이해

참고 : 어떻게 스파크 구성 매개 변수
코드에서 구성 매개 변수 1. 방법 :

conf.set(key,value)
conf.set("spark.serializer","org.apache.spark.serializer.KryoSerializer")

자원에 대해 조정 매개 변수는 다음과 같다 :
NUM-집행
조작에 집행의 총 수
매개 변수 튜닝 권장 사항 : 불꽃 작업이 일반적으로 약 50-100 집행자 프로세스의 각 세트를 실행하는 데 너무 적거나 너무 많은 집행자 설정 프로세스가 좋지 않다, 적합합니다.
다음 너무 많은 설정, 대부분의 큐의 제공되지 않을 수 있습니다 충분한 자원, 너무 몇 가지 설정은 클러스터 리소스의 전체를 사용 할 수 없습니다.

== == 실행 프로그램 메모리
파라미터 설명 :이 파라미터는 각각의 프로세스의 실행 프로그램 메모리를 설정하기 위해 사용된다. 집행자의 메모리 크기는 종종 직접 성능 스파크 작업을 결정
하지만, 일반적인 JVM OOM의 예외를 제외하고는 직접적인 상관 관계가있다.
640G 메모리 32g * 20 = 640G

20 집행자
최대 메모리 제한 자원 큐 자신의 팀을 볼 수는 집행 메모리를 곱한 많이 내림 집행, 그것은 메모리의 전체 양을 나타내는 방법 인 스파크 작업에 응용 프로그램 (즉, 모든 집행자 메모리 프로세스의 합) ,
이 금액은 큐 메모리의 최대 양을 초과 할 수 없다. 당신이 팀에서 다른 사람들과이 자원 큐를 공유하는 경우 또한, 다음 메모리의 총량은 응용 프로그램이 자신의 스파크 작업을 피하기 위해 최대 총 메모리 자원 큐 1/3 ~ 1/2을 초과하지 않아야한다
대기열을 모두 차지 다른 학생들의 작업에 주요 자원은 실행할 수 없습니다.

== 집행 코어 ==
각 집행 얼마나 많은 CPU 코어
의 핵심은 물리적 코어를 참조하지 않고, 논리적 핵심을 말한다
4 코어 8 스레드 I7

파라미터 튜닝 권장 사항 : 핵심 집행자가 4 2로 설정 번호 CPU의 더 적합합니다. 세트에 서로 다른 부서가 동일한 자원 큐에 한에 따르면, 당신은 최대 CPU 코어 제한 자신의 자원을 대기열의 수입니다 확인한 다음 집행자의 수에 따라 설정할 수 있습니다
각각의 집행자 프로세스가 여러 CPU 코어에 할당 할 수 있습니다 결정. 또한 큐가 다른 사람들과 공유하는 경우, 다음의 num-집행이 * 집행자 코어는 전체 코호트 CPU 코어가 적절 1/2 ~ 1/3에 관한 것입니다 초과하지 않는 것을 제안
뿐만 아니라 다른 학생들을 실행하는 작업에 영향을주지 않도록 할 수 있습니다.

드라이버 메모리
작업이 수집 할 때 프로그램에 할당 Dirver 메모리, 우리는 더 큰 dirver 메모리를 제공해야

spark.default.parallelism
매개 변수 설명 :이 매개 변수는 작업의 각 단계에 대한 기본 번호를 설정하는 데 사용됩니다. 이 매개 변수는 직접 작업 성능 스파크에 영향을 미칠 수 있습니다 설정되어 있지 않은 경우, 매우 중요합니다.

spark.default.parallelism = 납입 실행기는 executor- * 코어 (2-3 시간)
이 설정 한 후이 각 작업 2-3은 모두 CPU있다

네 개의 코어를 가지고 각각의 실행 프로그램 실행기 (10), 제공 spark.default.parallelism = 120
각 작업의 얼마나 많은 코어 (40), 40분의 120는 = 코어의 실행 집행자

CPU 코어에 할당 된 수보다 확실히 큰 총 작업 수,은, 자원의 낭비 반면, 그것의 일반적인 2 ~ 3 배 더 적합
: 병렬 처리 수준 설정하는 방법
어떻게 스파크 응용 프로그램의 병렬 처리 수준을 설정하는 방법을?

 1.spark.defalut.parallelism   
   默认是没有值的,如果设置了值比如说10,是在shuffle的过程才会起作用(val rdd2 = rdd1.reduceByKey(_+_) 
 	//rdd2的分区数就是10,rdd1的分区数不受这个参数的影响)

      new SparkConf().set(“spark.defalut.parallelism”,”500“)
	  
 2、如果读取的数据在HDFS上,增加block数,默认情况下split与block是一对一的,而split又与RDD中的partition对应,所以增加了block数,也就提高了并行度。
 3、RDD.repartition,给RDD重新设置partition的数量
 4、reduceByKey的算子指定partition的数量
      val rdd2 = rdd1.reduceByKey(_+_,10)  val rdd3 = rdd2.map.filter.reduceByKey(_+_)
 5、val rdd3 = rdd1.join(rdd2)  
 	rdd3里面partiiton的数量是由父RDD中最多的partition数量来决定,因此使用join算子的时候,增加父RDD中partition的数量。
 6、spark.sql.shuffle.partitions 
 	//spark sql中shuffle过程中partitions的数量

경사 튜닝 튜닝 데이터를 3.spark

이 데이터가 일어날 기울일 필터를이란? ?

질문 : 데이터 스큐 확실히 스큐, 그럼 어떻게 당신이 기울어 진 키 알 수 있습니까 발생하는 몇 가지 주요 데이터입니까? ?
10,000,000 20,000 밖을 촬영합니다

val sampledPairs = pairs.sample(false, 0.1)
val sampledWordCounts = sampledPairs.countByKey()
sampledWordCounts.foreach(println(_))

해결 방법 :
1. 깨진
2. 필터

2. 구성 할 수있는 스크립트 매개 변수
형식을 사용하여이 :

./bin/spark-submit \
  --class <main-class> \
  --master <master-url> \
  --deploy-mode <deploy-mode> \
  --conf <key>=<value> \
  ... # other options
  <application-jar> \
  

예를 들면 :

./bin/spark-submit \
  --master yarn-cluster \
  --num-executors 100 \
  --executor-memory 6G \
  --executor-cores 4 \
  --driver-memory 1G \
  --conf spark.default.parallelism=1000 \
  --conf spark.storage.memoryFraction=0.5 \
  --conf spark.shuffle.memoryFraction=0.3 \

구성 파일 3. 조정 가능한 매개 변수
의 conf / 불꽃은 defaults.conf 구성 파일은 구성 옵션을 참조하십시오. CONT / 불꽃은 defaults.conf 구성 파일에서,
각각의 행은 동일한 기호로 분할 될 수 중간 공간으로 분할 될 수있는 키 - 값 쌍이다 직접적

질문 :이 세 곳의 매개 변수가 세 곳에서 같은 매개 변수 구성을 구성 할 수 있으며, 그 다음, 값 매개 변수와 같은 아니에요
결국이 적용이다? ?

우선 순위 :
가장 높은 우선 순위의 코드에서 - "수단 작성하면 작업을 포장, 코드가 나타납니다을 수정하지 않는 한, 다른 장소에서 일부 매개 변수가 변경되지 작성하지 않는 때문에이에, 바람직하지 않다, 변경할 수 없습니다 어떤 구성이 적절한
스크립트에서 두 번째로 높은 우선 순위 - "그것에 파라미터 기록에 더 적합한, 매우 유연한 일반적인
구성 파일에서 최저 -"둘 이상의 구성 파라미터는 파라미터는 애플리케이션에 특정한 구성 파일은 몇 가지 매개 변수를 작성하는 더 적절한 전역 매개 변수, 가장 낮은 우선 순위는 모두 사용할 필요가 있습니다

2. 자원 조정
3. 데이터 경사 조정
4.shuffle 튜닝 섹션

//////////////////////////////////
스파크 최적화 원리

RDD의 내부에 컴퓨팅 작업을 시도 1.
// 잘못된 접근.
//은 <롱, 문자열> 형식 RDD, 즉 rdd1있다.
비즈니스 요구 //이 다음 rdd2을 만든 맵 rdd1에 작업을 수행하고, 데이터가 만 rdd1 rdd2이기 때문에
말을하는 것입니다 그것의 가치, 가치, rdd2은 rdd1의 부분 집합이다.
JavaPairRDD <긴 문자열> = ... rdd1
JavaRDD RDD2 rdd1.map = (...)
// 다른 알고리즘 rdd1의 rdd2의 실행 서브 작업이다.
rdd1.reduceByKey (...)
rdd2.map (...)

설명 : rdd2은 이상 변경 후 동작 V의 KV 타입의 rdd1입니다

오른쪽 접근 방식 :

JavaPairRDD<Long, String> rdd1 = ...  .Cache()
rdd1.reduceByKey(...)
rdd1.map(tuple._2...)

RDD의 형성을 감소

셔플을 최소화합니다

// 전통적인 작업이 셔플 동작됩니다 가입 할 수 있습니다.
// 두 RDD 때문에 동일한 키는 네트워크상의 노드를 끌어 필요한 태스크가 조인 연산 수행.
rdd1.join의 rdd3 = 발 (RDD2)
(가) 조인 작업의 // 방송 +지도 작업을 셔플으로 이어질하지 않습니다.
// 방송은 RDD 변수로 방송 적은 양의 데이터를 사용합니다.
rdd2.collect rdd2Data 브로 = ()
브로 = rdd2DataBroadcast sc.broadcast (rdd2Data)
// rdd1.map rdd2DataBroadcast rdd2에서 모든 데이터를 얻을 수있는 연산자.
// 반복 처리는,이 데이터 부분의 rdd2의 rdd1의 키 데이터와 현재 키에 있으면 동일하고 판정 할 수
가입 할.
//이 때, 데이터의 요구에 따라 실시 할 수있다, 현재의 데이터와 rdd2 rdd1은 (문자열 함께 접합, 접속 될 수도
또는 튜플).
rdd1.map rdd3 = 발 (rdd2DataBroadcast ...)
// 상기 동작은, 데이터 만 사용하는 경우 (예로서 수백 M, 열두 G) 이하 rdd2 추천합니다.
// 각 실행자 메모리이므로, 데이터는 rdd2 전액 상주한다.

게시 18 개 원래 기사 · 원 찬양 2 · 조회수 374

추천

출처blog.csdn.net/CH_Axiaobai/article/details/104161795