我有一个包含用户请求的URL的日志流。 每分钟我想在所有时间内请求前100页并将其保存到HDFS。
我了解如何为每个网址维护多个请求:
val ratingItemsStream : DStream[(String,Long)] = lines
.map(LogEntry(_))
.map(entry => (entry.url, 1L))
.reduceByKey(_ + _)
.updateStateByKey(updateRequestCount)
// this provides a DStream of Tuple of [Url, # of requests]
但接下来我该怎么办? 显然我需要将所有更新传递给主机以维持优先级,然后每1分钟取一个顶级K.
我怎样才能做到这一点?
UPD:我见过火花示例和algebird的MapMonoid。但由于我不明白它是如何工作的(令人惊讶的是没有在网上找到任何信息),我不想使用它。我必须有一些方法,对吗?
答案 0 :(得分:1)
您可以通过对数据进行x分钟窗口聚合并应用排序来获得排名来实现它。
val window = ratingItemStream.window(Seconds(windowSize), Seconds(windowSize))
window.forEachRDD{rdd =>
val byScore = rdd.map(_.swap).sortByKey(ascending=false).zipWithIndex
val top100 = byScore.collect{case ((score, url), index) if (index<100) => (url, score)}
top100.saveAsTextFile("./path/to/file/")
}
(示例代码,未经测试!)
请注意rdd.top(x)
会提供比排序/压缩更好的性能,但它返回一个数组,因此,您可以自己使用hadoop API将其保存到hdfs(这是一个选项) ,我认为)