(C) de ventana se calcula y operaciones de combinación SparkStreaming

El accionamiento de las ventanillas SparkStreaming

Spark Streaming Streaming marco de computación también proporciona una operación de ventana, lo que permite la aplicación de varias funciones en la ventana de conversión; obras como se muestra
Aquí Insertar imagen Descripción
en esta figura se describe con ventana deslizante un salto
utilizando la ventana debe especificar dos parámetros:

  • longitud de la ventana : longitud real de la longitud de la ventana de la ventana (en el mapa, la longitud de la ventana es de tres unidades de tiempo)
  • Sliding paso : intervalo o paso deslizante paso de deslizamiento (la figura, el tamaño de deslizamiento paso ventana está contenido dos veces)

nota:

  • Si es necesario definir una ventana de rodadura, 窗口长度=滑动步长que pueda
  • ventana de la sesión no admite
  • Tiene que haber un estado de la informática

Aquí Insertar imagen Descripción
A continuación se analiza la diferencia entre las dos versiones de reduceByKeyAndWindow

  • reduceByKeyAndWindow ( func , windowLength , slideInterval , [ numTasks ])
  • reduceByKeyAndWindow ( FUNC , invFunc , windowLength , slideInterval , [ numTasks ]) más eficiente reduceByKeyAndWindow operación

Motivo:

Ambos métodos se llevan a cabo de acuerdo con el valor de la clave para reducir la operación, y los resultados de la operación de estos dos métodos son los mismos, la diferencia es diferentes eficiencias, el método más eficiente para la espalda;

  • Un primer método: una base acumulativa (ventana micro lote resultados acumulativos)
  • El segundo método: cálculo incrementales (ventana de resultados del cálculo en un nuevo elemento de ventana actual + - expira una ventana = ventana de datos resultado de cálculo actual)

análisis Principio:

DSTREAM: 10 9 8 7 6 5 4 3 2 1
microbatch: b1: b2 1: 2 b3: 3 ...

Ventana calculado: longitud 5 paso 3

W1 de :. 5. 4. 3. 1 2
W2 de :. 4. 5. 6. 7. 8
W3 de: 10. 11. 7. 8. 9
============================= =============
primer método: base acumulativa reduceByKeyAndWindow

w1: 1 + 2 + 3 + 4 + 5 = 15 ( calculados cinco veces)
w2 de :. 6. 4 + 5 + 30 + = 8. 7 + (calculado 5).
W3: ...

El segundo método: el cálculo de una ventana reduceByKeyAndWindow incremental de cálculo + nuevos datos de la ventana actual - una ventana en los datos de caducidad

w1: 0 + 1 + 2 + 3 + 4 + 5 - 0 = 15 ( calculado 6)
w2 de:. + 15 + 6. 8. 7 + - 1 - 2-3 = 30 (calculado 6)
W3: 30 9 + 10 11 -4-5-6 = ...

¿Por qué es la eficiencia del segundo método es relativamente alto?

Reflect: la longitud de la ventana deslizante es relativamente grande y un tamaño relativamente pequeño paso

Longitud: 100s pasos: 1

W1 :. 1 - 100
w2 de: 2 - 101
W3 :. 3 - 102
=================================== ====
cantidad total calculado:
W1 :. 3. 1 + 2 + ... + 100 100 veces 4.
w2: 2 + 3 + 4 + 5 ... 101

Incremental calcula:
W1: 1+ 3 + 2 + 100.
W2 de: 5050 + 101 = -1 resultado de la ventana actual 2

Conclusión: La coincidencia de la ventana de forma más eficiente de utilizar la segunda recomendación, la ventana de datos es menos coincidiendo utilizando un primer

package window.transformation

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}

/**
 * 测试窗口的转换函数(6个)
 */
object TransformationOnWindow {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("wordcount on window").setMaster("local[*]")
    // 注意:微批和窗口的大小必须是倍数关系
    // 如:微批1s   窗口 5s
    // 如:微批5s   窗口 10、15、20...
    val ssc = new StreamingContext(conf, Seconds(1))
    ssc.sparkContext.setLogLevel("ERROR")

    // 并没有设定检查点??(程序可以使用:因为有本地状态内存)
    // 建议设置检查点,对本地状态提供远程副本
    ssc.checkpoint("hdfs://xxx:9000/checkpo")

