python 運行分布式任務 mapreduce

來源:互聯網
上載者:User

前言

mapreduce在我的理解裡一直都是java等語言的專利,介於python乃至於pypy的效能局限, 一直沒想過用python寫分布式任務,最多就是多workers從訊息佇列取任務執行這樣,但是最近一件事真的顛覆 了我對python的認識.

先說說起因

某天分享sed和awk,領導突發奇想讓我用一些顧問的實際工作需要去我們的大量資料裡面擷取想要的資料的需求作為一些示範的例子.其中有這樣一個需求(我去掉實際一些專業晦澀的用語,用實際的內容來表達):

需求


1. 有大量的gz壓縮檔, 找到其中某2天的資料, 每一行都是一條實際資料
2. 需要解壓縮每個檔案,遍曆每行找到用逗號隔開的第21列為16233,第23列為27188的行. 以第2列為鍵計算符合的數量
3. 在全部統計結果裡面根據值計算符合的鍵的數量: 比如{'a':2, 'b':1, 'c':1},結果就是{1:2, 2:1},也就是2次的有2個,1次的只有一個

分析

一上來真的想用awk來搞.但是和其他同事一聊,有幾個痛點:

1. 2天資料總量在400G以上,用awk還要保留2次雜湊結果-不可能用awk
2. 用python,據同事經驗說:只是解壓縮這些小檔案後讀取什麼都不做也大概1天多的時間,完全不能忍
3. 資料還沒有放到hadoop, 沒有其他更好更快的方法

解題思路:

    最初我想做成這樣:
        把需要處理的這些壓縮檔放到隊列裡面
        啟動多進程出隊列裡面擷取要處理的檔案,執行,把符合的結果放到共用變數疊加
        計算完成後從共用變數裡面或者資料在產生上面第三條的結果

但是今天講的是python得mapreduce,也就是我後續的版本,它源於偉大的Doug Hellmann的Implementing MapReduce with multiprocessing

#!/usr/bin/env python
#coding=utf-8
# python mapreduce 跑數實現
# Author: Dongweiming
import gzip
import time
import os
import glob
import collections
import itertools
import operator
import multiprocessing


class AdMapReduce(object):

    def __init__(self, map_func, reduce_func, num_workers=None):
        '''
        num_workers: 不指定就是預設可用cpu的核心數
        map_func: map函數: 要求返回格式類似:[(a, 1), (b, 3)]
        reduce_func: reduce函數: 要求返回格式類似: (c, 10)
        '''
        self.map_func = map_func
        self.reduce_func = reduce_func
        self.pool = multiprocessing.Pool(num_workers)

    def partition(self, mapped_values):
        partitioned_data = collections.defaultdict(list)
        for key, value in mapped_values:
            partitioned_data[key].append(value)
        return partitioned_data.items()

    def __call__(self, inputs, chunksize=1):
        '''調用類的時候被觸發'''
        # 其實都是借用multiprocessing.Pool.map這個函數, inputs是一個需要處理的列表,想想map函數
        # chunksize表示每次給mapper的量, 這個根據需求調整效率
        map_responses = self.pool.map(self.map_func, inputs, chunksize=chunksize)
        # itertools.chain是把mapper的結果連結起來為一個可迭代的對象
        partitioned_data = self.partition(itertools.chain(*map_responses))
        # 大家想,上面的就是[(a, [1,2]), (b, [2,3]),列表中的數就是當時符合的次數,reduce就是吧列表符合項sum
        reduced_values = self.pool.map(self.reduce_func, partitioned_data)
        return reduced_values


def mapper_match(one_file):
    '''第一次的map函數,從每個檔案裡面擷取符合的條目'''
    output = []
    for line in gzip.open(one_file).readlines():
        l = line.rstrip().split(',')
        if int(l[20]) == 16309 and int(l[22]) == 2656:
            cookie = l[1]
            output.append((cookie, 1))
    return output


def reduce_match(item):
    '''第一次的reduce函數,給相同的key做統計'''
    cookie, occurances = item
    return (cookie, sum(occurances))


def mapper_count(item):
    '''第二次mapper函數,其實就是把某key的總數做鍵,但是值標1'''
    _, count = item
    return [(count, 1)]


def reduce_count(item):
    '''第二次reduce函數'''
    freq, occurances = item
    return (freq, sum(occurances))


if __name__ == '__main__':
    start = time.time()
    input_files = glob.glob('/datacenter/input/2013-12-1[01]/*')
    mapper = AdMapReduce(mapper_match, reduce_match)
    cookie_feq = mapper(input_files)
    mapper = AdMapReduce(mapper_count, reduce_count)
    cookie_feq = mapper(cookie_feq)
    cookie_feq.sort(key=operator.itemgetter(1))
    for freq, count in cookie_feq:
        print '{0}t{1}t{2}'.format(freq, count, freq*count)
    #cookie_feq.reverse()
    end = time.time()
    print 'cost:', end - start

後話

哇,看python做mapreduce也是可以這樣優雅的, 我是用pypy跑下來,竟然只有了61分鐘….

但是其實他只是藉助mapreduce思想和多核的硬體基礎,其實pool做的還是檔案層級的處理.假如是少量的大檔案,就未必有這樣好的效果了.

我想很多時候這樣的工作都可以交給這個Admapreduce類來做

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.