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)
相关推荐
isNotNullX6 小时前
一文解读OLAP的工具和应用软件
大数据·数据库·etl
不是笨小孩i8 小时前
Git常用指令
大数据·git·elasticsearch
howard20059 小时前
大数据概念与价值
大数据·特征·概念·价值
知识分享小能手9 小时前
mysql学习教程,从入门到精通,SQL DISTINCT 子句 (16)
大数据·开发语言·sql·学习·mysql·数据分析·数据库开发
紫钺-高山仰止9 小时前
【脑机接口】脑机接口性能的电压波形的尖峰分类和阈值比较
大数据·分类·数据挖掘
Alluxio10 小时前
选择Alluxio来解决AI模型训练场景数据访问的五大理由
大数据·人工智能·分布式·ai·语言模型
武子康10 小时前
大数据-133 - ClickHouse 基础概述 全面了解
java·大数据·分布式·clickhouse·flink·spark
shuxianshrng12 小时前
大气网格化精细化监管监测系统
大数据·服务器·windows·经验分享
aqymnkstkw12 小时前
2024年【电气试验】考试题库及电气试验模拟试题
大数据·c语言·人工智能·嵌入式硬件·安全
环能jvav大师12 小时前
基于R语言的统计分析基础:使用dplyr包进行数据操作
大数据·开发语言·数据分析·r语言