例項講解hadoop中的map/reduce查詢(python語言實現
條件,假設你已經裝好了hadoop叢集,配好了hdfs並可以正常執行。
$hadoop dfs -ls /data/dw/explorer
Found 1 items
drwxrwxrwx - rsync supergroup 0 2011-11-30 01:06 /data/dw/explorer/20111129
$ hadoop dfs -ls /data/dw/explorer/20111129
Found 4 items
-rw-r--r-- 3 rsync supergroup 12294748 2011-11-29 21:10 /data/dw/explorer/20111129/explorer_20111129_19_part-00000.lzo
-rw-r--r-- 3 rsync supergroup 1520 2011-11-29 21:11 /data/dw/explorer/20111129/explorer_20111129_19_part-00000.lzo.index
-rw-r--r-- 3 rsync supergroup 12337366 2011-11-29 22:09 /data/dw/explorer/20111129/explorer_20111129_20_part-00000.lzo
-rw-r--r-- 3 rsync supergroup 1536 2011-11-29 22:10 /data/dw/explorer/20111129/explorer_20111129_20_part-00000.lzo.index
資料格式如下
20111129/23:59:54 111.161.25.184 182.132.25.243 <Log_Explorer ProductVer="5.05.1026.1111" UUID="{C9B80A9B-704E-B106-9134-1ED3581D0123}"><UserDoubleClick FileExt="mp3" AssociateKey="Audio.mp3" Count="1"/></Log_Explorer>
1.map指令碼取資料explorer_map.py
#!/usr/bin/python
#-*-coding:UTF-8 -*-
import sys
import cElementTree
debug = False#設定lzo檔案偏移位
if debug:
lzo = 0
else:
lzo = 1
for line in sys.stdin:
try:
flags = line[:-1].split('t')
#hadoop查詢走標準輸入,資料以t分隔,去掉每行中的n
if len(flags) == 0:
break
if len(flags) != 11+lzo:
#hadoop採用lzo則偏移位+1,lzo設定為False則+1
continue
stat_date=flags[0+lzo]#日期
stat_date_bar = stat_date[:4]+"-"+stat_date[4:6]+'-'+stat_date[6:8]#拼成2011-11-29格式
version = flags[4+lzo]
xmlstr = flags[10+lzo]
#xmlstr=line
dom = cElementTree.fromstring(xmlstr)
#xml欄位物件,以下均為取值操作
uuid = dom.attrib['UUID']
node = dom.find('UserDoubleClick')
associateKey=node.get('AssociateKey')
associateKeys=associateKey.split('.')
player = associateKeys[0]
fileext=node.get('FileExt')
count=node.get('Count')
print stat_date_bar+','+version+','+fileext+','+player+','+associateKey+'t'+count
#輸出map後的資料,這裡map不對資料做任何處理,只做取值,拼接操作
#將t前的字串作為key輸入reduce,t後的count作為reduce計算用的value
except Exception,e:
print e
#丟擲異常
2.reduce指令碼計算結果並輸出explorer_red.py
#!/usr/bin/python
#-*-coding:UTF-8 -*-
import sys
import cElementTree
import os
import string
res = {}
for line in sys.stdin:
try:
flags = line[:-1].split('t')
#拆分t以獲得map傳過來的key和value
if len(flags) != 2:
#t切割後,如果資料有問題,元素多於2或者少於2則認為資料不合法,跳出繼續下一行
continue
skey= flags[0]
#取出第一個元素作為key
count=int(flags[1])
#取出第二個元素作為value
if res.has_key(skey) == False:
res[skey]=0
res[skey] += count
#計算count總和
except Exception,e:
pass
#不丟擲,繼續執行
for key in res.keys():
print key+','+'%s' % res[key]
#格式化輸出,以放入臨時檔案
3.放入crontab執行的指令碼
#!/bin/sh
[ $1 ] && day=$1 DATE=`date -d "$1" +%Y%m%d`
[ $1 ] || day=`date -d "1 day ago" +%Y%m%d` DATE=`date -d "1 day ago" +%Y%m%d`
#取昨天日期
cd /opt/modules/hadoop/hadoop-0.20.203.0/
#進入hadoop工作目錄
bin/hadoop jar contrib/streaming/hadoop-streaming-0.20.203.0.jar -file /home/rsync/explorer/explorer_map.py -file /home/rsync/explorer/explorer_red.py -mapper /home/rsync/explorer/explorer_map.py -reducer /home/rsync/explorer/explorer_red.py -inputformat com.hadoop.mapred.DeprecatedLzoTextInputFormat -input /data/dw/explorer/$DATE -output /tmp/explorer_$DATE
#執行map/reduce,並將排序完結果放入hdfs:///tmp/explorer
bin/hadoop fs -copyToLocal /tmp/explorer_$DATE /tmp
#將m/r結果從hdfs://tmp/explorer_$DATE 儲存到本地/tmp下
bin/hadoop dfs -rmr /tmp/explorer_$DATE
#刪除hdfs下臨時資料夾
cd
#返回自身目錄
cd explorer
#進入explorer資料夾
./rm.py $DATE
執行入庫和刪除臨時資料夾指令碼
4.將/tmp生成的結果入庫並刪除臨時資料夾
#!/usr/bin/python
import os
import sys
import string
if len(sys.argv) == 2:
date = sys.argv[1:][0] #取指令碼引數
os.system ("mysql -h192.168.1.229 -ujobs -p223238 -P3306 bf5_data -e "load data local infile '/tmp/explorer_"+date+"/part-00000' into table explorer FIELDS TERMINATED
BY ',' (stat_date,ver,FileExt,player,AssociateKey,count)"")#執行入庫sql語句,並用load方式將資料載入到統計表中
os.system ("rm -rf /tmp/explorer_"+date)#刪除map/reduce過的資料
else:
print "Argv error"
#因為沒有安裝MySQLdb包,所以用執行指令碼的方式載入資料。
原始資料和最後完成的輸出資料對比,紅色為原資料,綠色為輸出資料
20111129/23:59:54 111.161.25.184 182.132.25.243 <Log_Explorer ProductVer="5.05.1026.1111" UUID="{C9B80A9B-704E-B106-9134-1ED3581D0123}"><UserDoubleClick FileExt="mp3" AssociateKey="Audio.mp3" Count="1"/></Log_Explorer>
-----------------------------------------------------------
2011-11-29,5.05.1026.1111,mp3,Audio,Audio.mp3,1
5.除錯技巧
因為這種方式比較抽象,所以你很難得到一個直觀的除錯過程。建議除錯如下
#將hadoop中的資料文字copy出來一個,lzo需要解壓縮,然後將map中的debug模式置為True,也就是不加hadoop中的lzo偏移量。
#用head輸入hadoop裡的檔案,透過管道操作放入map/reduce中執行,看輸出結果
$head explorer_20111129 | explorer_map.py | explorer_red.py
一天的資料大概幾十個G,以前用awk和perl指令碼跑需要至少半小時以上,改用map/reduce方式後,大概20幾秒跑完,效率還是提高了很多的。
©著作權歸作者所有:來自51CTO部落格作者Slaytanic的原創作品,謝絕轉載,否則將追究法律責任
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2508/viewspace-2820386/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python中的Map、Reduce和Filter函數語言程式設計PythonFilter函數程式設計
- Hadoop Map Reduce 漫談Hadoop
- Go語言map的底層實現Go
- 在幕後看看Swift中的Map,Filter和Reduce的實現SwiftFilter
- Python裝飾器例項講解(三)Python
- Java中的函數語言程式設計(七)流Stream的Map-Reduce操作Java函數程式設計
- OQL(物件查詢語言)在產品實現中造成的RCE(Object Injection)物件Object
- Python中的if、while、for 語法及例項PythonWhile
- python 連線mongodb實現增刪改查例項PythonMongoDB
- python-python的sao操作 map reduce filterPythonFilter
- Python 入門之經典函式例項之Map-Reduce - 對映與歸約的思想Python函式
- oracle 例項表查詢Oracle
- gorm 使用map實現in 條件查詢用法GoORM
- MySql中的資料查詢語言(DQL)三:連線查詢MySql
- C#中的虛方法(virtual)例項講解C#
- 自定義註解例項實現SQL語句生成SQL
- Hadoop - 實時查詢DrillHadoop
- python內建函式 map/reducePython函式
- python中快速處理關鍵字map,reduce,filterPythonFilter
- Python中compile函式的語法及例項!PythonCompile函式
- C語言實現雙連結串列的(終端)新增和查詢C語言
- python類例項化如何實現Python
- SQL語言(結構化查詢語言)SQL
- prometheus之查詢語言Prometheus
- Kibana查詢語言(KQL)
- NLP自然語言處理中的hanlp分詞例項自然語言處理HanLP分詞
- reduce實現filter,map 陣列扁平化等Filter陣列
- python實現查詢糾錯Python
- python 單一程式例項 實現Python
- python3+requests+unittest介面自動化例項講解Python
- 【Hadoop】按照map-reduce的思想試述完整的pagerank計算過程Hadoop
- MySQL — 資料查詢語言MySql
- vue例項+axios-天氣查詢VueiOS
- 快遞鳥查詢訂單例項單例
- 靈活的API查詢語言——GraphQLAPI
- Python學習筆記 - filter,map,reduce,zipPython筆記Filter
- python之高階函式map,reduce,filter用法Python函式Filter
- SQL觸發器例項講解SQL觸發器