背景
监控是Spark非常重要的一部分。Spark的运行情况是由ListenerBus以及MetricsSystem 来完成的。通过Spark的Metrics系统,我们可以把Spark Metrics的收集到的信息发送到各种各样的Sink,比如HTTP、JMX以及CSV文件。
目前支持的Sink包括:
- ConsoleSink
- CSVSink
- JmxSink
- MetricsServlet
- GraphiteSink
- GangliaSink
有时我们需要实时获取metrics数据通过spark分析展示等需求,这个时候若有个KafkaSink将metrics指标数据实时往kafka发送那就太方便了,故有了这篇博文。
实践
所有的Sink都需要继承Sink这个特质:
private[spark] trait Sink {
def start(): Unit
def stop(): Unit
def report(): Unit
}
当该Sink注册到metrics系统中时,会调用start方法进行一些初始化操作,再通过report方式进行真正的输出操作,stop方法可以进行一些连接关闭等操作。直接上代码:
package org.apache.spark.metrics.sink
import java.util.concurrent.TimeUnit
import java.util.{Locale, Properties}
import com.codahale.metrics.MetricRegistry
import org.apache.kafka.clients.producer.KafkaProducer
import org.apache.spark.SecurityManager
import org.apache.spark.internal.Logging
private[spark] class KafkaSink(val property: Properties, val registry: MetricRegistry,
securityMgr: SecurityManager) extends Sink with Logging{
val KAFKA_KEY_PERIOD = "period"
val KAFKA_DEFAULT_PERIOD = 10
val KAFKA_KEY_UNIT = "unit"
val KAFKA_DEFAULT_UNIT = "SECONDS"
val KAFKA_TOPIC = "topic"
val KAFKA_DEFAULT_TOPIC = "kafka-sink-topic"
val KAFAK_BROKERS = "kafka-brokers"
val KAFAK_DEFAULT_BROKERS = "XXX:9092"
val TOPIC = Option(property.getProperty(KAFKA_TOPIC)).getOrElse(KAFKA_DEFAULT_TOPIC)
val BROKERS = Option(property.getProperty(KAFAK_BROKERS)).getOrElse(throw