Spark Scala-批量并行处理不同的子数据帧

时间:2019-05-29 21:22:30

标签: scala apache-spark parallel-processing apache-spark-sql outliers

我正在从事一个欺诈性交易检测项目,该项目利用了星火,主要使用基于规则的方法对传入交易进行风险评分。对于这种基于规则的方法,将从历史数据中创建几个地图以表示交易中的各种模式,然后在为交易评分时使用这些模式。由于数据大小的快速增长,我们现在正在修改代码以在每个帐户级别生成这些地图。

以前的代码用于

createProfile(clientdata)

但现在变成了

accountList.map(account=>createProfile(clientData.filter(s"""account=${account}""")))

使用这种方法可以生成配置文件,但是由于此操作是顺序进行的,因此似乎不可行。

此外,createProfile函数本身正在利用数据帧,sparkContext / SparkSessions,因此,这导致无法将这些任务发送到工作节点的问题,因为根据我的理解,只有驱动程序才能访问数据帧和sparkSession / sparkContext。因此,以下代码不起作用

import sparkSession.implicit._ val accountListRdd=accountList.toSeq.toDF("accountNumber") accountList.rdd.map(accountrow=>createProfile(clientData.filter(s"""account=${accountrow.get(0).toString}""")))

上面的代码不起作用,但是代表了所需输出行为的逻辑。

我正在研究的另一种方法是使用scala Future在驱动程序级别使用多线程。但是即使在这种情况下,在单个createProfile函数调用中也会创建许多jvm对象,因此通过增加线程,甚至如果这种方法可行,则可能导致大量jvm对象,而这些对象本身可能导致垃圾回收和内存开销问题。

仅从时间角度来看,单个帐户的createProfile平均需要大约10分钟,而我们有3000个帐户,因此顺序需要花费很多天。使用多线程,即使我们达到10的倍数,也将需要很多天。因此,我们需要100s左右的并行度。

如果存在的话,可能有用的一件事是.let让我们说,如果在groupBY类型的操作中存在诸如spark groupBy之类的东西,那么在第一层,我们可以按“帐户”进行分组,然后执行其他操作 (当前的问题是UDF无法处理我们要执行的操作)

另一种可行的解决方案是SPark Streaming的工作方式- 它具有forEachRDD方法和spark.streaming.concurrentjobs参数,该参数允许并行处理多个RDD。我不确定它是如何工作的,但是也许这种实现可能会有所帮助。

上面是问题描述和我对它的当前看法。

请让我知道是否有人对此有任何想法!而且,我宁愿进行逻辑更改,也不愿提出其他技术建议

0 个答案:

没有答案