SparkStreaming创建DirectStream连接kafka时策略详解

SparkKafka直接流(createDirectStream)和kafka分区

每个kafka主题分区对应一个RDD分区。
spark可以通过spark.streaming.kafka.maxRatePerPartition
配置,对每个分区每秒接受的消息树进行控制。

LocationStrategies

位置策略,
控制特定的主题分区在哪个执行器上消费的。
在executor针对主题分区如何对消费者进行调度。
位置的选择是相对的,位置策略有三种方案:
1.PreferBrokers
    首选kafka服务器,只有在kafka服务器和executor位于同一主机,可以使用该中策略。

2.PreferConsistent
    首选一致性.
    多数时候采用该方式,在所有可用的执行器上均匀分配kakfa的主题的所有分区。
    综合利用集群的计算资源。

3.PreferFixed
    首选固定模式。
    如果负载不均衡,可以使用该中策略放置在特定节点使用指定的主题分区。手动控制方案。
    没有显式指定的分区仍然采用(2)方案。

ConsumerStrategy

ConsumerStrategies

消费者策略,是控制如何创建和配制消费者对象。
或者对kafka上的消息进行如何消费界定,比如t1主题的分区0和1,
或者消费特定分区上的特定消息段。
该类可扩展,自行实现。
1.ConsumerStrategies.Assign
    指定固定的分区集合,指定了特别详细的方范围。
    def Assign[K, V](
          topicPartitions: Iterable[TopicPartition],
          kafkaParams: collection.Map[String, Object],
          offsets: collection.Map[TopicPartition, Long])

2.ConsumerStrategies.Subscribe
    允许消费订阅固定的主题集合。

3.ConsumerStrategies.SubscribePattern 
    使用正则表达式指定感兴趣的主题集合。

消费者策略和语义模型代码示例

 import java.net.Socket

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

    import scala.collection.mutable.ArrayBuffer
    import org.apache.kafka.clients.consumer.ConsumerRecord
    import org.apache.kafka.common.TopicPartition
    import org.apache.kafka.common.serialization.StringDeserializer
    import org.apache.spark.SparkConf
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    import org.apache.spark.streaming.kafka010._
    import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent
    import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe

    /**
      * Created by Administrator on 2018/3/8.
      */
    object SparkStreamingKafkaScala {

        def sendInfo(msg: String, objStr: String) = {
            //获取ip
            val ip = java.net.InetAddress.getLocalHost.getHostAddress
            //得到pid
            val rr = java.lang.management.ManagementFactory.getRuntimeMXBean();
            val pid = rr.getName().split("@")(0);
            //pid
            //线程
            val tname = Thread.currentThread().getName
            //对象id
            val sock = new java.net.Socket("s101", 8888)
            val out = sock.getOutputStream
            val m = ip + "\t:" + pid + "\t:" + tname + "\t:" + msg + "\t:" + objStr + "\r\n"
            out.write(m.getBytes)
            out.flush()
            out.close()
        }

        def main(args: Array[String]): Unit = {
            val conf = new SparkConf()
            conf.setAppName("kafka")
    //        conf.setMaster("spark://s101:7077")
            conf.setMaster("local[8]")

            val ssc = new StreamingContext(conf, Seconds(5))

            //kafka参数
            val kafkaParams = Map[String, Object](
                "bootstrap.servers" -> "s102:9092,s103:9092",
                "key.deserializer" -> classOf[StringDeserializer],
                "value.deserializer" -> classOf[StringDeserializer],
                "group.id" -> "g1",
                "auto.offset.reset" -> "latest",
                "enable.auto.commit" -> (false: java.lang.Boolean)
            )


            val map = scala.collection.mutable.Map[TopicPartition,String]()
            map.put(new TopicPartition("t1" , 0) , "s102")
            map.put(new TopicPartition("t1" , 1) , "s102")
            map.put(new TopicPartition("t1" , 2) , "s102")
            map.put(new TopicPartition("t1" , 3) , "s102")
            val locStra = LocationStrategies.PreferFixed(map) ;

            val consit = LocationStrategies.PreferConsistent

            val topics = Array("t1")

            //主题分区集合
            val tps = scala.collection.mutable.ArrayBuffer[TopicPartition]()
            tps.+=(new TopicPartition("t1" , 0))
    //        tps.+=(new TopicPartition("t2" , 1))
    //        tps.+=(new TopicPartition("t3" , 2))

            //偏移量集合
            val offsets = scala.collection.mutable.Map[TopicPartition,Long]()
            offsets.put(new TopicPartition("t1", 0), 3)
    //        offsets.put(new TopicPartition("t2", 1), 3)
    //        offsets.put(new TopicPartition("t3", 2), 0)

            val conss = ConsumerStrategies.Assign[String,String](tps , kafkaParams , offsets)



            //创建kakfa直向流
            val stream = KafkaUtils.createDirectStream[String,String](
                ssc,
                locStra,
                ConsumerStrategies.Assign[String, String](tps, kafkaParams, offsets)
            )

            val ds2 = stream.map(record => {
                val t = Thread.currentThread().getName
                val key = record.key()
                val value = record.value()
                val offset = record.offset()
                val par = record.partition()
                val topic = record.topic()
                val tt = ("k:"+key , "v:" + value , "o:" + offset, "p:" + par,"t:" + topic ,"T : " + t)
                //xxxx(tt) ;
                //sendInfo(tt.toString() ,this.toString)
                tt
            })

            ds2.print()

            ssc.start()

            ssc.awaitTermination()
        }
    }

你可能感兴趣的:(SparkStreaming创建DirectStream连接kafka时策略详解)