spark streaming实时流式处理wordcount,数据写出到redis

 Spark Streaming是spark的一个组件,可以对实时流式数据进行数据处理,数据的基本操作对象是DStream.DStream是一系列的RDDs。这个对象将流式的数据按时间切分为一系列的rdd的数据文件。然后就对数据进行处理。rdd=DStrema At Batch Time。

  思想:创建对象ssc,实时读取文件,处理,输出结果写出到redis(建立连接redis

可以设计到的优化:

* 写出数据时可以减少数据连接,foreanchPartition()* 批次对象时间的设置科学
* 对象的序列化设置为spark的方法
* redis连接池的懒加载使用
*
* linux的开启服务端接口:nc -lk 44444

1.代码实现:



import org.apache.log4j.{Level, Logger}
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{Seconds, StreamingContext}
import redis.clients.jedis.Jedis


object WC2Redis {

  //设置log的输出级别
  Logger.getLogger("org").setLevel(Level.WARN)

  def main(args: Array[String]): Unit = {

    val conf = new SparkConf()
      //在本地运行的时候是需要设置文件的运行的cores的数量的,一个是用来接收数据的,还有的其他的就是用来数据的处理的。
      .setMaster("local[2]")
      .setAppName("wc-streaming-redis")
      //需要指定RDD的序列化的方式,worker之间的数据传输序列化方式
      .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")

    val ssc: StreamingContext = new StreamingContext(conf, Seconds(2))

    //从端口实时获取数据,并封装到DStream中。
    val file: ReceiverInputDStream[String] = ssc.socketTextStream("192.168.33.102", 44444)

    val words: DStream[String] = file.flatMap(_.split(" "))
    val wordAndOne: DStream[(String, Int)] = words.map((_, 1))
    val wordCount: DStream[(String, Int)] = wordAndOne.reduceByKey(_ + _)


    //得到结果,这个结果可以进行输出显示,也可以进行输出到数据库中。
    //wordCount.print()

    //将结果写出到redis。
    wordCount.foreachRDD({
      rdd =>
        rdd.foreachPartition({
          it =>
            //建立redis的客户端连接
            val jedis: Jedis = OpRedis.getJedis()
            //然后将一个区里面的数据一条一条的写出
            it.foreach({
              wordCount =>
                //清楚结果类型
                jedis.incrBy(wordCount._1,wordCount._2)
            })
            jedis.close()
        })
    })


    //程序开始
    ssc.start()
    //程序被停止。
    ssc.awaitTermination()

  }
}
2.使用到jedis的工具类,创建连接池优化

import redis.clients.jedis.{Jedis, JedisPool}

object OpRedis {

  //在这里搞一个redis的连接池,可以是懒加载的,不用就不加载,可以是私有的,通过方法来得到我的连接对象
  private lazy val Jpool = new JedisPool("192.168.33.101",6379)

  def getJedis():Jedis ={Jpool.getResource}

}


3.当将结果写出到mysql时:

wordCount.foreachRDD({
      rdd =>
        rdd.foreachPartition({
          it => {
            val conn: Connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/bbs", "root", "123456")
            it.foreach({
              wc =>
                val pst = conn.prepareStatement("select * from t_wc where word = ?")
                pst.setString(1, wc._1)
                val rs = pst.executeQuery()
                var flag = true

                while (rs.next()) {
                  flag = false
                  val preCount = rs.getInt("counts")
                  val pst1 = conn.prepareStatement("update t_wc set counts = ? where word = ?")
                  pst1.setInt(1, wc._2 + preCount)
                  pst1.setString(2, wc._1)
                  pst1.executeUpdate()
                  pst1.close()
                }

                rs.close()
                pst.close()

                if (flag) {
                  val pst1 = conn.prepareStatement("insert into t_wc values(?,?)")
                  pst1.setString(1, wc._1)
                  pst1.setInt(2, wc._2)
                  pst1.execute()
                  pst1.close()
                }
            })
          }
        })

思想就是:创建ssc对象,处理数据,写出数据。




你可能感兴趣的:(spark,stremaing)