将单词计数的结果持久化到MySQL中

本文介绍如何使用 Spark Streaming 进行实时数据处理,并将处理后的数据持久化到 MySQL 数据库中。文章展示了如何创建连接池以提高数据库操作效率,并实现数据的实时更新与存储。

1.MySQL的连接池

package streaming.utils

import java.sql.{Connection, DriverManager}

object MysqlPool {
  private val max=8 ;//连接池的连接总数
  private val connectionNum=10;//每次产生的连接数
  private var conNum=0;//当前连接池已经产生的连接数
  
  import java.util
  private val pool=new util.LinkedList[Connection]();//连接池
  
  {
    
    Class.forName("com.mysql.jdbc.Driver")
  }
  /**
   * 释放连接
   */
  def releaseConn(conn:Connection):Unit={
    pool.push(conn);
  }
  /**
   * 获取连接
   */
  def getJdbcCoon():Connection={
    //同步代码块
    AnyRef.synchronized({
      if(pool.isEmpty()){
        for( i <- 1 to connectionNum){
          val conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/htt","root","root");
          pool.push(conn);
          conNum+1;
        }
      }
      
      pool.poll();
    })
    
  }
}

2.持久化到数据库

import org.apache.log4j.{Level, Logger}
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.ReceiverInputDStream
import org.apache.spark.streaming.{Seconds, StreamingContext}
import streaming.lesson01.utils.MysqlPool

/**
  * Created by Administrator on 2017/8/9.
  */
object WordCountByUpdateBykeyAndForeachRDD {
  def main(args: Array[String]): Unit = {
    /**
      * 这个地方设置的线程数至少是2,因为一个线程用来接收数据
      * 另外一个线程是用来处理数据的。
      * 如果你只写了一个线程,也不报错,只不过光是接收数据,不处理数据。
      */
    val conf = new SparkConf().setMaster("local[2]").setAppName("test")
    val ssc = new StreamingContext(conf,Seconds(1))
     //设置日志级别
    Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
    ssc.checkpoint("hdfs://hadoop1:9000/streaming")
    //通过监听一个端口得到一个DStream流    数据的输入
    val DStream: ReceiverInputDStream[String] = ssc.socketTextStream("hadoop1",9999)

    val wordOneDstream = DStream.flatMap(_.split(","))
      .map((_, 1))
    /**
      *   updateFunc: (Seq[V], Option[S]) => Option[S]
      *   scala功底:  k,v  k:String  每一个单词  v:int 出现的次数
      *   看样子是需要我们传进入两个参数,还要有返回值
      *   参数一:Seq[V]   hadoop,1 hadoop,1 haodop,1
      *               对应这个key在这个批次里面出现的次数
      *               1,1,1
      *   参数二:Option[S]
      *           代表的是这个key,上一次的中间状态  4
      *
      *   返回值:Option[S]
      *            把这个key最后的结果返回去
      *
      *            Option:
      *              Some
      *              None
      */
    val wordCountDStream = wordOneDstream.updateStateByKey((values: Seq[Int], state: Option[Int]) => {
      val currentCount = values.sum
      val lastCount = state.getOrElse(0)
      Some(currentCount + lastCount)
    })

   // wordCountDStream.print()

    wordCountDStream.foreachRDD( rdd =>{
      rdd.foreachPartition( partitionRecord =>{
         val coon = MysqlPool.getJdbcCoon()
        val statement = coon.createStatement()
        partitionRecord.foreach( record  =>{
          val sql=s"insert into wordcount values(now(),'${record._1}',${record._2})"
          statement.execute(sql)
        } )
        MysqlPool.releaseConn(coon)

      })
    })

    ssc.start()
    ssc.awaitTermination()
    ssc.stop()

  }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值