我有一个带字符串(textData)的文件和一组正则表达式过滤器(regx),我想应用并获取计数。在我们迁移到星火,我用GREP如下:Apache Spark:使用ReduceByKey的正则表达式比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()
我以为我很聪明,但代码实际上比较慢。任何人都可以指出任何明显的错误?我正在运行它作为 火花提交 - 本地[*] filename.py
我没有在同一确切的数据上运行两个版本,以确切地检查速度有多慢。如果需要,我可以轻松地做到这一点。当我检查本地主机:4040大部分时间正在由reduceByKey作业。
为了说明所花费的时间,文件中的行数是100,000,每行的平均#chars约为1000左右。过滤器的数量len(regx)= 20。这个代码已经在具有128GB RAM的8核处理器上运行了44分钟。
编辑:只需添加,正则表达式过滤器和文本文件的数量将在最终系统中乘以100倍。而不是写入/读取文本文件中的数据,我会用SQL语句查询rdd中的数据。因此,我认为Spark是一个不错的选择。
如果您发现'grep'比Spark慢得多,这将是一个有趣的问题。另一种方式,特别是在本地模式下,它甚至不是令人惊讶的。虽然你的代码可以通过相当多的方式得到改进,但是在非分布式设置中,grep是不现实的。 – zero323
您是否尝试过(增加)更改'textFile'中的'minPartitions'参数? –
@ zero323好吧,我目前正在开发环境,但将转向分布式设置。如果你能详细说明'在不同方面有所改进',那将会非常有用。我非常感激。 –