kafka에서 데이터를 가져 와서 redis에 씁니다.

여러분: 

  좋다! kafka에서 데이터를 가져 와서 redis에 쓰려면 spark에서 redis 클라이언트 구성을 사용해야합니다. 이전 블로그 ( https://blog.csdn.net/zhaoxiangchong/article/details/78379883 )를 참조하세요 .

첫 번째 단계는 데이터를 kafka에 입력하는 것입니다. 이전 블로그 https://blog.csdn.net/zhaoxiangchong/article/details/78379927을 참조하세요.

참고 : kafka의 주제 이름에 특히주의하십시오.이 두 가지는 동일해야합니다.

두 번째 단계는 아래와 같이 kafka 코드를 redis에 배포하는 것입니다.

package Traffic


import java.text.SimpleDateFormat
import java.util.Calendar
import kafka.serializer.{StringDecoder, StringEncoder}
import org.apache.spark.streaming.kafka.KafkaUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext}
import net.sf.json.JSONObject


/**
  * Created by Administrator on 2017/10/14.
  * 功能: 从kafka中获取数据写入到redis中
  *
  */
object CarEventAnalysis {
  def main(args: Array[String]): Unit = {
   //配置SparkStrteaming
    val conf=new SparkConf().setAppName("CarEventAnalysis").setMaster("local[2]")
    val sc=new SparkContext(conf)
    val ssc=new StreamingContext(sc,Seconds(5))
    val dbindex=1 //指定是用哪个数据库进行连接
    //从kafka中读取数据(用直连的方法)
    val topics=Set("car_event")
    // 只要和brokers相关的都要写全
    val brokers="192.168.17.108:9092"
    //配置kafka参数
    val kafkaParams=Map[String,String](
      "metadata.broker.list"->brokers,
    "serializer.class"->"kafka.serializer.StringEncoder"
    )
    //创建一个流  这是一个模板代码  参数中的两个String代表的是kafka的键值对的数据,及key和value
    val kafkaStream=KafkaUtils.createDirectStream[String,String,
                    StringDecoder,StringDecoder](ssc,kafkaParams,topics)
    //从kafka中将数据读出
    val events=kafkaStream.flatMap(line=>{
      //转换为object
      val data=JSONObject.fromObject(line._2) // ._2是真正的数据
//      println(data)
      //必须用Some修饰data option有两个子类 none 代表无值  some代表有值
      // 加上some表示一定有值,后面有x.getString和x.getInt,保证程序能知道有值
      Some(data)
    })
    //从kafka中取出卡口编号和速度数据
    val carspeed=events.map(x=>(x.getString("camer_id"),x.getInt("car_speed")))
    //把数据变成(camer_id,(car_speed,1))
        .mapValues((x:Int)=>(x,1.toInt))
      //每隔10秒计算一次前20秒的速度(4个rdd) Tuple2表示两个参数
      // (速度,数量)  (速度,数量)
      .reduceByKeyAndWindow((a:Tuple2[Int,Int], b:Tuple2[Int,Int]) =>
      {(a._1 + b._1,a._2 + b._2)},Seconds(20),Seconds(10))
    // carspeed  速度之和  数量之和
//    carspeed.map{case(key,value)=>(key,value._1/value._2.toFloat)}
     carspeed.foreachRDD(rdd=>{
       rdd.foreachPartition(partitionofRecords=>{
         //得到连接池的一个资源
         val jedis=RedisClient.pool.getResource
         // camer_id 卡口以及总的速度
         partitionofRecords.foreach(pair=>{
           val camer_id=pair._1  //卡口
           val total_speed=pair._2._1  //总的速度
           val count=pair._2._2  //总的数量
           val now=Calendar.getInstance().getTime() //获取当前的时间
           val minuteFormat=new SimpleDateFormat("HHmm") //获取分钟格式
           val dayFormat=new SimpleDateFormat("yyyyMMdd") //获取天格式
           val time = minuteFormat.format(now) //获取分钟
           val day = dayFormat.format(now)     //获取天


           //开始往redis中插入数据
           if(count!=0){
             jedis.select(dbindex)   //用选择的数据库
             // set进去一个map
             jedis.hset(day + "_" + camer_id, time ,total_speed + "_" + count)
             // 从redis中取数据
             val foreachdata=jedis.hget(day + "_" + camer_id, time)
             println(foreachdata)
           }
         })
         RedisClient.pool.returnResource(jedis)
       })
     })
    println("----------计算开始---------------------------")


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

 3 단계 : 두 번째 단계에서 배포 한 kafka 코드를 실행하여 아이디어에 redis를 입력합니다. 프로그램의 스크린 샷은 다음과 같습니다.

설명 : 이것은 kafka에 해당하는 주제에 데이터를 입력 할 작업이 없음을 나타냅니다. 이것은 정상입니다. 현재 Kafka에 데이터가 없기 때문에이 단계는 코드의 정확성을 테스트하는 것입니다.

종속 jar가 도입되지 않은 경우이 단계에서 오류가보고됩니다. 스크린 샷은 다음과 같습니다.

설명 : ezmorph-1.0.6.jar 및 3 개의 종속 jar commons-collections-3.2.jar, commons-lang-2.3.jar, commons-pool2-2.2.jar, 총 4 개의 jar를 도입해야합니다. 

네 번째 단계 : 첫 번째 단계를 실행하여 Kafka에서 데이터를 인쇄합니다. 스크린 샷은 아래와 같습니다.

설명 : 1 스크린 샷은 Kafka에서 데이터 인쇄를 시작했음을 보여줍니다.

         2 이때 데이터 소스, 테스트 데이터는 한동안 Kafka에서 모든 데이터가 히트하는 것을 방지하기 위해 더 많은 포인트를 만들어야합니다.

5 단계 : Kafka에 데이터가 있으므로 3 단계에서 프로그램 실행 결과를 확인합니다. 스크린 샷은 다음과 같습니다.

설명 : 이것은 Kafka가 redis에서 데이터를 펀치하기 시작했음을 의미합니다.

6 단계 : redis 클라이언트에 로그인하고 데이터가 redis에 저장되어 있는지 확인합니다.

[root@hadoop ~]# redis-cli -p 12002
127.0.0.1:12002> select 1
OK
127.0.0.1:12002[1]> hgetall 20180824_310999015305
1) "2038"
2) "40_2"

说明: 结果的意思是,在20180824的20点38分,在卡口310999015305,共有2辆车通过,这2辆车的总速度是40

설명 : 1 프로그램에서 redis의 키 값 시간이 현재 날짜를 기준으로하기 때문에 테스트 데이터의 날짜 대신 20180824가 표시됩니다. 실제 생산에서 데이터의 날짜는 실시간으로 계산되기 때문에 현재 날짜와 매우 가깝습니다.

   

추천

출처blog.csdn.net/zhaoxiangchong/article/details/78379977