Python实现用Hadoop的map/reduce对web日志进行统计

2019-03-28 13:05|来源: 网络

Python实现用Hadoop的map/reduce对web日志进行统计

日志格式

61.160.241.107 - - [23/Aug/2011:22:00:00 +0800] "GET /map.php?gid=38&sid=75&user=14717213&roleid=490711&time=1314108000&user_yx=736959&levafee11f0d1bacbfecbb631192 HTTP/1.1" 200 5 "-" "Java/1.6.0_23"

以对IP 的访问量进行统计为例

map脚本map.py 清洗日志数据

#!/usr/bin/python
import sys
import re
debug = False#设置lzo文件偏移位
if debug:
        lzo = 0
else:
        lzo = 1
for line in sys.stdin:
    ipaddress=re.compile(r'([\d.]*) (- - \[[^[\]]*\] "[^ ]* /)([^ ]*)([^ ]*\.php\?)([^ ]*)')
    match=ipaddress.match(line.split('\t',1)[lzo])
    if match:
        ip=match.group(1)
        #tb=match.group(2)
        #url=match.group(4)
        print ip

reduce脚本red.py 对ip数进行统计

#!/usr/bin/python
#-*-coding:UTF-8 -*-
import sys
import os
import string
res = {}
for line in sys.stdin:
    skey=line[0:-1]
    if(res.has_key(skey)==False):
        res[skey]=0
    res[skey]=res[skey]+1
for key in res.keys():
    print key+"\t"+str(res[key])

将map.py  red.py脚本修改为可执行权限
 
# chmod +x *.py
 
在shell中进行调试
 
# cat 1.log|/home/map.py|/home/red.py
 
在hadoop streaming中执行mapreduce作业
 
# hadoop jar /opt/mapr/hadoop/hadoop-0.20.2/contrib/streaming/hadoop-0.20.2-dev-streaming.jar -file /home/map.py -file /home/red.py  -mapper /home/map.py -reducer /homej/red.py -input /test/a.log.-output /test/test2
 
其中input 与output 路径都为hdfs文件系统路径  如果将输出文件进行压缩的话需要加参数 -jobconf mapred.output.compress=true -jobconf mapred.output.compression.codec=com.hadoop.compression.lzo.LzopCodec
 
如果输入文件格式为lzo压缩格式的话  需要指定参数-inputformat com.hadoop.mapred.DeprecatedLzoTextInputFormat  注意的是在hadoop中使用lzo的话,偏移位需要加1。

更多Hadoop相关信息见Hadoop 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=13

相关问答

更多
  • 找到离存数据最近的一台机器运行和这个数据相关的map任务,reduce是按照你整理出的key有多少个来决定的。一个机器很难说,处理的快的处理多一点,保持所有机器使用平衡。 上面你都自己写了20个map,和文件大小个数有关,和数据条数无关。 要看你选择的输入格式是什么,默认是行偏移量,然后由你编写map函数,指定key和value是什么。相同的key整合起来传给reduce,由reduce进行下一步处理,最后输出到指定的地方。
  • map的数量 map的数量通常是由hadoop集群的DFS块大小确定的,也就是输入文件的总块数,正常的map数量的并行规模大致是每一个Node是10~100个,对于CPU消耗较小的作业可以设置Map数量为300个左右,但是由于hadoop的每一个任务在初始化时需要一定的时间,因此比较合理的情况是每个map执行的时间至少超过1分钟。具体的数据分片是这样的,InputFormat在默认情况下会根据hadoop集群的DFS块大小进行分片,每一个分片会由一个map任务来进行处理,当然用户还是可以通过参数mapred ...
  • 你是否期望每个reducer能够在完全相同的映射数据上工作? 但至少“钥匙”应该是不同的,因为它决定了哪个减速器要去。 您可以在mapper中多次输出输出,并将其输出为密钥(其中$ i代表第i个缩减器,$ key是您的原始密钥)。 您需要添加一个“分区程序”以确保这些记录是基于$ i分布在还原器中的。 然后使用“GroupingComparator”按原始$ key对记录进行分组。 有可能做到这一点,但不是在一个MR中以微不足道的方式。 Are you expecting every reducer to ...
  • shanthanu,你的第一个问题是 问)哪种脚本语言对hadoop有用? A)大多数脚本语言,如php,python,perl,ruby bash都很好。 任何能够从stdin读取,写入sdtout和parse选项卡以及新行字符的语言都可以工作:Hadoop Streaming只是将键值对的字符串表示与一个选项卡连接到必须在每个任务跟踪器节点上可执行的任意程序。 在用于设置hadoop集群的大多数Linux发行版中,已经安装了python,bash,ruby,perl ......但是没有什么能阻止你为自 ...
  • hadoop-streaming的-file选项仅适用于本地文件。 但请注意,其帮助文本提到-file标志已被弃用,以支持generic -files选项。 使用generic -files选项允许我们指定一个远程(hdfs / gs)文件来进行舞台。 另请注意,通用选项必须位于应用程序特定标志之前。 您的调用将变为: hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar \ -files gs://bucket-name/intro_t ...
  • 这是除了最佳之外的一切,因为地图输出必须始终复制到另一台服务器。 但您可以简单地修改服务器上的mapred-site.xml。 mapred.tasktracker.map.tasks.maximum 4 The maximum number of map tasks that will be run simultaneously by a task tracker.
  • 您可能可以完成这项工作。 一种可能的方法是让每个hadoop节点运行一个嵌入式路由唯一弹性搜索节点。 这应该使查询更高效一些,因为节点会找出每个查询需要联系哪些节点,并利用有效的内部协议来执行此操作。 您可以通过添加更多es数据节点来进行水平缩放。 唯一的缺点是你的hadoop节点不会接近不同节点上的数据; 所以你有一点延迟通过网络。 但即使如此,你应该能够运行大量的看起来应该很便宜的查询这种方式。 由于它只有20GB,所以你的es节点很少需要去磁盘,并且可以在内存中执行所有操作,利用过滤器缓存等。 实际上 ...
  • 我通过以下方式在Eclipse中开发Cassandra / Hadoop应用程序: 使用maven(m2e)为我的Eclipse项目收集和配置依赖项(Hadoop,Cassandra,Pig等) 创建测试用例(src / test / java中的类)来测试我的映射器和缩减器。 诀窍是使用扩展RecordWriter和StatusReporter的内部类动态构建上下文对象。 如果执行此操作,则在调用setup / map / cleanup或setup / reduce / cleanup之后,您可以断言正 ...
  • 可能不是一个优雅的解决方案,但您可以创建两个模板,以便在作业完成后将reduce任务的输出转换为所需的格式。 通过编写一个shell脚本可以实现自动化,该脚本可以查找reduce输出并在其上应用模板。 使用shell脚本,转换按顺序进行,不会处理集群中的n台机器。 或者在reduce任务中,您可以将两种输出格式创建为具有一些分隔符的单个文件,然后使用分隔符将它们拆分。 在此方法中,由于转换发生在reduce中,因此转换将分布在集群中的所有节点上。 Might not be an elegant soluti ...
  • 您需要提供SequenceFileAsTextInputFormat作为hadoop流jar的输入inputformat 。 我从来没有使用过amazon aws mapreduce,但是在正常的hadoop安装上它会这样做: HADOOP=$HADOOP_HOME/bin/hadoop $HADOOP jar $HADOOP_HOME/contrib/streaming/hadoop-*-streaming.jar \ -input -output