描述:实时统计每天各地区各城市各广告的点击总流量,并将其存入 MySQL。
原方案:
1)单个批次内对数据进行按照天维度的聚合统计;
2)结合 MySQL 数据跟当前批次数据更新原有的数据。
新方案:
1)通过kafka获取黑名单过滤后的数据
2)按照时间、地市、城市聚合统计点击量
3)更新时间、地市、城市、点击量入库到mysql
CREATE TABLE area_city_ad_count (
time VARCHAR(30),
area VARCHAR(30),
city VARCHAR(30),
prov VARCHAR(30),
adid VARCHAR(50),
count BIGINT,
PRIMARY KEY (time,area,prov,city,adid)
);
ALTER DATABASE mysql CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE area_city_ad_count CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
//获取黑名单过滤后的日志信息
val filterClickData: InputDStream[ConsumerRecord[String, String]] =
dao.getKafkaData("clickTopic")
def dataDealMain(): Unit = {
val debugFlag=false
val clickLogData: DStream[ClickLog] = getKafkaData
if (debugFlag) {
println("kafka数据获取如下")
clickLogData.print()
}
//过滤黑名单用户,返回过滤后的日志
val filterBlack: DStream[ClickLog] = filterBlackUser(clickLogData).cache()
//过滤后数据传给城市点击统计模块
filterBlack.foreachRDD(
rdd=>{
rdd.foreachPartition(
(iter: Iterator[ClickLog]) => {
iter.foreach(
(data: ClickLog) =>{
dao.setDataToKafka("clickTopic",Array(data.time,data.userId,data.cityId,data.cityName,data.provName,data.advAddres))
}
)
})
}
)
//计算每日点击量,写入mysql,每天点击量超限,拉入黑名单
addUserClickInfo(filterBlack)
sscGet().start()
sscGet().awaitTermination()
}
//按照天的维度统计点击量
val reduceData: DStream[Array[Any]] = filterClickData.transform(
rdd => {
rdd.map((data: ConsumerRecord[String, String]) => {
data.value().split(",")
}).map((data: Array[String]) => {
/*
Array(data.time,data.userId,data.cityId,data.cityName,data.provName,data.advAddres)
=>((data.time,data.cityId,data.cityName,data.provName,data.advAddres),count)
* */
((data(0), data(2), data(3), data(4), data(5)), 1)
}).reduceByKey(_ + _).map(data =>{
Array(data._1._1,data._1._2,data._1._3,data._1._4,data._1._5,data._2,data._2)
})
}
)
reduceData.foreachRDD(rdd => {
rdd.foreachPartition(rddPartition => {
val mysqlConn = mysqlConnect()
rddPartition.foreach(
(data: Array[Any]) => {
//建立mysql链接
dao.executeOneData(mysqlConn, sql, data, true)
}
)
mysqlConn.close()
})
}
原因:忘了需要执行类似于行动算子的输出
Incorrect string value: '\xE6\xB7\xAE\xE5\x8C\x97'
原因:
你试图插入的字符串是'\xE6\xB7\xAE\xE5x8C\x97',这是一个UTF-8编码的中文字符串,对应的汉字是"你好"。然而,如果你的数据库表或列的字符集编码设置为不支持这种UTF-8编码的字符,那么当你尝试插入这个字符串时,就会出现“Incorrect string value”的错误。
解决这个问题的方法通常是更改你的数据库表或列的字符集编码,使其能够支持你想要插入的字符。例如,你可以将字符集编码更改为MySQL支持的utf8mb4,它支持更多的Unicode字符,包括一些特殊的中文字符。
解决办法:
ALTER DATABASE mysql CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE area_city_ad_count CONVERT TO CHARACTER SET utf8mb4 CO
SparkStreaming Data source rejected establishment of connection, message from server: Too many connections
原因:产生了太多了mysql连接,且都是sleep状态
SELECT COUNT(*) FROM information_schema.PROCESSLIST;--查看连接的数量
解决办法:
1、首先需要在代码中增加连接关闭
mysqlConn.close()
2、设置interactive_timeout和wait_timeout
超过时间的sleep连接会自动杀掉
set global interactive_timeout=10;
set global wait_timeout=10;
3、设置资源池来管理连接