编写高效的scala函数来匹配Spark

时间:2017-02-13 21:58:07

标签: scala apache-spark

我有2个hive表AB,其中包含有关某些用户的信息。表A是巨大的(数亿行),表B是常规大小,范围为100万行。我需要使用昵称匹配来匹配名字:AB

Table A

pid      fn         ln
001    Bill    Lattner
002    Tom     Jenkins
003    Dan     Forsyth
004    Mark    Simmons

Table B

uid      fnam     lnam
103   William  Lattner
105    Thomas  Jenkins
208    Daniel     Lark

我还有一个昵称对的文件nicknames.dat

Bill     William
Tom      Thomas
Dan      Daniel
Matt     Matthew

我试图找出如何编写一个高效的scala函数来执行在Spark中使用的昵称匹配任务。我有一些编写scala代码的经验。我不确定的是如何编写一个高效的scala函数来在Spark上运行。例如,我可以在scala中编写以下函数:

def nicknameMatching(fn1: String, fn2: String, pairs: Vector[(String, String)]): Boolean =
  pairs.contains((fn1, fn2)) || pairs.contains((fn2, fn1))

使用pairs构建nicknames.dat

我知道有一些技巧可以让程序在Spark上运行得更快,例如缓存,广播等。编写此函数(以及其他一些设置)的最佳方法是什么,以便它在实际集群中的Spark中运行效率最高?

1 个答案:

答案 0 :(得分:0)

我不完全确定你想要的输出是什么,但我的想法如下:

  • 内容nicknames.dat可能比A或B小得多,因此很容易适合记忆。
  • 如果是这样,迭代表B并查找相应的全名并不需要Spark,Spark的开销对于该操作来说是不值得的。
  • 你可能想要加入最后一步的结果(称之为B')到表A. B'拥有与B一样多的行(如果你只对昵称的人感兴趣,则会更少),所以你可以播放它并在每个工作人员上复制一份。

前两步的一小段代码:

case class Bentry(uid: Int, firstName: String, lastName: String)

val nicknames: Map[String, String] = (your nicknames, keys as first names, values last name)

val tableB: Seq[Bentry] = (table B's entries)

val bWithNicknames: Seq[(Bentry, String)] = tableB.map(nicknames.getOrElse(_.firstName, ""))

现在,将bWithNicknames转换为数据框bDF并假设您将A作为数据框aDF。然后(假设适当命名的列,并且您想要左连接):

val result = aDF.join(broadcast(bDF), Seq("firstName", "lastName), "left")