这些天我必须处理非常大的日志数据(压缩为7z后700GB),性能问题至关重要。考虑到我正在工作的环境(8-Cores),我正在考虑利用并行编程来实现更好的性能。 目前我使用的是内置的多处理库,性能得到了提升,但我想要更好。我听说有许多其他的python并行编程库,比如pp。
所以我的问题是这些模块之间的区别是什么?有没有比其他更好的?
答案 0 :(得分:3)
首先,只是几个问题:
我认为你应该研究一下这个数据量的MapReduce。
出于示例任务的目的,我将假设您拥有800GB的压缩广告服务器事件日志数据,并且您希望执行一些简单的操作,例如计算该数据集中唯一用户的数量。对于这一数量的数据和这种处理多处理将会有所帮助,但使用MapReduce可以更快地获得更多:我会查看EMR和MrJob或Dumbo。执行像用户计数这样的简单处理工作将有助于验证程序并帮助您从映射器和缩减器方面开始考虑问题。需要花费更多的时间来处理更复杂的任务,但我认为如果您将在任何实际的时间内处理这些数据量,那么投资将非常值得。
例如,对唯一用户进行计数将从一个mapper开始,该mapper简单地获取每行adserver数据并发出userID(cookieID,IP地址,我们可以用来区分用户)。您还将拥有一个reducer,它将这些用户ID作为输入,并删除或计算重复项。
当然,一旦你决定试一试,还有相当多的工作要做。准备数据(拆分大文件或将小文件分组为blob,以便您有效地分配工作,存储未压缩的数据或以EMR的Hadoop风格理解的压缩格式),调整hadoop变量以使用可用资源和算法,上传数据到s3等。
从好的方面来说,实际上你应该可以在几个小时内处理800GB的数据。
python中的一个简单的mapreduce示例:
这是日志文件格式:
AuctionID\tUserID\tSiteID\tURL\tUserAgent\tTimestamp
它只是一个简单的制表符分隔值(tsv)文件。
因此,我们将编写一个简单的映射器,从stdin中读取这样的行,并将UserIDs写入stdout。
import sys
def usercount_mapper(input):
for line in input:
line = line.strip()
parts = line.split("\t")
user_id = parts[1]
print "%s\t%s"%(user_id, 1)
if __name__=="__main__":
usercount_mapper(sys.stdin)
还原器的一个简单实现,用于统计唯一的userId:
import sys
user_ids = {}
def usercount_reducer(input):
for line in input:
line = line.strip()
user_id, count = line.split("\t")
try:
count = int(count)
except ValueError:
continue
current_count = user_ids.get(user_id, 0)
user_ids[user_id] = current_count + count
for user_id, count in user_ids.iteritems():
print "%s\t%s"%(user_id, count)
if __name__=="__main__":
usercount_reducer(sys.stdin)
您可以在一个数据块上运行此操作,只需执行以下操作即可在本地进行测试:
$ cat mydata.tsv | map.py | sort | reduce.py > result.tsv
mapreduce框架(如果使用EMR,则为hadoop)将负责运行多个map并减少任务,并在将数据传递给reducer之前对映射器中的数据进行排序。为了让reducers实际完成他们的工作,MR框架还将散列键值(映射器中的选项卡分隔输出中的第一个值(在本例中为UserID))并将具有相同散列的映射器分发到同一个reducer。这样,id为4的用户将始终转到reducer 1,id 5将转到reducer 2等。
如果你想自己构建一些东西,你可以直接看Disco(Disco是Python和Erlang,所以如果你对java过敏它可能是一个很好的选择:-))或Hadoop构建自己的mapreduce基础架构而不是使用EMR。在Hadoop / EMR世界中,还有一些很酷的数据处理平台,如Hive(用于描述数据和mapreduce算法的类似SQL的环境)或Pig(如类固醇上的grep和awk),可能是比上面的脚本更适合你。
例如,在Hive中表达了您的架构,您可以编写以下查询以获取唯一用户(假设您之前已定义了表用户):
SELECT DISTINCT users.user_id FROM users;
答案 1 :(得分:0)
你应该结帐Celery。
从他们的网站:
Celery是基于分布式消息传递的异步任务队列/作业队列。它专注于实时操作,但也支持调度。 执行单元(称为任务)使用多处理,Eventlet或gevent在单个或多个工作服务器上并发执行。任务可以异步(在后台)或同步执行(等到准备好)。
答案 2 :(得分:0)
您可能正在寻找的这些可能的解决方案
http://groups.google.com/group/comp.lang.python/browse_thread/thread/fe55f38c64f58a9d/
http://wiki.python.org/moin/ParallelProcessing
您可以在python中使用multiprocessing
模块
http://pypi.python.org/pypi/multiprocessing/
http://www.ibm.com/developerworks/aix/library/au-multiprocessing/
执行操作时,文件不会unzip
或extract
。Python
支持在不提取的情况下访问7z
个文件。