启动redis: ./redis-cli -h hadoop01
package utils
import org.apache.commons.pool2.impl.GenericObjectPoolConfig
import redis.clients.jedis.{Jedis, JedisPool}
/**
* 创建jedis连接池
*/
object Jpools {
private val poolConfig = new GenericObjectPoolConfig()
poolConfig.setMaxIdle(5)//最大的空闲连接数
poolConfig.setMaxTotal(2000)//支持最大的连接数
//连接池不需要对外提供访问
private lazy val jedisPool = new JedisPool(poolConfig,"hadoop01")
/**
* 对外提供一个可以从池子里面获取连接的方法
* @return
*/
def getJedis :Jedis={
val jedis = jedisPool.getResource
jedis.select(1)
jedis
}
}
package shujuku
import org.apache.spark.rdd.RDD
import org.apache.spark.streaming.dstream.ReceiverInputDStream
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext}
import utils.Jpools
/**
* 将实时统计的词频写入到redis里面
*/
object WordCountRedis {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[*]").setAppName("WordCountRedis")
//每2秒钟采样一次数据
//第二个参数是批次时间间隔,多长时间的数据集作为一个批次,这个时间不能随意设置,必须是科学合理的设置,只有这样才能稳定运行
val ssc = new StreamingContext(conf,Seconds(3))
//接收数据
val words: ReceiverInputDStream[String] = ssc.socketTextStream("hadoop01",1235)
words.foreachRDD(rdd=>{
//计算当前批次结果
val current_batch_result: RDD[(String, Int)] = rdd.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
//把计算好的当前批次结果写到redis
current_batch_result.foreachPartition(partition=>{
//每个分区从池子里获取一个连接对象
val jedis= Jpools.getJedis
partition.foreach(tp=>{
//redis的特性hincrby
jedis.hincrBy("wordcount",tp._1,tp._2)
})
//用完之后,记得文明
jedis.close()
})
})
ssc.start()
ssc.awaitTermination()
}
}