Giraphソースコード解析(5) - データ同期サマリをロードします+

著者|ホワイトパイン

Giraph約9章の合計、この第五章。

環境:単一のマシン(マシン名:giraphx)には、2人の労働者を開始しました。

入力:SSSPフォルダには、二つの文書の1.TXTと2.txtがあります。

1は、マスター労働者の健康状態の報告の後、InputSplitを作成するために、マスターのを待つようになりました。

方法:有無を検出し、このウォッチャーのznodeに設定することにより、各ワーカーのznodeノード。そうでない場合、この方法は、待機状態に、現在のスレッド()のwaitForever BSPEventによってロックを解除します。マスターはのznodeを作成するまで待ちます。このステップはstartSuperStep BSPServiceWorkerクラスメソッドに配置され、以下のように、待機中のコードは次のとおりです。

Giraphソースコード解析(5) - データ同期サマリをロードします+
図2は、マスタコールcreateInputSplits()メソッドは、InputSplitを作成します。

Giraphソースコード解析(5) - データ同期サマリをロードします+

InputSplits VertexInputFormatユーザ設定を取得するgenerateInputSplits()メソッド。コードは以下の通りであります:

Giraphソースコード解析(5) - データ同期サマリをロードします+

minSplitCountHintは、分割の最小数を作成しており、その値は次のとおりです。

minSplitCountHint =労働者数目* NUM_INPUT_THREADS

NUM_INPUT_THREADS入力分割ローディングごとのスレッドの数、1のデフォルト値を表しています。検証後、minSplitCountHintはTextVertexValueInputFormat抽象クラスでgetSplitsパラメータ()メソッドは無視されます。ユーザー入力VertexInputFormat TextVertexValueInputFormat抽象クラスを継承します。

minSplitCountHintよりも結果splits.size少ない場合、一部の労働者には支出ではありません。

他の従業員がアクセスするように分割情報を取得した後、この情報は、飼育係に記述する必要があります。以下のようにして得られた分割情報:

[HDFS:// giraphx:9000 /ユーザ/ルート/ SSSP / 1.TXT:0 + 66、HDFS:// giraphx:9000 /ユーザ/ルート/ SSSP / 2.txt:0 + 46]

トラバーサルは、情報の価値を分割し、各分割のためのznodeを作成し、リストを分割します。スプリット-0のznodeのために作成された、次のとおりです。HDFS:// giraphx:9000 /ユーザー/ルート/ SSSP / 1.TXT:0 + 66

/ _hadoopBsp / job_201404102333_0013 / _vertexInputSplitDir / 0

HDFS:の値を、のznode分割-1(下記)を作成// giraphx:9000 /ユーザ/ルート/ SSSP / 2.txtを:+ 46 0

/ _hadoopBsp / job_201404102333_0013 / _vertexInputSplitDir / 1

それは、すべての分割が作成されていることを意味/ _hadoopBsp / job_201404102333_0013 / _vertexInputSplitsAllReady:最後に、のznodeを作成します。

3、マスタースプリット応じパーティションの作成。最初は、パーティションの数を決定します。

Giraphソースコード解析(5) - データ同期サマリをロードします+

MasterGraphPartitionerでBSPServiceMaster <IV、E、M>デフォルトのターゲットHashMasterPartitioner。次のようにcreateInitialPartitionOwners()メソッドは、次のとおりです。

Giraphソースコード解析(5) - データ同期サマリをロードします+

上記のコードは次のように計算され、パーティションツールPartitionUtilsに計算された数です。

partitionCount=PARTITION_COUNT_MULTIPLIER availableWorkerInfos.size() availableWorkerInfos.size() ,其中PARTITION_COUNT_MULTIPLIER表示Multiplier for the current workers squared,默认值为1 。

可见,partitionCount值为4(122)。创建的partitionOwnerList信息如下:

[(id=0,cur=Worker(hostname=giraphx, MRtaskID=1, port=30001),prev=null,ckpt_file=null),

(id=1,cur=Worker(hostname=giraphx, MRtaskID=2, port=30002),prev=null,ckpt_file=null),

(id=2,cur=Worker(hostname=giraphx, MRtaskID=1, port=30001),prev=null,ckpt_file=null),

(id=3,cur=Worker(hostname=giraphx, MRtaskID=2, port=30002),prev=null,ckpt_file=null)]

4、Master创建Znode:/_hadoopBsp/job_201404102333_0013/_applicationAttemptsDir/0/_superstepDir/-1/_partitionExchangeDir,用于后面的exchange partition。

5、Master最后在assignPartitionOwners()方法中

把masterinfo,chosenWorkerInfoList,partitionOwners等信息写入Znode中(作为Znode的data),该Znode的路径为: /_hadoopBsp/job_201404102333_0013/_applicationAttemptsDir/0/_superstepDir/-1/_addressesAndPartitions 。

Master调用barrierOnWorkerList()方法开始等待各个Worker完成数据加载。调用关系如下:

Giraphソースコード解析(5) - データ同期サマリをロードします+

barrierOnWorkerList中创建znode,path=/_hadoopBsp/job_201404102333_0013/_vertexInputSplitDoneDir 。然后检查该znode的子节点数目是否等于workers的数目,若不等于,则线程陷入等待状态。后面某个worker完成数据加载后,会创建子node(如 /_hadoopBsp/job_201404102333_0013/_vertexInputSplitDoneDir/giraphx_1)来激活该线程继续判断。

6、当Master创建第5步的znode后,会激活worker。

每个worker从znode上读出data,data包含masterInfo,WorkerInfoList和partitionOwnerList,然后各个worker开始加载数据。

把partitionOwnerList复制给BSPServiceWorker类中的workerGraphPartitioner(默认为HashWorkerPartitioner类型)对象的partitionOwnerList变量,后续每个顶点把根据vertexID通过workerGraphPartitioner对象获取其对应的partitionOwner。

Giraphソースコード解析(5) - データ同期サマリをロードします+

每个Worker从znode: /_hadoopBsp/job_201404102333_0013/_vertexInputSplitDir获取子节点,得到inputSplitPathList,内容如下:

[/_hadoopBsp/job_201404102333_0013/_vertexInputSplitDir/1,

/_hadoopBsp/job_201404102333_0013/_vertexInputSplitDir/0]

然后每个Worker创建N个InputsCallable线程读取数据。N=Min(NUM_INPUT_THREADS,maxInputSplitThread),其中NUM_INPUT_THREADS默认值为1,maxInputSplitThread=(InputSplitSize-1/maxWorkers +1

那么,默认每个worker就是创建一个线程来加载数据。

在InputSplitsHandler类中的reserveInputSplit()方法中,每个worker都是遍历inputSplitPathList,通过创建znode来保留(标识要处理)的split。代码及注释如下:

Giraphソースコード解析(5) - データ同期サマリをロードします+

当用reserveInputSplit()方法获取某个znode后,loadSplitsCallable类的loadInputSplit方法就开始通过该znode获取其HDFS的路径信息,然后读入数据、重分布数据。

Giraphソースコード解析(5) - データ同期サマリをロードします+

Giraphソースコード解析(5) - データ同期サマリをロードします+

VertexInputSplitsCallable类的readInputSplit()方法如下:

Giraphソースコード解析(5) - データ同期サマリをロードします+

7、每个worker加载完数据后,调用waitForOtherWorkers()方法等待其他workers都处理完split。

Giraphソースコード解析(5) - データ同期サマリをロードします+

策略如下,每个worker在/_hadoopBsp/job_201404102333_0013/_vertexInputSplitDoneDir目录下创建子节点,后面追加自己的worker信息,如worker1、worker2创建的子节点分别如下:

/_hadoopBsp/job_201404102333_0013/_vertexInputSplitDoneDir/giraphx_1

/_hadoopBsp/job_201404102333_0013/_vertexInputSplitDoneDir/giraphx_2

创建完后,然后等待master创建/_hadoopBsp/job_201404102333_0013/_vertexInputSplitsAllDone。

8、从第5步骤可知,若master发现/_hadoopBsp/job_201404102333_0013/_vertexInputSplitDoneDir下的子节点数目等于workers的总数目,就会在coordinateInputSplits()方法中创建

_hadoopBsp/job_201404102333_0013/_vertexInputSplitsAllDone,告诉每个worker,所有的worker都处理完了split。

9、最后就是就行全局同步。

master创建znode,path=/_hadoopBsp/job_201404102333_0013/_applicationAttemptsDir/0/_superstepDir/-1/_workerFinishedDir ,然后再调用barrierOnWorkerList方法检查该znode的子节点数目是否等于workers的数目,若不等于,则线程陷入等待状态。等待worker创建子节点来激活该线程继续判断。

每个worker获取自身的Partition Stats,进入finishSuperStep方法中,等待所有的Request都被处理完;把自身的Aggregator信息发送给master;创建子节点,如/_hadoopBsp/job_201404102333_0013/_applicationAttemptsDir/0/_superstepDir/-1/_workerFinishedDir/giraphx_1,data为该worker的partitionStatsList和workerSentMessages统计量;

最后调用waitForOtherWorkers()方法等待master创建/_hadoopBsp/job_201404102333_0013/_applicationAttemptsDir/0/_superstepDir/-1/_superstepFinished 节点。

master发现/_hadoopBsp/job_201404102333_0013/_applicationAttemptsDir/0/_superstepDir/-1/_workerFinishedDir的子节点数目等于workers数目后,根据/_hadoopBsp/job_201404102333_0013/_applicationAttemptsDir/0/_superstepDir/-1/_workerFinishedDir子节点上的data收集每个worker发送的aggregator信息,汇总为globalStats。

Master若发现全局信息中(1)所有顶点都voteHalt且没有消息传递,或(2)达到最大迭代次数 时,设置 globalStats.setHaltComputation(true)。告诉works结束迭代。

マスタ/ _hadoopBsp / job_201404102333_0013 / _applicationAttemptsDir / 0 / _superstepDir / -1 / _superstepFinishedノードを作成し、データがglobalStatsあります。すべての労働者は、現在のスーパーステップを終了教えてください。

各ワーカーは、マスタ/ _hadoopBsp / job_201404102333_0013 / _applicationAttemptsDir / 0 / _superstepDir / -1 / _superstepFinishedノードを作成し、検出のznode、即ち、グローバル統計のデータを読み出します。そして、次の反復を続行するかどうかを決定します。

10、次のスーパー同期ステップの開始後。

11、マスターと労働者は、同期処理をまとめました。

(1)マスタ作成のznodeのA、およびその後子供が労働者の数に等しい数のノードかどうかを検出し、待機中にそれを意味するものではありません。子ノードを作成するために、労働者の後、それがウェイクアップマスターを検出します。

(2)各ワーカーは、自分の仕事が完了した実施子ノードA1 Aさんを作成します。その後のznode B.を作成するためのマスターを待ちます

(3)サブマスタノードAの検出数のznode Bを作成し、労働者の数に等しい場合

(4)マスタノードBが作成されたら、それは、個々の作業者を活性化します。同期の終了は、各ワーカーは、次のスーパーのステップを開始することができます。

これは、本質的にグローバル同期のznodeのB.によって行われます

おすすめ

転載: blog.51cto.com/14463231/2427624