tutorial spark que kafka data apache-spark spark-streaming

apache spark - spark - Transmisión de chispas: ventanas sin exceso de alimentación sin estado frente al estado de mantenimiento



spark streaming kafka (2)

Creo que uno de los otros inconvenientes del tercer enfoque es que los RDD no se reciben cronológicamente ... considerando su ejecución en un clúster ...

ongoingEventsStream.foreachRDD { /*accumulate state in casssandra*/ }

también, ¿qué pasa con la comprobación y el fallo del nodo del controlador? En ese caso, ¿vuelve a leer todos los datos? ¿Tienes curiosidad por saber cómo quieres manejar esto?

Supongo que quizás map withstate es un mejor enfoque por el que considera todos estos escenarios ...

¿Cuáles serían algunas consideraciones para elegir operaciones de ventana deslizante sin estado (por ejemplo, reducirByKeyAndWindow) en lugar de mantener el estado (por ejemplo, a través de updateStateByKey o el nuevo mapStateByKey) al manejar un flujo de sesiones de eventos secuenciales y finitos con Spark Streaming?

Por ejemplo, considere el siguiente escenario:

Un dispositivo portátil rastrea los ejercicios físicos realizados por el usuario. El dispositivo detecta automáticamente cuándo comienza un ejercicio y emite un mensaje; emite mensajes adicionales mientras se realiza el ejercicio (p. ej., frecuencia cardíaca); Y, finalmente, emite un mensaje cuando se realiza el ejercicio.

El resultado deseado es un flujo de registros agregados por sesión de ejercicio. es decir, todos los eventos de la misma sesión deben agregarse juntos (por ejemplo, para que cada sesión pueda guardarse en una sola fila de base de datos). Tenga en cuenta que cada sesión tiene una duración finita, pero el flujo completo desde múltiples dispositivos es continuo. Para mayor comodidad, supongamos que el dispositivo genera un GUID para cada sesión de ejercicio.

Puedo ver dos enfoques para manejar este caso de uso con Spark Streaming:

  1. Usando ventanas no superpuestas, y manteniendo el estado. Se guarda un estado por GUID, y todos los eventos coinciden. Cuando llega un nuevo evento, el estado se actualiza (por ejemplo, usando mapWithState), y en caso de que el evento sea "final de sesión de ejercicio", se emitirá un registro agregado basado en el estado y se eliminará la clave.

  2. Usando ventanas deslizantes superpuestas, y manteniendo solo las primeras sesiones. Suponga una ventana deslizante de longitud 2 e intervalo 1 (vea el diagrama a continuación). También asuma que la longitud de la ventana es 2 X (tiempo máximo posible de ejercicio). En cada ventana, los eventos son creados por GUID, por ejemplo, usando reduceByKeyAndWindow. Luego, todas las sesiones que comenzaron en la segunda mitad de la ventana se vuelcan, y las sesiones restantes se emiten. Esto permite usar cada evento exactamente una vez, y asegura que todos los eventos que pertenecen a la misma sesión se agreguen juntos.

Diagrama para el enfoque # 2:

Only sessions starting in the areas marked with /// will be emitted. ----------- |window 1 | |////| | ----------- ---------- |window 2 | |////| | ----------- ---------- |window 3 | |////| | -----------

Pros y contras que veo:

El enfoque # 1 es menos costoso computacionalmente, pero requiere guardar y administrar el estado (por ejemplo, si el número de sesiones simultáneas aumenta, el estado puede ser mayor que la memoria). Sin embargo, si el número máximo de sesiones simultáneas está limitado, esto podría no ser un problema.

El enfoque # 2 es dos veces más caro (cada evento se procesa dos veces) y con una latencia más alta (tiempo de ejercicio máximo 2 X), pero más simple y fácil de manejar, ya que no se retiene ningún estado.

¿Cuál sería la mejor manera de manejar este caso de uso? ¿Es alguno de estos enfoques el "correcto" o hay mejores formas?

¿Qué otros pros / contras deben tenerse en cuenta?


Normalmente no hay un enfoque correcto , cada uno tiene compensaciones. Por lo tanto, agregaría un enfoque adicional a la mezcla y resumiré mi opinión sobre sus pros y sus contras. Así podrás decidir cuál es el más adecuado para ti.

