リアルタイム・データ・ストリームの解析処理をストリーミングスパーク、受信データのソースからのデータの安定した流れに切断時間間隔が処理され、
バッチと明確に区別ストリーミング、バッチデータは明確な境界を持って、データサイズが既知です;また、データサイズが不明である、データストリームの境界を処理しない流れる
、この場合には、ハードウェア、ネットワーク、および他の関連するリソースを処理するデータのレートともそうデータストリームが予測不可能であること、データストリームので流動特性を処理するが、ストリームのデータレートを制限することを定常流で来て、特定のデータの流れを処理するスパークノード障害、ネットワーク障害、またはデータがそこに降りてくるし続けた場合に、クラッシュにつながるストリーミングOOMスパークすることが可能と思われることはありません。
にスパークは、異なる戦略の制限速度を使用して、異なるデータソースをストリーミング、それはカフカのレート(速度)の計算をPIDControllerに使用されるアルゴリズムから計算されるソケットポリシーデータソースまたはデータ・ソースを制限するポリシーを制限することです。
以下は、ソース角度から導入されたソケット・データ・ソースとカフカデータソース流れを制限 管理。
更新レート制限の計算
スパークストリーミングストリーム処理は、実際にマイクロバッチ(マイクロバッチ)に基づいており、すなわち、間隔データがマイクロバッチ処理データのセクションに切断され、比較的短い時間によるデータストリーム。
StreamingContextレートコントローラ(rateController)はStreamingListenerリスナーに追加されたときに活性化される)を起動する(呼び出す;
各バッチ処理は、リスナー(RateController)をトリガするために完了すると、バッチ処理の終了時刻を用いて、処理遅延時間、スケジューリング遅延時間、記録着信PIDRateEstimator PIDアルゴリズム(PIDコントローラ)の放出速度制限とバッチのレート(速度)及び更新レート制限(レート制限)を算出する行数。
override def onBatchCompleted(batchCompleted: StreamingListenerBatchCompleted) {
val elements = batchCompleted.batchInfo.streamIdToInputInfo
for {
processingEnd <- batchCompleted.batchInfo.processingEndTime
workDelay <- batchCompleted.batchInfo.processingDelay
waitDelay <- batchCompleted.batchInfo.schedulingDelay
elems <- elements.get(streamUID).map(_.numRecords)
} computeAndPublish(processingEnd, elems, workDelay, waitDelay)
}
private def computeAndPublish(time: Long, elems: Long, workDelay: Long, waitDelay: Long): Unit =
Future[Unit] {
val newRate = rateEstimator.compute(time, elems, workDelay, waitDelay)
newRate.foreach { s =>
rateLimit.set(s.toLong)
publish(getLatestRate())
}
}
ソケットは、データソースを制限します
バッチレート制限は、ここでデータがソケットデータフローリストリクタを介して受信される、上記で算出された。
SocketInputStreamバッファに書き込まれる前にバッファBlockGeneratorコール・フローリストリクタに格納された受信データに基づいてメソッドを受け取ります(RateLimiter)は、書き込みデータへの電流を制限するために、
RateLimiter流量制限がRateLimiterグアバ流量制限を内蔵Googleのオープンソースを使用して、そのような単にグアバ流量制限をカプセル化し、
両者の使用によってスパークがストリーミングであってもよいですspark.streaming.receiver.maxRate初期速度パラメータと最大速度、spark.streaming.backpressure.initialRate; 4つのパラメーター値も配置さPIDController関連するアルゴリズムであってもよい。
RateLimiter流量制限は、トークンバケットアルゴリズムの基本原理に基づいている比較的単純ですいかなるトークンバケットは、好ましく確保するためのアルゴリズムを待ってブロックされない場合、一定速度のトークンバケットを生成するために、バケツは、要求を処理するトークンバケットからトークンを削除する必要が完全に停止されシステムがピークを圧倒していません。
private lazy val rateLimiter = GuavaRateLimiter.create(getInitialRateLimit().toDouble)
/**
* Push a single data item into the buffer.
*/
def addData(data: Any): Unit = {
if (state == Active) {
//调用限流器等待
waitToPush()
synchronized {
if (state == Active) {
currentBuffer += data
} else {
throw new SparkException(
"Cannot add data as BlockGenerator has not been started or has been stopped")
}
}
} else {
throw new SparkException(
"Cannot add data as BlockGenerator has not been started or has been stopped")
}
}
def waitToPush() {
//限流器申请令牌
rateLimiter.acquire()
}
基本的な使用制限グアバライブラリRateLimiter電流:
//创建限流器,每秒产生令牌数1
RateLimiter rateLimiter=RateLimiter.create(1);
for (int i = 0; i < 10; i++) {
//获得一个令牌,未申请到令牌则阻塞等待
double waitTime = rateLimiter.acquire();
System.out.println(String.format("id:%d time:%d waitTime:%f",i,System.currentTimeMillis(),waitTime));
}
カフカは、電流制限用のデータソースを達成します
次のようにスパークにアクションを引くストリーミングカフカカフカデータパケットは次のようになり:
1、最新の撮影カフカオフセット、パーティション
各パーティションはに引くことができるrateControllerメッセージの最大数を制限することにより2、
DirectKafkaInputDStream KafkaRDDにおいて、3はそれで、作成データを引き出し、関連するオブジェクトを呼び出します
上記の手順からも見ることができ、制限はカフカオフセットパーティション(オフセット)もメッセージの数の範囲を制限することができるカフカから取り出したように、電流制限、スパークの目的はカフカこのストリーミング達成するようにすることによって達成される、引っ張られ;
各パーティション率は、以下の手順制限の計算値:
現在のオフセット入手可能な最新seekToEndを取得することで、1は、比較は、現在の遅延は、すべてのパーティションをオフセット得るオフセット
-電流パーシャル単一パーティション遅延オフセット=最新の記録オフセットシフト量記録
2を、各パーティションの構成要素は、最大速度取得
:のように計算される背圧の各パーティション率について計算(spark.streaming.kafka.maxRatePerPartition)、背圧速度計算を、
単一のパーティションが単一のパーティションバック圧力をオフセット=遅延量/全パーティションの合計遅延*レート制限
レート制限(レート制限):計算動的PIDController来
構成した場合の、各パーティションの最大速度は、最大速度であり、アイテムが取るように配置さの背圧の両方の最小値を、設定されていない、次に取る背圧の速度を各パーティションに対して律速として、
3、メッセージ=の最大数制限各パーティションレートに対する各パーティションのバッチ間隔(batchDuration)*
4は、現在のパーティションを取る両方+パーティションの最大メッセージ数とオフセット最新のうち最小にし、それによって制御オフセットメッセージレートを引き出します。
オフセット電流は、のようにメッセージの最新の現在のオフセット+パーティションの最大数であり、+パーティションのオフセットは、最新が他のオフセット取るメッセージの最大数よりも大きい範囲カフカオフセットデータを引っ張ります。
// 限制每个分区最大消息数
protected def clamp(
offsets: Map[TopicPartition, Long]): Map[TopicPartition, Long] = {
maxMessagesPerPartition(offsets).map { mmp =>
mmp.map { case (tp, messages) =>
val uo = offsets(tp)
tp -> Math.min(currentOffsets(tp) + messages, uo)
}
}.getOrElse(offsets)
}
かカフカソケットデータソースまたはデータ・ソースは、スパークストリーミング使用さPIDControllerを計算するためのアルゴリズムレート制限の差がデータソース取得の2つだけの方法であるため、値をデータ特性決定のを。グアバRateLimiterを使用し、そしてカフカ自身がデータソース実現ソケットデータソースベースのオフセットが制限を、
上記の導入のためのフレームワークのバージョンその:火花ストリーミングカフカ-0-10_2.11とバージョン2.3.2ストリーミングスパーク。
参考:
http://kafka.apache.org
http://spark.apache.org
記事開始アドレス:Solinx
https://mp.weixin.qq.com/s/yHStZgTAGBPoOMpj4e27Jg