我有一个包含字符串(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用于其他事情,所以我也希望在这里获得火花的好处。所以我写了这段代码。
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。此代码已在具有128GB RAM的8核处理器上运行44分钟。
编辑:只是补充一点,正则表达式过滤器和文本文件的数量将在最终系统中倍增100倍。另外,不是从文本文件中写入/读取数据,而是使用SQL语句查询rdd中的数据。因此,我认为Spark是一个不错的选择。
答案 0 :(得分:2)
我也是一个非常重的用户,虽然Spark在本地设置中感觉不那么快,但您应该考虑其他一些事情:
即。在Hadoop集群中,可以并行处理RDD分区。这是您不会表现出来的地方。
Spark将处理Hadoop以尽力实现数据位置"这意味着您的进程直接针对本地硬盘运行,否则数据将在网络中复制,就像执行时一样类似于的进程。这些是阶段。了解阶段以及如何在执行程序中移动数据将带来很好的改进,而且考虑到 sort类型" reduce"它会在Spark上触发一个新的执行阶段,可能会在网络上移动数据。在正在执行地图的相同节点上拥有备用资源可以节省大量的网络开销。
否则它仍然可以很好地工作,你不能错误地销毁HDFS文件: - )
通过在自恢复执行环境中并行分散任务以对抗大量硬盘驱动器,您可以真正获得数据和执行的性能和安全性。
在本地设置中,您只是觉得它反应迟钝,主要是因为加载,启动和跟踪过程需要一些时间,但在跨多个节点处理多个GB时感觉快速而安全。
我也喜欢shell脚本,我经常处理合理的GB数量,但你不能正常匹配5 TB的数据,而不需要分配磁盘IO或支付RAM,就好像没有明天一样。