Enfoque de estado externo (enfoque # 3)

Puede acumular el estado de los eventos en almacenamiento externo. Cassandra es muy utilizada para eso. Puede manejar eventos finales y en curso por separado, por ejemplo, como a continuación:

val stream = ... val ongoingEventsStream = stream.filter(!isFinalEvent) val finalEventsStream = stream.filter(isFinalEvent) ongoingEventsStream.foreachRDD { /*accumulate state in casssandra*/ } finalEventsStream.foreachRDD { /*finalize state in casssandra, move to final destination if needed*/ }

Enfoque trackStateByKey (enfoque # 1.1)

Podría ser una solución potencialmente óptima para usted, ya que elimina los inconvenientes de updateStateByKey, pero considerando que se acaba de lanzar como parte de la versión Spark 1.6, también podría ser riesgoso (ya que por alguna razón no está muy publicitado). Puede utilizar el link como punto de partida si desea obtener más información.

Pros contras

Enfoque # 1 (updateStateByKey)

Pros

  • Fácil de entender o explicar (para el resto del equipo, los recién llegados, etc.) (subjetivo)
  • Almacenamiento : un mejor uso de la memoria almacena solo el último estado de ejercicio
  • Almacenamiento : mantendrá solo los ejercicios en curso y los descartará tan pronto como terminen
  • La latencia está limitada solo por el rendimiento de cada procesamiento de micro lotes

Contras

  • Almacenamiento : si el número de teclas (ejercicios concurrentes) es grande, es posible que no se ajuste a la memoria de su grupo
  • Procesamiento : ejecutará la función updateState para cada clave dentro del mapa de estado, por lo tanto, si el número de ejercicios concurrentes es grande, el rendimiento se verá afectado

Enfoque # 2 (ventana)

Si bien es posible lograr lo que necesita con Windows, parece mucho menos natural en su escenario.

Pros

  • El procesamiento en algunos casos (dependiendo de los datos) puede ser más efectivo que updateStateByKey, debido a la tendencia de updateStateByKey a ejecutar la actualización en cada clave, incluso si no hay actualizaciones reales

Contras

  • El "máximo tiempo de ejercicio posible", que parece un gran riesgo, podría ser una duración bastante arbitraria basada en un comportamiento humano. Algunas personas pueden olvidar "terminar el ejercicio". También depende del tipo de ejercicio, pero puede variar de segundos a horas, cuando se desea una menor latencia para ejercicios rápidos, mientras que tendría que mantener la latencia tan alta como el ejercicio más largo podría existir.
  • Se siente más difícil de explicar a otros sobre cómo funcionará (subjetivo)
  • Almacenamiento : Deberá mantener todos los datos dentro del marco de la ventana, no solo el más reciente. También liberará la memoria solo cuando la ventana se deslice fuera de este intervalo de tiempo, no cuando el ejercicio haya terminado realmente. Si bien no será una gran diferencia si solo mantendrás los últimos dos intervalos de tiempo, aumentará si intentas lograr una mayor flexibilidad deslizando la ventana más a menudo.

Enfoque # 3 (estado externo)

Pros

  • Fácil de explicar, etc. (subjetivo).
  • Enfoque de procesamiento de transmisión pura, lo que significa que la chispa es responsable de actuar en cada evento individual, pero no intentar almacenar el estado, etc. (subjetivo)
  • Almacenamiento : no limitado por la memoria del clúster para almacenar el estado; puede manejar una gran cantidad de ejercicios simultáneos
  • Procesamiento : el estado se actualiza solo cuando hay actualizaciones reales (a diferencia de updateStateByKey)
  • La latencia es similar a updateStateByKey y solo está limitada por el tiempo requerido para procesar cada micro-lote

Contras

  • Componente adicional en su arquitectura (a menos que ya use Cassandra para su salida final)
  • Procesamiento : por defecto es más lento que el procesamiento solo en chispa ya que no está en la memoria + necesita transferir los datos a través de la red
  • Tendrá que implementar exactamente una vez semántica para generar datos en cassandra (para el caso de fallas en el trabajo durante foreachRDD)

Enfoque sugerido

Probaría lo siguiente:

  • Pruebe el enfoque de UpdateStateByKey en sus datos y su clúster.
  • vea si el consumo y el procesamiento de la memoria son aceptables incluso con una gran cantidad de ejercicios simultáneos (se espera en las horas pico)
  • Vuelve a acercarte con Cassandra en caso de no ser así.