MapReduce的执行过程(以及其中排序)

Map阶段(MapTask): 切片(Split)-----读取数据(Read)-------交给Mapper处理(Map)------分区和排序(sort)

Reduce阶段(ReduceTask): 拷贝数据(copy)------排序(sort)-----合并(reduce)-----写出(write)

1、Map task读取:

框架调用InputFormat类的子类读取HDFS中文件数据,把文件转换为InputSplit。

默认,文件的一个block对应一个InputSplit,一个InputSplit对应一个map task。

一个InputSplit中的数据会被RecordReader解析成<k1,v1>。

默认,InputSplit中的一行解析成一个<k1,v1>。

默认,v1表示一行的内容,k1表示偏移量。

map:

框架调用mapper 类中的map方法,接收<k1,v1>输出<k2,v2>,有多少个<k1,v1>,就执行多少次map分区: 框架对mapp的输出进行分区,分区的目的是确定哪些<k2,v2>进入哪个reduce task。默认只有一个分区。

排序分组:框架对不同分区中的<k2,v2>进行排序分组.排序是按照k2进行排序。分组指的是相同k2的v2分到一个组中。分组不会减少<k2,v2>的数量。(快速排序)

combiner:可以在map task中对<k2,{v2}>执行reduce归约。

写入本地:框架对map的输出写入到Linux本地磁盘

2、reduce taskshuffle:

框架根据map不同分区中的数据,通过网络copy到不同的reduce节点合并

排序分组:每个reduce会把多个map传来的<k2,{v2}>进行合并排序分组(归并排序)

reduce:框架调用reduce<k2,v2s>,有多少个分组就回执行多少回reduce

写入HDFS:

框架对reduce输出的数据写入到hdfs中

快速排序:

个人理解:

就是归位,分区,递归

比如: 4,6,9,2,1,3,8 这个数组,要对它使用快速排序

首先,选第一个 4 对它进行归位 ,依次和4进行比较得到

左边: 2,1,3

右边:6,9,8

这样我们就的得到了 2,1,3,4 ,6,9,8

然后在对两边进行递归的操作。

python 实现

python 复制代码
def partition(li, left, right):
    tmp = li[left]
    # 当两边搜索并没有重合的时候就进行双向查找
    while left < right:
        # 这一级两个判断条件
        # 因为li[right] >= tmp退出说明在right出找到了小于tmp的值,这样填到left就行了
        # 因为left < right退出是因为left右侧的所有值都大于tmp,left已经和right重合了
        while left < right and li[right] >= tmp:  # left有空缺,需要right小于tmp的值来填补
            right = right - 1  # 往前一位接着找
        li[left] = li[right]  # 将右边的数写到左边空缺处
        # 找到之后,right出现空缺,应从left找比tmp大的数填到right
        while left < right and li[left] <= tmp:
            left = left + 1
        li[right] = li[left]

    # 当双向查找两边重合时侯,left=right,将值写入
    li[left] = tmp
    return li

li = [5, 7, 4, 6, 3, 1, 2, 9, 8]
result = partition(li, 0, len(li)-1)
print(result)

def quick_sort(li, left, right):
    if left < right:  # 至少两个元素
        mid = partition(li, left, right)
        # 拿到mid之后就能对两边的部分进行相同的整理
        quick_sort(li, left, mid-1)
        quick_sort(li, mid+1, right)

li = [5,7,4,6,3,1,2,9,8]
quick_sort(li, 0, len(li)-1)

归并排序:

是将数组按 left mid right 划分成两个部分,要求每个部分是有序的,然后假设有两个指针指在,两个部分的第一个位置,开始比较,较小的被放到一个临时集合中,指针移动到下一个位置,然后继续比较,直到一方没有下一个值 ,另一方剩下的就是最大的一部分直接放在临时集合最后,整个排序完成。

python 实现

python 复制代码
# 实现一次归并的过程
# 前提是已经拿到两个有序子的列表
def merge(li, low, mid, high):
    """
    :param li:列表
    :param low:第一段有序子列表起始位
    :param mid:第一段有序子列表终止位
    :param high:第二段有序子列表终止位
    :return:一次归并操作之后的整个列表
    """
    # i,j开始分别指向两个有序子序列的起始位
    i = low
    j = mid + 1
    ltmp = []  # 存储结果用
    while i<=mid and j<=high:  # 只要两个有序子序列都有数
        if li[i] < li[j]:
           ltmp.append(li[i])
           i = i + 1
        else:
            ltmp.append(li[j])
            j = j + 1
    # 两部分中有一部分拿光了
    while i <= mid:  # 说明后面的拿光了
        ltmp.append(li[i])
        i = i + 1
    while j <= high:  # 说明前面的拿光了
        ltmp.append(li[j])
        j = j + 1
    li[low:high+1] = ltmp  # 将结果写回去

li = [0,2,4,6,8,1,3,5,7,9]
merge(li, 0, 4, len(li)-1)
相关推荐
zskj_qcxjqr7 小时前
七彩喜艾灸机器人:当千年中医智慧遇上现代科技
大数据·人工智能·科技·机器人
洛克大航海10 小时前
Ubuntu安装Hbase
大数据·linux·数据库·ubuntu·hbase
GIOTTO情11 小时前
媒介宣发的技术革命:Infoseek如何用AI重构企业传播全链路
大数据·人工智能·重构
ApacheSeaTunnel12 小时前
新兴数据湖仓手册·从分层架构到数据湖仓架构(2025):数据仓库分层的概念与设计
大数据·数据仓库·开源·数据湖·dataops·白鲸开源·底层技术
落雪财神意12 小时前
股指10月想法
大数据·人工智能·金融·区块链·期股
柳贯一(逆流河版)12 小时前
ElasticSearch 实战:全文检索与数据聚合分析的完整指南
大数据·elasticsearch·全文检索
白鲸开源12 小时前
最佳实践:基于Apache SeaTunnel从MySQL同步到PostgreSQL
大数据·mysql·postgresql
QYResearch12 小时前
2025年全球移动变电站市场占有率及行业竞争格局分析报告
大数据
字节跳动数据平台12 小时前
为何底层数据湖决定了 AI Agent 的上限?
大数据
QYResearch12 小时前
自主机器人扫雪机行业现状与分析
大数据