【问题标题】:Apache Spark: Regex with ReduceByKey is lot slower than GREP commandApache Spark:使用 ReduceByKey 的正则表达式比 GREP 命令慢很多
【发布时间】:2016-10-23 07:19:34
【问题描述】:

我有一个包含字符串 (textData) 和一组正则表达式过滤器 (regx) 的文件,我想应用并获取计数。在我们迁移到 Spark 之前,我使用 GREP 如下:

from subprocess import check_output
result={}
for reg in regx: # regx is a list of all the filters
   result[reg] = system.exec('grep -e ' + reg + 'file.txt | wc -l') 

注意:我在这里解释为“system.exec”,实际上我使用的是 check_output。

我升级到 SPARK 是为了其他事情,所以我也想在这里利用 spark 的好处。所以我写了这段代码。

import re

sc = SparkContext('local[*]')
rdd = sc.textFile('file.txt') #containing the strings as before
result = rdd.flatMap(lambda line: [(reg, line) for reg in regx])
            .map(lambda line: (line[0], len(re.findall(line[0], line[1]))))
            .reduceByKey(lambda a,b: a+b)
            .collect()

我以为我很聪明,但代码实际上更慢。谁能指出任何明显的错误?我正在运行它 spark-submit --master local[*] filename.py

我没有在相同的确切数据上运行两个版本来检查到底慢了多少。如果需要,我可以轻松做到这一点。当我检查 localhost:4040 时,大部分时间都被 reduceByKey 作业占用。

为了说明所花费的时间,文件中的行数为 100,000,平均每行的 #chars 约为 1000 左右。过滤器的数量 len(regx)=20。这段代码在 8 核处理器上运行了 44 分钟,内存为 128GB。

编辑:只是添加,正则表达式过滤器和文本文件的数量将在最终系统中增加 100 倍。另外,我将使用 SQL 语句查询 rdd 中的数据,而不是从文本文件中写入/读取数据。因此,我认为 Spark 是一个不错的选择。

【问题讨论】:

  • 如果您观察到grep 比 Spark 慢得多,这将是一个有趣的问题。反过来,尤其是在本地模式下,这甚至不足为奇。虽然您的代码可以通过多种方式改进以期待类似的性能,但在非分布式设置中,grep 是不现实的。
  • 您是否尝试(增加)更改minPartitions 中的textFile 参数?
  • @zero323 好吧,我目前在开发环境中,但将转向分布式设置。如果您可以详细说明“以多种方式改进”,那将非常有帮助。非常感谢。
  • @EhsanM.Kermani 谢谢。我做到了,它根本没有帮助。也许是因为它没有按照零的建议分发。还有其他想法吗?
  • 行的平均大小是多少?线条是否独特?如果不是,那么预期的唯一行数是多少?

标签: regex performance apache-spark pyspark rdd


【解决方案1】:

我也是一个相当重度用户,虽然 Spark 在本地设置中感觉不那么快,但您应该考虑其他一些事情:

  • 您的数据集有多大?当需要大量 RAM 时,sort 会将记录交换到 /tmp。
  • 您为 Spark 应用程序分配了多少 RAM?默认情况下它只有 1GB,与没有 RAM 限制的排序命令相比,这在排序方面非常不公平。
  • 两个任务是否在同一台机器上执行? Spark 机器是在“自动扩展”磁盘文件中运行的虚拟设备吗? (表现不佳)。
  • Spark 集群会自动将您的任务分散到多台服务器上。如果在 Hadoop 上运行,请记住文件被分成 128MB 块,每个块可以是一个 RDD 分区。

即在 Hadoop 集群中,RDD 分区可以并行处理。这是您会注意到性能的地方。

Spark 将与 Hadoop 打交道以尽最大努力实现“数据本地化”,这意味着您的进程直接针对本地硬盘驱动器运行,否则数据将通过网络复制,就像执行 reduce-类似的过程。这些是阶段。了解阶段以及数据在执行器之间的移动方式将为​​您带来很好的改进,此外考虑到 sort 属于“reduce”类型,它会触发 Spark 上的新执行阶段,可能会在网络中移动数据。在执行地图的同一节点上拥有备用资源可以节省大量网络开销。

否则它仍然可以正常工作,并且您不能错误地破坏 HDFS 中的文件:-)

这是您真正获得数据和执行的性能和安全性的地方,方法是在自我恢复的执行环境中并行分配任务以处理大量硬盘驱动器。

在本地设置中,您只是觉得它反应迟钝,主要是因为加载、启动和回溯过程需要一些时间,但在处理多个节点上的大量 GB 时感觉快速且安全。

我也喜欢 shell 脚本,而且我经常处理合理数量的 GB,但是如果没有分配磁盘 IO 或支付 RAM 费用,就无法对 5 TB 的数据进行正则表达式匹配,就好像没有明天一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-12
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 2019-01-30
    相关资源
    最近更新 更多