面试题目:有5亿活跃用户,将其支付数据(uid 消费金额)投放到kafka。给你一台16核32g内存机器要求给出按支付金额的用户排名榜。这个题目有解法吗
代码不难,难得是要运行多久,代码如下:
对支付金额进行排序并给出用户排名榜,使用分布式计算框架,Apache Spark。以下是代码:
from pyspark import SparkContext
# 创建SparkContext对象
sc = SparkContext("local", "payment ranking")
# 读取支付数据
data = sc.textFile("path/to/payment/data")
# 将数据转化为RDD
rdd = data.map(lambda line: (line.split(",")[0], float(line.split(",")[1])))
# 根据支付金额进行排序
rdd_sorted = rdd.sortBy(lambda x: x[1])
# 取出支付金额所有的用户ID
top_users = rdd_sorted.take(500000000)
# 输出排名榜
for user_id, amount in top_users:
print("Rank {}: {} USD".format(amount, user_id))
在这个示例代码中,我们使用SparkContext对象创建一个本地的Spark应用程序,并使用textFile()方法从文件中读取支付数据。然后,我们使用map()方法将每一行数据转化为一个元组,其中第一个元素是用户ID,第二个元素是支付金额。接着,我们使用sortBy()方法对RDD按照支付金额进行排序,并将结果保存在rdd_sorted变量中。最后,我们使用take()方法取出支付金额所有用户ID,并使用for循环输出排名榜。
这个可以考虑用基数排序+外部排序,虽然有5亿用户,但是支付金额大多数都集中在比如0-10000这个范围内,所以完全可以将用户按照1元为单位存入这些区间对应的数据里,然后再组内排序
不知道你这个问题是否已经解决, 如果还没有解决的话:
使用消息队列的好处
1)解耦
允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
2)可恢复性
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所
以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
3)缓冲
有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致
的情况。
4)灵活性 & 峰值处理能力
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。
如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列
能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
5)异步通信
很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户
把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要
的时候再去处理它们。