求助,求一个flink实时计算中以scala实现商品销售额汇总的demo。

fxqice 2020-09-06 01:39:10
数据格式:以脚本模拟生成的:{“price”:18,“id”:123},实时数据,求一个以scala编程实现的flink实时计算demo,实现结果:1、以id分组,每件商品价格累计;2、以id分组,上一分钟每件商品的销售额累计;3、销售总额。谢谢谢谢,万分感谢。求助无门了。初学者,弄了一个星期了。

要求flink能实现如下spark一样的计算结果:
object OrderConsumer {
//Redis配置
val dbIndex = 0
//每件商品总销售额
val orderTotalKey = "app::order::total"
//每件商品上一分钟销售额
val oneMinTotalKey = "app::order::product"
//总销售额
val totalKey = "app::order::all"


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

// 创建 StreamingContext 时间片为1秒
val conf = new SparkConf().setMaster("local").setAppName("UserClickCountStat")
val ssc = new StreamingContext(conf, Seconds(1))

// Kafka 配置
val topics = Set("order")
val brokers = "127.0.0.1:9092"
val kafkaParams = Map[String, String](
"metadata.broker.list" -> brokers,
"serializer.class" -> "kafka.serializer.StringEncoder")


// 创建一个 direct stream
val kafkaStream = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParams, topics)

//解析JSON
val events = kafkaStream.flatMap(line => Some(JSON.parseObject(line._2)))

// 按ID分组统计个数与价格总合
val orders = events.map(x => (x.getString("id"), x.getLong("price"))).groupByKey().map(x => (x._1, x._2.size, x._2.reduceLeft(_ + _)))

//输出
orders.foreachRDD(x =>
x.foreachPartition(partition =>
partition.foreach(x => {


println("id=" + x._1 + " count=" + x._2 + " price=" + x._3)

//保存到Redis中
val jedis = RedisClient.pool.getResource
jedis.select(dbIndex)
//每个商品销售额累加
jedis.hincrBy(orderTotalKey, x._1, x._3)
//上一分钟第每个商品销售额
jedis.hset(oneMinTotalKey, x._1.toString, x._3.toString)
//总销售额累加
jedis.incrBy(totalKey, x._3)
RedisClient.pool.returnResource(jedis)


})
))


ssc.start()
ssc.awaitTermination()
}

}

谢谢
...全文
49574 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
fxqice 2021-01-24
  • 打赏
  • 举报
回复 1
object ReadingFromKafka { //Redis配置 //val dbIndex = 0 //每件商品总销售额 val orderTotalKey = "app::order::total" //每件商品上一分钟销售额 //val oneMinTotalKey = "app::order::product" //总销售额 //val totalKey = "app::order::all" private val ZOOKEEPER_HOST = "192.168.10.111:2181,192.168.10.112:2181,192.168.10.113:2181,192.168.10.114:2181,192.168.10.115:2181" private val KAFKA_BROKER = "192.168.10.111:9092,192.168.10.112:9092,192.168.10.113:9092,192.168.10.114:9092,192.168.10.115:9092" private val TRANSACTION_GROUP = "com.KafkaRedis.flink" //自行定义一个封装类型 // 定义窗口聚合结果样例类,这里主要作用还是当成一个数据结构来使用,方便管理内部的数据 case class IdAndPrice (id:String, price:Double) def main(args : Array[String]){ val env = StreamExecutionEnvironment.getExecutionEnvironment env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime) env.enableCheckpointing(1000) env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE) // configure Kafka consumer val kafkaProps = new Properties() kafkaProps.setProperty("zookeeper.connect", ZOOKEEPER_HOST) kafkaProps.setProperty("bootstrap.servers", KAFKA_BROKER) kafkaProps.setProperty("group.id", TRANSACTION_GROUP) //因为kafka版本是0.9所以选FlinkKafkaConsumer09 val transaction = env .addSource( new FlinkKafkaConsumer09[String]("test1_topic", new SimpleStringSchema(), kafkaProps) ) /** FlinkKafkaConsumer09提供的API中第二个参数 new SimpleStringSchema() *是指反序列化Schema,指明如何将kafka中的序列化的数据转换为Flink中的对象。 *但是还是需要数据格式JSON字符串转换为JSON对象。 */ //.map(IdAndPrice =>JSON.parseObject(IdAndPrice)) //关联类 val mapStream: DataStream[IdAndPrice] = transaction.map(x => { val json = JSON.parse(x.toString).asInstanceOf[JSONObject] val price = json.get("price") val id = json.get("id") IdAndPrice(java.lang.Long.parseLong(price.toString),id.toString) }) // 用Id划出keyedStream,简单理解就是变成多个流 val keybyStream: KeyedStream[IdAndPrice, Tuple] = mapStream.keyBy("id") val reduceStream = keybyStream.reduce((sr1, sr2) => IdAndPrice(sr2.id, sr1.price + sr2.price)) //实例化Flink和Redis关联类FlinkJedisPoolConfig,设置Redis端口 val conf = new FlinkJedisPoolConfig.Builder().setHost("192.168.10.112").build() //实例化RedisSink,并通过flink的addSink的方式将flink计算的结果插入到redis val redisSink = new RedisSink[(String,String)](conf,new MyRedisMapper) reduceStream.addSink(redisSink) env.execute() } class MyRedisMapper extends RedisMapper[IdAndPrice] { //指定Redis key并将flink数据类型映射到Redis数据类型 /** * 设置使用的redis数据结构类型,和key的名字 * 通过RedisCommand设置数据结构类型 */ override def getCommandDescription: RedisCommandDescription = { new RedisCommandDescription(RedisCommand.HSET,"orderTotalKey") } //表示从接收的数据中获取需要操作的redis key override def getKeyFromData(data: IdAndPrice): String = data.id //表示从接收的数据中获取需要操作的redis value override def getValueFromData(data: IdAndPrice): String = data.price.toString } } } 自己补个回复。结贴
Li909919255 2021-12-15
  • 举报
回复
@fxqice 你好 我是初学者 能留个联系吗

1,258

社区成员

发帖
与我相关
我的任务
社区描述
Spark由Scala写成,是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用的并行计算框架,Spark基于MapReduce算法实现的分布式计算。
社区管理员
  • Spark
  • shiter
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