    val lines = ssc.socketTextStream("localhost", 7777)

    /*
    lines
      .flatMap(_.split(","))
      .map((_, 1))
      // 只负责划分窗口 不负责处理数据
      //.window(Seconds(10),Seconds(5))
      // 滑动步长默认为1s
      //.window(Seconds(10))

      // countByWindow方法  统计窗口中元素的个数
      //.countByWindow(Seconds(10),Seconds(5))
      .print()
     */

    /*
    lines
        .flatMap(_.split(","))
        .map(strNum => strNum.toInt)
        // reduceByWindow 基于窗口计算
        .reduceByWindow((v1:Int,v2:Int) => v1+v2,Seconds(10),Seconds(5))
        .print()
     */

    /*
    lines
      .flatMap(_.split(","))
      .map((_, 1))
      // 第一个参数:增量式的加法  第二个参数:过期数据的减法
      .reduceByKeyAndWindow(_ + _, _ - _, Seconds(5), Seconds(3))
      .print()
     */


    lines
      .flatMap(_.split(","))  // word
      // countByValueAndWindow 统计当前窗口中单词相同的个数 返回(key,count)
      .countByValueAndWindow(Seconds(5), Seconds(3))
      .print()
    ssc.start()
    ssc.awaitTermination()
  }
}

Pregunta: ¿Por qué es el cálculo SparkStreaming ventana debe ser cómputo con estado (debe ser puesto de control conjunto)?

Debido a que el flujo de datos es SparkStreaming división aceptará un lote de datos (micro lotes), por micro-batch RDD motor de procesos Spark, para producir la corriente resultado final. DSTREAM capa inferior se compone de una secuencia Seq [RDD], y que comprende cada uno una pluralidad de tales ventanas micro lotes. ventana, así, el resultado final será calculado en serie calcula el resultado final, es decir, necesita una ventana de datos cuando la ventana próximos cálculos.
En resumen, la ventana se debe calcular SparkStreaming se proporciona punto de control, y se debe calcular con estado

unirse a la Operación

Sobre la base de la ventana DSTREAM y DSTREAM Únete
Aquí Insertar imagen Descripción
Nota: Para DSTREAM ventana y DSTREAM unirse a los genéricos deben ser [String, String]

package join

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Minutes, Seconds, StreamingContext}

object DStreamAndDStreamJoinOnWindow {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setMaster("local[*]").setAppName("streaming wordcount")

    val ssc = new StreamingContext(conf, Seconds(5))
    // 将日志等价变为高级别
    ssc.sparkContext.setLogLevel("ERROR")

    //2. 构建数据源的DStream
    // 通过TCP Source构建DStream对象 获取Tcp请求数据
    val w1 = ssc.socketTextStream("localhost",8888).map((_,1)).window(Seconds(10))
    val w2 = ssc.socketTextStream("localhost",7777).map((_,1)).window(Seconds(15))
    /// 事件时间处理
    w1
      .join(w2)
      .print()

    ssc.start()
    ssc.awaitTermination()
  }
}

DSTREAM y RDD de la unión (flujo y el lote Unir)

  • Aquí con una pequeña caja de entender lo determinado por lotes de Ingreso escenarios de flujo y qué (por ejemplo: algunas aplicaciones de palabras sensibles filtran y se sustituyen por **)
package join

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}

/**
 * 敏感词过滤
 */
object DStreamAndRDDJoin {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setMaster("local[2]").setAppName("streaming wordcount")

    val ssc = new StreamingContext(conf, Seconds(5))
    // 将日志等价变为高级别
    ssc.sparkContext.setLogLevel("ERROR")

    // 流数据stream
    val messages = ssc.socketTextStream("localhost", 7777)

    // 批次rdd
    val words = ssc.sparkContext.makeRDD(List(("sb", 1), ("傻逼", 1)))

    messages
      .map((_, 1))
      .transform(rdd => {
        // 连接操作 最好左外连接
        rdd.leftOuterJoin(words)
      })
      .map(t2 => {
        var message = t2._1
        if(!t2._2._2.isEmpty){
          message = "**"
        }
        message
      })
      .print()

    ssc.start()
    ssc.awaitTermination()
  }
}
Publicado 24 artículos originales · ganado elogios 1 · visitas 494

Supongo que te gusta

Origin blog.csdn.net/Mr_YXX/article/details/105035547
Recomendado
Clasificación