**
1、はじめにスパーク
**
1)、スパークの歴史:2012初期リリースバージョン0.6リリースでは、6歳がありました。
2)、スパークの創設者:カリフォルニア大学バークレー校、米国の大学のAMPの研究室。
3)、高速MRスパーク理由より:
①Sparkは、使用されるリソースを多重化し、粗粒状リソーススケジューリングあります。
②Sparkサポートメモリベースの反復は、MRがサポートされていません。
③SparkサポートDAGは非循環グラフタスクpiplelineを指示しました。
④Spark異なるシナリオは、異なるシャッフルに応じて適宜選択することができ、スパークMRよりも高性能(sortShuffle)をシャッフル
5)、スパーク動作モード:ローカル、スタンドアロン、糸、mesos 。
6)言語スパークの開発:スカラ座、ジャワ、パイソン、R 。(スカラおよびJava互換性と効率が同じです)
2、RDD(弾性分散データセット)(強調)
1)、RDD五大特性:(重点)
1. RDD是由一系列的Paratition组成的。(partition个数=split切片数 约等于 block数;Spark没有读文件的方法,依赖MR读文件的方法)
2. RDD提供的每一个算子实际上是作用在每一个Paratition上的。
3. RDD实际上是有一系列的依赖关系的,依赖于其他的RDD。(计算的容错性;体现了RDD的弹性;父RDD不一定知道子RDD是谁,子RDD一定知道父RDD是谁)
4. 可选:分区器作用在内部计算逻辑的返回值是kv格式的RDD上。
5. 可选:RDD会提供一系列的最佳计算位置。(计算找数据)
2)、算子
1. taransformation类算子
map(一对一)、flatMap(一对多)、filter(一对N(0、1))、join、leftouterJoin、rightouterJoin、fullouterJoin、sortBy、sortByKey、gorupBy、groupByKey、reduceBy、reduceByKey、sample、union、mappatition、mappatitionwithindex、zip、zipWithIndex。
2. action类算子
count、collect(将task的计算结果拉回到Driver端)、foreach(不会回收所有task计算结果,原理:将用户传入的参数推送到各个节点上去执行,只能去计算节点找结果)、saveAsTextFile(path)、reduce、foreachPatition、take、first。
(関連項目方法の結果:各ノードを表示するためのWebUI、ワーカーの作業ディレクトリ)
3.コントロールオペレータクラス
キャッシュ(相当MEMOORY_ONLY)、
持続(MEMORY_ONLY、DISK_ONLY、MEMORY_AND_DISK)
コントロールクラスオペレーターの注意事項:
1)、コントロールオペレータは、クラスオペレータアクションの後者のサブクラス保つことができない
、バッファユニットパーティション2)
3)、トリガーの実行に必要なオペレータのアクションの遅延、一種を行います。(アプリケーションはコントロールクラスの演算子を使用する必要、1つのジョブのみされていない場合)
3、スパークは、おそらくクラスタ内でプロセスを実行します
1. Driver分发task到节点运行(计算找数据)。
2. task执行结果拉回到Driver(有可能发生OOM)。
Driver的作用:
1)、分发任务到计算节点运行。
2)、监控task(thread)的运行情况。
3)、如果task失败,会重新发送(有限制)。
4)、可以拉回结果到Driver进程。
结论:Driver进程会和集群频繁通信。
4、アプリケーションの提出
1、Client
提交方式:spark-submit --deploy-mode client --class jarPath args
特点:Driver进程在客户端节点启动
适用场景:测试环境
大概运行流程:
1)、在Client本地启动Driver进程。
2)、Driver会向Master为当前Application申请资源。
3)、Master接收到请求后,会在资源充足的节点上启动Executor进程。
4)、Driver分发task到Executor执行。
2、Cluster
提交方式:spark-submit --deploy-mode cluster --class jarPath args
特点:每次启动application,Driver进程在随机一台节点启动
适用场景:生产环境
大概运行流程:
1)、客户端执行spark-submit --deploy-mode cluster --class jarPath args命令,启动一个sparksubmit进程。
2)、为Driver向Master申请资源。Driver进程默认需要1G内存,1core。
3)、master会随机找一台Worker节点启动Driver进程。
4)、Driver进程启动成功后,spark-submit进程关闭,然后Driver会向Master为当前Application申请资源。
5)、Master接收到请求后,会在资源充足的节点上启动Executor进程。
6)、Driver分发task到Executor执行。
1、タスクスケジューリングポイントを学習する前に知っておく必要があります
1.1は、専門用語のいくつかのスパーク
関連1.1.1、タスク
(DriverProgram + ExecutorProgram)ユーザーが記述したアプリケーション:アプリケーション。
求人:クラスアクションを操作するオペレータがトリガされます。
舞台:地図タスク次のようなタスクのセット。
タスク:クラスタ内の(スレッド)を実行し、実行の最小単位。
1.1.2、資源関連
Mstaer資源管理のマスターノード。
ワーカー資源管理ノードから。
エグゼキュータ:タスクを実行するプロセス。
ThreadPoolの:スレッドプール(プロセスでエグゼキュータ存在)
1.2、RDD中的依赖关系
1.2.1、宽依赖
父RDD与子RDD,partition之间的关系是一对多,一般来说,宽依赖都会导致shuffle。(默认情况下,groupByKey返回的RDD的分区数与父RDD是一致的。如果你在使用groupByKey的时候,传入一个Int类型的值,那么分区数就是这个值。)
1.2.2、窄依赖
父RDD与子RDD,partition之间的依赖关系是一对一,这种依赖关系不会有shuffle。
1.2.3、宽窄依赖的作用
宽窄依赖的作用就是:把job切割成一个个的stage。
切割stage的过程:(stage与 stage之间是宽依赖,stage内部是窄依赖)
那么接下来问题来了,为什么我们需要把job切割成stage呢?
答:把job切割成stage之后,stage内部就可以很容易的划分出一个个的task任务(用一条线把task内部有关联的子RDD与父RDD串联起来),然后就可把task放到管道中运行了。
下一个问题:RDD存储的到底是什么样的计算逻辑呢?下面用一个例子来解释:
在这个Application中有一个job,一个stage,2个task。
task0:这条线贯穿所有的partition中的计算逻辑,并且以递归函数展开式的形式整合到一起,fun2(fun1(textFile(b1))),最好将这个计算逻辑发送到b1或者其副本所在节点。task1也是相同的逻辑。同时注意:task的计算模式是pipeline的计算模式。
1.3、学习任务调度前需要了解的问题
1.3.1、stage中的每一个task(管道计算模式)会在什么时候落地磁盘?
1)、如果stage后面是跟的是action类算子
saveAsText:将每一个管道计算结果写入到指定目录。
collect:将每一个管道计算结果拉回到Driver端内存中。
count:将每一个管道计算结果,统计记录数,返回给Driver。
2)、如果stage后面是跟的是stage
在shuffle write阶段会写磁盘。(为什么在shuffle write阶段写入磁盘?防止reduce task拉取文件失败,拉取失败后可以直接在磁盘再次拉取shuffle后的数据)
1.3.2、Spark在计算的过程中,是不是特别消耗内存?
不是。Spark是在管道中计算的,而管道中不是特别耗内存。即使有很多管道同时进行,也不是特别耗内存。
1.3.3、什么样的场景最耗内存?
使用控制类算子的时候耗内存,特别是使用cache时最耗内存。
1.3.4、如果管道中有cache逻辑,他是如何缓存数据的?
有cache时,会在一个task运行成功时(遇到action类算子时),将这个task的运行结果缓存到内存中。
1.3.5、RDD(弹性分布式数据集),为什么他不存储数据还叫数据集?
虽然RDD不具备存储数据的能力,但是他具备操作数据的能力。
2、タスクスケジューリング
2.1、タスクスケジューリングプロセス
1)、DAGScheduler:根据RDD的宽窄依赖关系将DAG有向无环图切割成一个个的stage,将stage封装给另一个对象taskSet,taskSet=stage,然后将一个个的taskSet给taskScheduler。
2)、taskScheduler:taskSeheduler拿倒taskSet之后,会遍历这个taskSet,拿到每一个task,然后去调用HDFS上的方法,获取数据的位置,根据获得的数据位置分发task到响应的Worker节点的Executor进程中的线程池中执行。
3)、taskSchedule:taskSchedule节点会跟踪每一个task的执行情况,若执行失败,TaskSche会尝试重新提交,默认会重试提交三次,如果重试三次依然失败,那么这个task所在的stage失败,此时TaskSchedule向DAGSchedule做汇报。
4)、DAGScheduler:接收到stage失败的请求后,,此时DAGSheduler会重新提交这个失败的stage,已经成功的stage不会重复提交,只会重试这个失败的stage。
(注:如果DAGScheduler重试了四次依然失败,那么这个job就失败了,job不会重试)
2.2、配置信息使用的三种方式
1)、在代码中使用SparkConf来配置。
2)、在提交的时候使用 --conf来配置。
spark-submit --master --conf k=v 如果要设置多个配置信息的值,需要使用多个–conf
3)、在spark的配置文件spark-default.conf中配置。
2.3、什么是挣扎(掉队)的任务?
当所有的task中,75%以上的task都运行成功了,就会每隔一百秒计算一次,计算出目前所有未成功任务执行时间的中位数*1.5,凡是比这个时间长的task都是挣扎的task。
2.4、关于任务调度的几个小问题
2.4.1、如果有1T数据,单机运行需要30分钟,但是使用Saprk计算需要两个小时(4node),为什么?
1)、发生了计算倾斜。大量数据给少量的task计算。少量数据却分配了大量的task。
2)、开启了推测执行机制。
2.4.2、对于ETL(数据清洗流程)类型的数据,开启推测执行、重试机制,对于最终的执行结果会不会有影响?
有影响,最终数据库中会有重复数据。
解决方案:
1)、关闭各种推测、重试机制。
2)、设置一张事务表。
1.はじめに
我々はスパークアプリケーションを実行すると、最初のステップは、Sparkアプリケーションアプリケーションを作成すること、およびその後、ドライバのアプリケーションリソースのリソーススケジューラを呼び出す必要があります。アプリケーションが成功した後、あなたがサインアップした後、アプリケーションのアプリケーション・リソースのためのマスターは、ノードの実行にタスクを分散するためにリソーススケジューラを呼び出します。並行して、各ノードで計算分散。
2、事前知識
アプリケーションのためには、リソースが執行あります。これは、エグゼキュータのメモリ、コアのためのリソースです。
労働者、waitingDrivers、waitingApps:マスター、いくつかのオブジェクトがあります。ここでは簡単な紹介を行うには、これらのオブジェクトのいくつかは、これらのオブジェクトは、ソースコードで宣言されている。ソースコードでのより詳細な認知、自己ビューの外観のために(ソースコードは、簡単な概要については、スカラ座をしてください使用しています参照「Scalaの速い学習」)。
ヴァル作品=新しいHashSetのWorkInfo
ヴァルwaitingDrivers =新しいArrayBuffer DriverInfo
ヴァルwaitingApps =新しいArrayBuffer にApplicationInfo
上記のコードでは、ノード情報がWorkInfoワークノードを表現します。DriverInfo要求情報は、ドライバから送信されます。ApplicationInfoアプリケーション情報がから送信されます。
新しい新しいHashSetのワークス=ヴァルWorkInfo
ワークスHashSetの仕事のアレイに記憶されているノード情報を用いて設定し、作業が重複ノードを格納回避することができます。なぜ重複を避けるべきですか?まず、私たちが知っている必要があり、すべての作業ノードは、何らかの理由でハングアップマスタは、ノードは、その作品にオブジェクトを削除しますマスターノードを入れて、次の時間を切ったときに、マスタに次のレポートの後にハングアップして通信することができるがありますその後、このノードに一緒に来るまでの時間です。このように、理論は、作業ノードを複製しません。しかし、特殊なケースがあります:作業は、次の通信の前に、ハングアップし、彼が始まっていること、そして仕事情報の繰り返しがあるだろうに動作します。
=新しい新しいwaitingDrivers ArrayBufferヴァルDriverInfo
マスター資源ドライバへのクライアントアプリケーション、アプリケーション関連情報は、一般的なDriverInfoマスターノードにドライバーパッケージとなり、その後、waitingDriversに追加されました。コレクションのwaitingDrivers要素が空でない場合、マスターは、クライアントがアプリケーションのリソースをマスターするために持っていることを示し、このwaitingDriversオブジェクトを監視します。あなたが最初の作品集をご覧ください。この時点では、ワーカーノードは、ドライバーを開始、要件を満たすことがわかりました。ドライバが正常に起動すると、アプリケーション情報はwaitingDriversオブジェクトから削除されます。
waitingApps =新しい新しいArrayBufferヴァルにApplicationInfo
ドライバが正常に起動した後は、waitingAppsのターゲット・マスター・ノードへのアプリケーションの情報ストレージ、アプリケーションのマスターにリソースを適用します。waitingAppsが空でない場合も同様に、現在のマスタドライバアプリケーションは、資金調達のために適用することを示します。適したワーカープロセスノードは、executorを開始見つけ、労働者のコレクションを表示するには、この時間は、デフォルトではすべての労働者は、エグゼキュータは、メモリとコアのすべての1Gを使用しますが、各アプリケーションキュータのためのちょうどスタートです。エグゼキュータアプリケーション情報を開始した後waitingAppsオブジェクトから除去されます。
使用上の注意:マスターモニター上記のこれらの3セットは、その後、最終的にどのようにそれを監視するのですか???
モニター専用のスレッドのこれら三組のマスターでない指摘には、比較的、これは資源のより無駄です話します。マスターが変更(追加または削除)の1セットのこれらの3セットは、それは()メソッドのスケジュールを呼び出しますとき、実際に変更、3組の「モニタリング」です。スケジュール処理ロジックカプセル化方法は、上述しました。
図4に示すように、詳細なステップ
1、コミットコマンドが(ドライバがリソースを適用するために使用される)クライアントスパーク提出するクライアントのプロセスを開始します。
2は、修士のwaitingDriversコレクションで、このアプリケーションに情報を追加するには、マスタードライバ、ドライバにリソースを適用します。マスタービューは、作業ノードの右を選ぶ、コレクションに動作します。
図3は、ノードが(使命は、クローズ処理を完了した火花提出し、ドライバー・プロセスが開始された)選択されたドライバーの作業でプロセスを開始します。
あなたは、リソースを実行するアプリケーションのための4、ドライバーアプリケーション・プロセス(このリソースは、エグゼキュータのプロセスを意味します)。アプリケーション内のwaitingAppsリソース情報のこの時間のマスターで、あなたはこのアプリケーションを追加します。その後、必要に応じて作業者が(各ノードがリソースの量を使用する)を使用どのノードを参照するために必要なコンピューティングリソースに適用されます。エグゼキュータこれらのノードでプロセスを開始します。
:(注ポーリングはExecutor.Executorはコアの全てが1Gメモリをノードと労働者によって管理することができます占め始めた)
、その後、あなたが実行している各ワーカーノードを処理するために、ドライバーエグゼキュータのタスクを配布することができます5。
5、リソーススケジューリング結論
1は、デフォルトでは、各アプリケーションの各ワーカーは、executorを開始します。各エグゼキュータすべてのコア1Gメモリとワーカーデフォルトで管理することができます。
2、あなたがコアエグゼキュータの使用回数を指定するには、アプリケーションの提出時に、より多くの労働者キュータに開始したい場合。コマンドをコミット:スパーク-提出--executor-コア
3は、デフォルトでは、起動するエグゼキュータの方法は、ローカライズされたデータの賛成で、ある程度まで、ポーリングを開始することです。
ポーリング開始とは何ですか???なぜそれが回転で起動しますか???
ポーリングが開始しました:ポーリングは、スタートのスタートです。たとえば、5人がいる、誰もがリンゴ+バナナを送りたいです。アイデアを配布開始したポーリングはこれです:りんごの最初の5分の人、Appleは完全な再配布バナナを配布します。
なぜそれを開始するためにポーリングを使うのか???我々は間違いなく、データの計算がデータを見つけることが最初に計算することである拡張したいです。ローカル・データ・ストレージは、むしろ再計算上のデータ転送よりも、直接計算されます。我々はn個のデータのみが計算に格納されている場合ワーカーノードは、ノードを設定します。計算するにはほんの数労働者は、労働者のほとんどがアイドル状態です。この提案は、確かに現実的ではありません。我々はエグゼキュータを開始するためにポーリングを使用して、各ノードでの作業を可能にします。
それは、高速でなければなりませんので、ノーデータ・ストレージノードのネットワーク・トラフィックので、タスクの数がより実行されます。だから、クラスタリソースもある程度、データ・ストレージ・ノードで計算するだけでなく、ローカライズされたデータを助長することができ無駄にしないでください。
6、スパーク厚いきめ細かい
6.1、粗粒(富裕層)
タスクの実行前に、それは最初のリソース要求が完了すると、すべてのタスクが終了したとき、我々はいくつかのリソースを解放します。
長所:各タスクの実行前に。あなたは、自分のリソースを適用する必要がある、と開始時間を節約しません。
短所:タスクを実行するすべてのリソースがリソースを解放しますまで待ち、クラスタを十分に活用することができません。
6.2、ファイングレイン(貧しい秒)
自分のリソースを適用するために、各タスクのために提出されたアプリケーションは、タスクのアプリケーションにリソースが実行する時に、このタスクを実行すると、すぐにリソースを解放します。
長所:リソースの解放が終了した直後にすべてのタスク、ヘルプは、リソースをフルに活用します。
短所:各タスクは、タスクの開始時刻をその結果、独自のリソースを適用する必要があるとして、長すぎるのステージは、ジョブ、アプリケーションの起動時間が延長さにつながります。
7、理解深める
ここではいくつかのマイナーな問題、コンピュータゲームの利点です。。。
前提条件:我々は、5人の労働者、各ワーカーノードのメモリ10G、10コアを提供していたとします。
1、火花提出--master ... --executor -cores 2 --executor、メモリ2G ... どのように多くのエグゼキュータ・プロセスは、クラスタ内で開始しますか???
:25
の分析:2つのコア+ 2Gのメモリを使用して、各エグゼキュータ・プロセス。だから、ワーカーノードは、ステーション5エグゼキュータを開始することができます。ワーカーノードの5つのセットがありますので。だから、5 * 5 = 25エグゼキュータ・プロセスの合計を開始することができます。
2、火花提出--master ... --executor -cores 3 --executor・メモリ4G ... どのように多くのエグゼキュータ・プロセスは、クラスタ内で開始しますか???
:10の
分析:著者はコマンドに従って、エグゼキュータ・プロセスは、3つのコア+ 4Gのメモリを占有する必要があります。ワーカーノードは、コア10とメモリ10Gを有しています。コアに基づいて算出した場合、3 = 10/3、図3は、執行を開始することができます。メモリ10のカウントによれば,, / = 4 2は、2執行を開始することができます。ビュー、メモリ不足のこの点は、確かに3つのエグゼキュータを開始しません。したがって、5×2 = 10ワーカー2執行を開始します。
3、火花提出--master ... --executor -cores 2 --executorメモリ2G --total-エグゼキュータ・コア10 ... どのように多くのエグゼキュータ・プロセスは、クラスタ内で開始しますか???( -総-エグゼキュータ-コア:最も使用されるコアの応用整数)
A:5つ
の分析:この質問は前の二つのより1つの制約は、10コアに起動します。あなたはこの条件を考慮していない場合は、この質問とケースの最初の質問は、25キュータ、シェア50コアを開始することができるはずです。しかし、2コアを使用して最大10個のアプリケーション全体のコア、執行の使用は、それが10/2 = 5です。あなただけの5つのエグゼキュータを開始することができます。
4、火花送信--master ... --executor -cores 2 --executorメモリ2G --total-エグゼキュータ-コア4 ... クラスタ内のエグゼキュータ分布???( -総-エグゼキュータ-コア:最も使用されるコアの応用整数)
A:労働者は無作為に2つのノードを見つけます。
分析:まったく同じの質問にタイトルやアイデア。コア限界は、25執行を開始することができないので、唯一4/2 = 2エグゼキュータ・プロセスを開始することができます。ポーリングタスクの起動モードの火花が有効にされているので、それは2つのランダム開始ノードワーカーエグゼキュータを見つけることになります。
図5に示すように、スタート執行式の数:分(分(WM / EM 、WC / EC)* WN、TEC / EC)
注:
--executor-コア:EC
--executor-メモリ:EM
--total-executor-コア:TECの
worker_num:のWnを
worker_memory:WM
worker_core:WCの
分析:
分(WM / EM、WC / EC):コアの数とメモリ要件、ノードは2つの値を得ることができるが執行を開始します。これらの2つの数字が小さい値をとります。
分= X1(WM / EM、WC / EC)のワイアード:執行ワーカーの数は、ノードのノード=執行作業者が開始することができるの総数。
X2 = TEC / EC:エグゼキュータがアクティブコアの要件の合計数の合計数を見つけることができます。
分(分(WM / EM、 WC / EC)* WN、TEC / EC)==分(X1、X2): エグゼキュータは小さな値をとる上で必要な量の2つのアウト。