中国移动实时项目的问题总结

  1.spark程序中的kafka的host也定要写成hostname的格式而不是写ip的格式:

    例如:"bootstrap.servers" -> "os1:9092,os2:9092,os3:9092",而不是ip的格式,否则会报错

  2.flume的spooldir的source问题:

    如果使用spooldir进行监听日志文件夹,如果文件夹中的文件是递增的形式进行存入日志,这样使用spooldir的方式就会报错,因为spooldir在读取文件的时候,不能进行对文件进行更改,否则就报错

    解决办法:可以使用 taildir source

  3.增加spark-streaming的并发处理能力:

    增加kafka的某个topic分区数量,然后再spark提交任务的时候的executor的数量最好和topic的数量一致,这样每个executor都可以进行消费,否者就会存在executor浪费的

  4.spark-streaming消费kafka数据的时候偏移量的存储:

    偏移量存储的一般自己维护,因为使用spark-streaming - kafka0.10是将offset存储在kafka的__consumer_offsets这个topic中,但是这样不便于我们进行偏移量的维护,虽然说新版 kafka 中已经无需使用 zookeeper 管理偏移量了,

    但是使用 zookeeper 管理偏移量相比 kafka 自行管理偏移量有如下几点好处:

      可以使用 zookeeper 管理工具轻松查看 offset 信息;
      无需修改 groupId 即可从头读取消息;
      特别情况下可以人为修改 offset 信息。
      借助 zookeeper 管理工具可以对任何一个节点的信息进行修改、删除,如果希望从最开始读取消息,则只需要删除 zk 某个节点的数据即可。

    相应的offset维护代码:

    

package utils

import kafka.utils.{ZKGroupTopicDirs, ZkUtils}
import org.I0Itec.zkclient.ZkClient
import org.apache.kafka.common.TopicPartition
import org.apache.log4j.{Level, Logger}
import org.apache.spark.SparkConf
import org.apache.spark.rdd.RDD
import org.apache.spark.streaming.kafka010.{ConsumerStrategies, HasOffsetRanges, KafkaUtils, LocationStrategies}
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.kafka.common.serialization.StringDeserializer



object KafkaDirect_ZK_Offset {
  def main(args: Array[String]): Unit = {
    Logger.getLogger("org.apache.spark").setLevel(Level.OFF)
    val conf: SparkConf = new SparkConf().setAppName("KafkaDirect_ZK_Offset").setMaster("local[*]")
    val ssc: StreamingContext = new StreamingContext(conf,Seconds(5))
    val groupId = "cmcc_test2"

    /**
      * kafka参数列表
      */
    val kafkaParams = Map[String,Object](
      "bootstrap.servers" -> "os1:9092,os2:9092,os3:9092",
      "key.deserializer" -> classOf[StringDeserializer],
      "value.deserializer" -> classOf[StringDeserializer],
      "group.id" -> groupId,
      "auto.offset.reset" -> "earliest",
      "enable.auto.commit" -> (false:java.lang.Boolean)

    )
    val topic = "cmcc1"
    val topics = Array(topic)

    /**
      * 如果我们自己维护偏移量
      * 问题:
      * 1.程序在第一次启动的时候,应该从什么开始消费数据?earliest
      * 2.程序如果不是第一次启动的话,应该从什么位置开始消费数据?
      * 上一次自己维护的偏移量接着往后消费,比如上一次存储的offset=88
      */
    val zKGroupTopicDirs: ZKGroupTopicDirs = new ZKGroupTopicDirs(groupId,topic)
    /**
      * 生成的目录结构
      * /customer/g1/offsets/wordcount
      */
    val offsetDir: String = zKGroupTopicDirs.consumerOffsetDir
    //zk字符串连接组
    val zkGroups = "os1:2181,os2:2181,os3:2181"
    //创建一个zkClient连接
    val zkClient: ZkClient = new ZkClient(zkGroups)
    //子节点的数量
    val childrenCount: Int = zkClient.countChildren(offsetDir)
    //子节点的数量>0就说明非第一次
    val stream = if(childrenCount>0){
      println("已经启动过")
      //用来存储我们已经读取到的偏移量
      var fromOffsets = Map[TopicPartition,Long]()
      (0 until childrenCount).foreach(partitionId => {
        val offset = zkClient.readData[String](offsetDir+s"/$partitionId")
        fromOffsets += (new TopicPartition(topic,partitionId) -> offset.toLong)
      })
      KafkaUtils.createDirectStream(ssc,
        LocationStrategies.PreferConsistent,
        ConsumerStrategies.Assign[String,String](fromOffsets.keys.toList,kafkaParams,fromOffsets)
      )
    }
    else{
      println("第一次启动")
      KafkaUtils.createDirectStream(ssc,
        LocationStrategies.PreferConsistent,
        ConsumerStrategies.Subscribe[String,String](topics,kafkaParams)

      )
    }
    stream.foreachRDD(
      rdd => {
        //转换rdd为Array[OffsetRange]
        val offsetRanges =  rdd.asInstanceOf[HasOffsetRanges].offsetRanges
        val maped: RDD[(String, String)] = rdd.map(record => (record.key,record.value))
        //计算逻辑
        //maped.foreach(println)
        //自己存储数据,自己管理
        for(o <-offsetRanges){
          //写入到zookeeper,第二个参数为是否启动安全
          ZkUtils(zkClient,false).updatePersistentPath(offsetDir+"/"+o.partition,o.untilOffset.toString)
        }
      }

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

  

猜你喜欢

转载自www.cnblogs.com/zyc-2019/p/10617897.html