mapreduce 订阅
MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。概念"Map(映射)"和"Reduce(归约)",是它们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。 当前的软件实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(归约)函数,用来保证所有映射的键值对中的每一个共享相同的键组。 展开全文
MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。概念"Map(映射)"和"Reduce(归约)",是它们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。 当前的软件实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(归约)函数,用来保证所有映射的键值对中的每一个共享相同的键组。
信息
思想来源
Google的几篇论文
本    质
一种编程模型
特    点
分布可靠
用    途
大规模数据集的并行运算
应    用
大规模的算法图形处理、文字处理
外文名
MapReduce
MapReduce定义
MapReduce是面向大数据并行处理的计算模型、框架和平台,它隐含了以下三层含义:1)MapReduce是一个基于集群的高性能并行计算平台(Cluster Infrastructure)。它允许用市场上普通的商用服务器构成一个包含数十、数百至数千个节点的分布和并行计算集群。2)MapReduce是一个并行计算与运行软件框架(Software Framework)。它提供了一个庞大但设计精良的并行计算软件框架,能自动完成计算任务的并行化处理,自动划分计算数据和计算任务,在集群节点上自动分配和执行任务以及收集计算结果,将数据分布存储、数据通信、容错处理等并行计算涉及到的很多系统底层的复杂细节交由系统负责处理,大大减少了软件开发人员的负担。3)MapReduce是一个并行程序设计模型与方法(Programming Model & Methodology)。它借助于函数式程序设计语言Lisp的设计思想,提供了一种简便的并行程序设计方法,用Map和Reduce两个函数编程实现基本的并行计算任务,提供了抽象的操作和并行编程接口,以简单方便地完成大规模数据的编程和计算处理 [1]  。
收起全文
精华内容
参与话题
问答
  • MapReduce

    万次阅读 2018-01-10 14:59:12
    当数据量大到一定程度,传统的技术无法进行解决的时候,那么需要采用分布式计算引擎MapReduce来尝试解决了! 操作步骤 1. 架构图 Hadoop是由Apache基金会所开发的分布式系统基础架构,组织...

    应用场景

    当数据量大到一定程度,传统的技术无法进行解决的时候,那么需要采用分布式计算引擎MapReduce来尝试解决了!

    操作步骤

    1. 架构图

    Hadoop是由Apache基金会所开发的分布式系统基础架构,组织架构如下图所示:

    这里写图片描述

    正如上图所示:Hadoop包含很多优秀的子项目,例如HDFS,Mapreduce,Hbase,Hive,Zookeeper等,其中最重要的,也是Hadoop当时风靡一时的原因是HDFS(分布式文件系统)和Mapreduce(分布式计算框架)。HDFS解释了,hadoop如何解决大数据的存储问题,而Mapreduce解释了,hadoop如何对大数据的计算问题。

    2. MapReduce

    把大量的数据放到了HDFS上,接下去如何对大数据进行分析,需要Hadoop的另一个核心技术,MapReduce。
    Mapreduce是一种编程模型,是一种编程方法,抽象理论。MapReduce相当的抽象,还是用通俗的话来说比较好。比如,现在要做一份洋葱辣椒酱,当然取一个洋葱,把它切碎,然后拌入盐和水,最后放进混合研磨机里研磨。这样就能得到洋葱辣椒酱了。那现在要用薄荷、洋葱、番茄、辣椒、大蒜弄一瓶混合辣椒酱,我们会取薄荷叶一撮,洋葱一个,番茄一个,辣椒一根,大蒜一根,切碎后加入适量的盐和水,再放入混合研磨机里研磨,这样就可以得到一瓶混合辣椒酱了。
    这其实和MapReduce是一个道理,Map和Reduce其实是两种操作,Map(映射): 把洋葱、番茄、辣椒和大蒜切碎,是各自作用在这些物体上的一个Map操作。所以你给Map一个洋葱,Map就会把洋葱切碎。
    同样的,你把辣椒,大蒜和番茄一一地拿给Map,你也会得到各种碎块。 所以,当你在切像洋葱这样的蔬菜时,你执行就是一个Map操作。
    Map操作适用于每一种蔬菜,它会相应地生产出一种或多种碎块,在我们的例子中生产的是蔬菜块。在Map操作中可能会出现有个洋葱坏掉了的情况,你只要把坏洋葱丢了就行了。所以,如果出现坏洋葱了,Map操作就会过滤掉坏洋葱而不会生产出任何的坏洋葱块。Reduce(化简):在这一阶段,你将各种蔬菜碎都放入研磨机里进行研磨,你就可以得到一瓶辣椒酱了。这意味要制成一瓶辣椒酱,你得研磨所有的原料。因此,研磨机通常将map操作的蔬菜碎聚集在了一起。
    mapreduce操作过程如下图所示:

    这里写图片描述

    一切都是从最上方的user program开始的,user program链接了MapReduce库,实现了最基本的Map函数和Reduce函数。图中执行的顺序都用数字标记了。
    1.MapReduce库先把user program的输入文件划分为M份(M为用户定义),每一份通常有16MB到64MB,如图左方所示分成了split0~4;然后使用fork将用户进程拷贝到集群内其它机器上。
    2.user program的副本中有一个称为master,其余称为worker,master是负责调度的,为空闲worker分配作业(Map作业或者Reduce作业),worker的数量也是可以由用户指定的。
    3.被分配了Map作业的worker,开始读取对应分片的输入数据,Map作业数量是由M决定的,和split一一对应;Map作业从输入数据中抽取出键值对,每一个键值对都作为参数传递给map函数,map函数产生的中间键值对被缓存在内存中。
    4.缓存的中间键值对会被定期写入本地磁盘,而且被分为R个区,R的大小是由用户定义的,将来每个区会对应一个Reduce作业;这些中间键值对的位置会被通报给master,master负责将信息转发给Reduce worker。
    5.master通知分配了Reduce作业的worker它负责的分区在什么位置(肯定不止一个地方,每个Map作业产生的中间键值对都可能映射到所有R个不同分区),当Reduce worker把所有它负责的中间键值对都读过来后,先对它们进行排序,使得相同键的键值对聚集在一起。因为不同的键可能会映射到同一个分区也就是同一个Reduce作业(谁让分区少呢),所以排序是必须的。
    6.reduce worker遍历排序后的中间键值对,对于每个唯一的键,都将键与关联的值传递给reduce函数,reduce函数产生的输出会添加到这个分区的输出文件中。
    7.当所有的Map和Reduce作业都完成了,master唤醒正版的user program,MapReduce函数调用返回user program的代码。
    有人问:金庸的天龙八部小说里谁出现的次数最多?很多人说是乔峰,是错误的,其实这是一个用mapreduce的很好的例子,先把小说揉碎,揉成一个一个的词组,将人名词组定义为map中的key,value即为出现的次数,然后通过reduce进行归一,统计出现次数最多的人物,统计结果是段誉。结果前十位分别如下:

    这里写图片描述

    展开全文
  • mapreduce

    千次阅读 2016-07-05 08:48:38
    Hadoop mapreduce对外提供了5个可编程组件,分别是InputFormat,Mapper,Partitioner,Reducer,OutputFormat mapreduce能解决的问题有一个共同特点:任务可被分解成多个子问题,且这些子问题相对独立,彼此不会...
    Hadoop mapreduce对外提供了5个可编程组件,分别是InputFormat,Mapper,Partitioner,Reducer,OutputFormat
    mapreduce能解决的问题有一个共同特点:任务可被分解成多个子问题,且这些子问题相对独立,彼此不会相互牵制。
    分治的思想。
    task分为maptask和reducetask。hdfs以固定大小的block为基本的存储单元,而对于mapreduce而言,其处理单位是split,
    split是逻辑概念,它包含一些元数据信息,比如数据的起始位置,数据长度,数据所在节点等。它的划分由用户自己决定,
    split的多少决定了maptask的数目,因为每个split会交给一个maptask处理。


    maptask执行过程(map,buffer,split,sort(partition,key),combiner):先将对应的split迭代解析成一个个key/value对,依次
    调用map()函数进行处理,Map的输出是由collector控制的,输出的数据首先被写进
    环形内存缓冲区,这个缓冲区默认大小是100M,可以通过io.sort.mb属性来设置具体的大小,当缓冲区中的数据量达到一个特定
    的阀值(io.sort.mb * io.sort.spill.percent,其中io.sort.spill.percent 默认是0.80)时,系统将会启动一个后台线程把
    缓冲区中的内容spill 到磁盘(Map输出总是写到本地磁盘)。在spill过程中,Map的输出将会继续写入到缓冲区,但如果缓冲区已经满了,Map就会被阻塞
    直到spill完成。spill线程在把缓冲区的数据写到磁盘前,会对他进行一个二次排序,首先根据数据所属的partition排序,
    然后每个partition中再按Key排序。输出包括一个索引文件和数据文件,如果设定了Combiner,将在排序输出的基础上进行。
    Combiner就是一个Mini Reducer,它在执行Map任务的节点本身运行,先对Map的输出作一次简单的Reduce,使得Map的输出更紧凑,
    更少的数据会被写入磁盘和传送到Reducer。Spill文件保存在由mapred.local.dir指定的目录中,Map任务结束后删除。
    每当内存中的数据达到spill阀值的时候,都会产生一个新的spill文件,所以在Map任务写完他的最后一个输出记录的时候,可能
    会有多个spill文件,在Map任务完成前,所有的spill文件将会被归并排序为一个索引文件和数据文件。这是一个多路归并过程,
    最大归并路数由io.sort.factor 控制(默认是10)。


    reduce执行过程(复制map输出,排序合并,读取<key,value list>进行reduce处理):
    Reduce任务的输入数据分布在集群内的多个Map任务的输出中,只要有其中一个Map任务完成,
    Reduce任务就开始拷贝他的输出。这个阶段称为复制阶段,Reduce任务拥有多个拷贝线程,可以并行的获取Map输出。可以通过
    设定mapred.reduce.parallel.copies来改变线程数。
    如果reduce端接受的数据量相当小,则直接存储在ReduceTask内存中
    (缓冲区大小由mapred.job.shuffle.input.buffer.percent属性控制,表示用作此用途的堆空间的百分比),
    如果数据量超过了该缓冲区大小的一定比例(由mapred.job.shuffle.merge.percent决定),则对数据合并后溢写到磁盘中
    或者达到了Map输出的阀值的大小(由mapred.inmem.merge.threshold控制),
    在reduce复制map输出的同时,reduce任务就进入了合并排序阶段
    缓冲区中的数据将会被归并然后spill到磁盘。拷贝来的数据叠加在磁盘上,有一个后台线程会将它们归并为更大的排序文件,
    这样做节省了后期归并的时间。对于经过压缩的Map 输出,系统会自动把它们解压到内存方便对其执行归并。
    当所有的Map 输出都被拷贝后,Reduce 任务进入排序阶段(更恰当的说应该是归并阶段,因为排序在Map 端就已经完成),
    这个阶段会对所有的Map 输出进行归并排序,这个工作会重复多次才能完成。
    JVM重用


    •启动JVM是一个比较耗时的工作,所以在MapReduce中有JVM重用的机制。
    •条件是统一个作业的任务。
    •可以通过mapred.job.reuse.jvm.num.tasks定义重用次数,如果属性是-1那么为无限制。




    第三章 Mapreduce编程模型
    3.1.1 mapreduce编程接口体系结构
    mapreduce编程模型位于应用程序层和mapreduce执行器之间,可分两层,第一层是最基本的Java API,主要有五个可编程组件
    InputFormat,Mapper,Partitioner,Reducer,OutputFormat。Hadoop自带了很多可以直接使用的InputFormat,Partitioner,OutputFormat
    第二层是工具层,四个工具包JobControl(编写有依赖关系的作业),ChainMapper/ChainReducer(编写链式作业),Hadoop Streaming(脚本),Hadoop Pipes(c/c++编程)
    3.1.2 新旧API对比
    旧版api在org.apache.hadoop.mapred包中,新版在org.apache.hadoop.mapreduce包及子包中
    接口变抽象类,抽象类具有良好的向后兼容性,当需要为抽象类添加新方法时,只要新添加的方法提供了默认实现,用户之前的代码不必修改,
    编程组件变抽象类。
    3.2.1 序列化
    序列化的两个作用:永久存储和进程间通信
    Hadoop mapreduce中使对象可序列化的方法是让其对应的类实现Writable接口,对于key需要比较排序,key要实现WritableComparable接口
    3.2.3 回调机制
    mapreduce对外提供的5个组件,全部属于回调接口。当用户按照约定实现这几个接口后,mapreduce运行时环境会自动调用他们。
    3.3.1 Hadoop配置文件和作业配置
    后添加的属性取值覆盖掉前面所添加资源中的属性,被final修饰的属性不能被后面定义的属性覆盖
    Hadoop默认先加载core-default.xml,hdfs-default.xml和mapred-default.xml,然后加载管理员自定义配置文件core-site.xml,
    hdfs-site.xml和mapred-site.xml
    3.3.2 InputFormat的设计和实现
    InputFormat主要描述输入数据的格式,它提供以下两个功能:数据切分,将输入数据切分为若干个split,以便确定map task数量;
    为Mapper提供输入数据,将给定的split解析成一个个key value对
    新版API中InputFormat是抽象类,包含两种方法
    public abstract List<InputSplit> getSplits(JobContext context) throws IOException, InterruptedException;
    public abstract RecordReader<K,V> createRecordReader(InputSplit split, TaskAttemptContext context) throws IOException,InterruptedException;
    getSplits()方法在逻辑上对输入数据分片,InputSplit只记录了分片的元数据信息,比如起始位置,长度及所在的节点列表
    createRecordReader()方法返回RecordReader对象,该对象可将输入的InputSplit解析成key/value对。map执行过程中会不断调用
    RecordReader对象中的方法,迭代获取key/value对交给map函数处理
    整个基于文件的InputFormat体系的设计思路是由公共基类FileInputFormat采用统一的方法对各种输入文件进行切分。而由各个派生
    InputFormat自己提供机制将进一步解析InputSplit,具体的实现是基类FileInputFormat提供getSplit实现,派生类提供createRecordReader实现
    系统自带的各种InputFormat实现。他们都集成自InputFormat,基于数据库的InputFormat实现DBInputFormat,基于文件的InputFormat
    实现基类FileInputFormat,并由此派生出TextInputFormat和,KeyValueTextInputFormat,NLInputFormat。针对二进制格式的SequenceFileInputFormat等
    FileInputFormat基类的实现,它的重要功能是为各种InputFormat提供统一的getSplit函数,该函数最核心的两个算法是文件切分算法
    和host选择算法。
    (1)文件切分算法
    旧API:
    splitSize=max{minSize,min{goalSize,blockSize}}
    minSize,InputSplit的最小值,由配置参数mapred.min.split.size确定,默认是1
    goalSize,根据totalSize/numSplits,其中totalSize为文件总大小,numSplits为用户设定的Map Task个数,默认是1
    blockSize,文件在hdfs中块的大小,默认64M
    新API:
    splitSize=max(minSize, min(maxSize, blockSize));
    -----------------
    blockSize = file.getBlockSize();
    -----------------
    minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job));
    getFormatMinSplitSize() return 1;
    getMinSplitSize(JobContext job) return job.getConfiguration().getLong(SPLIT_MINSIZE, 1L);
    SPLIT_MINSIZE = "mapreduce.input.fileinputformat.split.minsize";
    -----------------
    maxSize = getMaxSplitSize(job);
    getMaxSplitSize(JobContext context) return context.getConfiguration().getLong(SPLIT_MAXSIZE,Long.MAX_VALUE);
    SPLIT_MAXSIZE = "mapreduce.input.fileinputformat.split.maxsize";


    一旦确定splitSize值后,FileInputFormat将文件依次切分成splitSize的InputSplit,最后剩余不足的splitSize的数据块单独成为
    一个InputSplit。
    (2) host选择算法
    待InputSplit切分方案确定后,下一步要确定每个InputSplit的元数据信息。这通常由四部分组成:<file,start,length,hosts>,分别表示
    InputSplit所在的文件、起始位置,长度,以及所在的host(节点)列表。在进行任务调度时,优先让空闲资源处理本节点的数据,
    如果节点上没有可处理的数据,则处理同一机架上的数据,最差的情况是处理其他机架上的数据。
    虽然InputSplit对应的block可能位于多个节点上,但考虑任务调度的效率,通常不会把所有节点加到InputSplit的host列表中,而是选择包含(InputSplit)
    数据总量最大的前几个节点(Hadoop限制最多选择10个,多余的会过滤掉),以作为人物调度时判断任务是否具有本地性的主要凭证。为此
    FileInputFormat设计了一个简单有效的启发式算法:首先按照rack包含的数据量对rack进行排序,然后在rack内部按照每个node包含的数据量对node排序。
    最后取前N个node的host作为InputSplit的host列表,这里的N为block副本数。
    host选择算法可知,当InputSplit尺寸大于block尺寸时,map Task并不能实现完全数据本地性,所以当使用基于FileInputFormat时,为提高map task的数据
    本地性,尽量使用InputSplit与block大小相同。
    派生类实现getRecordReader函数,该函数返回一个RecordReader对象,它实现了类似迭代器的功能,将某个InputSplit解析成
    一个个key/value对,在具体实现时RecordReader应考虑以下两点:定位记录边界,为了能够识别一条完整的记录,记录之间应该添加一些同步标识,
    对于TextInputFormat,每两条记录之间存在换行符。另外,FileInputFormat对文件的切分是严格按照偏移量来的,因而InputSplit的第一条记录和最后一条记录
    可能会被从中间分开,为了解决这种记录跨InputSplit的读取问题,RecordReader规定每个InputSplit的第一条不完整记录划给前一个InputSplit处理。
    TextInputFormat关联的是LineRecordReader,对于跨InputSplit的行,LineRecordReader会自动跨InputSplit去读取。
    以行记录形式的文本,还真可能存在一行记录被划分到不同的Block,甚至不同的DataNode上去。通过分析FileInputFormat里面的getSplits方法,可以得出,某一行记录同样也可能被划分到不同的InputSplit。
    第二点解析key/value,对于TextInputFormat,每一行的内容即为value,而该行在整个文件中的偏移量为key
    几个简单的结论:
    1. 一个split不会包含零点几或者几点几个Block,一定是包含大于等于1个整数个Block
    2. 一个split不会包含两个File的Block,不会跨越File边界
    3. split和Block的关系是一对多的关系
    4. maptasks的个数最终决定于splits的长度


    文件输入
    •实现类:FileInputFormat
    •通过文件作为输入源的基类。
    •四个方法:
    •addInputPath()
    •addInputPaths()
    •setInputPath()
    •setInputPaths()
    •FileInputFormat会按HDFS块的大小来分割文件
    •避免分割
    •继承FileInputFormat 重载isSplitable()
    •return false
    •实现类:TextInputFormat
    •TextInputFormat 是默认的输入格式。
    •包括:
    •KeyValueTextInputFormat
    •NLineInputFormat
    •XML
    •输入分片与HDFS块之间的关系
    •TextInputFormat的某一条记录可能跨块存在


    二进制输入


    •实现类:SequenceFileInputFormat
    •处理二进制数据
    •包括:
    •SequenceFileAsTextInputFormat
    •SequenceFileAsBinaryInputFormat


    多文件输入


    •实现类:MultipleInputs
    •处理多种文件输入
    •包括:
    •addInputPath


    数据库输入


    •实现类:DBInputFormat
    •注意使用,因为连接过多,数据库无法承受。
    3.3.3 OutputFormat抽象类设计与实现
    OutputFormat主要用于描述输出数据的格式,它能够将用户提供的key/value对写入特定格式的文件中。
    OutputFormat抽象类提供了checkOutputSpecs方法在用户提交作业前,检查输出目录是否存在,存在则抛出异常
    getRecordWriter方法返回一个RecordWriter对象,该类中的方法write接收一个key/value对,并将其写入文件。
    基类FileOutputFormat需要提供所有基于文件的OutputFormat实现的公共功能,主要有以下两个:
    (1)实现checkOutputSpecs抽象方法
    (2)处理side-effect file,任务的side-effect file并不是任务的最终输出文件,而是具有特殊用途的任务专属文件,
    它的典型应用是推测式任务,在hadoop中,同一作业的某些任务可能慢于其他任务,这种任务会拖慢整个作业的执行速度,Hadoop会在另一个节点上启动一个相同的
    任务,该任务便被称为推测式任务,为防止这两个任务同时往输出文件中写入数据发生冲突,FileOutputFormat会为每个task的数据创建一个side-effect file,并将
    产生的数据临时写入该文件,待task结束后,再移动到最终输出目录。这些文件的创建,删除,移动等均由OutputCommitter完成。它是一个抽象类,FileOutputCommitter
    继承自OutputCommitter,并重写相关方法。用户可以编写自己的OutputCommitter,并通过参数mapred.output.committer.class指定
    MultipleOutputs合并了旧版本的MultipleOutputs功能和MultipleOutputFormat功能,新api都是用mapreduce包。
    用法:在setup中new MultipleOutputs 对象,mapreduce中mos.write,cleanup中close()。
    public <K, V> void write(String namedOutput, K key, V value)
          throws IOException, InterruptedException


    public <K, V> void write(String namedOutput, K key, V value,
          String baseOutputPath) throws IOException, InterruptedException 


    public void write(KEYOUT key, VALUEOUT value, String baseOutputPath) 
          throws IOException, InterruptedException 


    LazyOutputFormat.setOutputFormatClass(job,
                    TextOutputFormat.class);


    3.3.4 Mapper与Reducer解析
    mapreduce提供了很多Mapper/Reducer实现:
    ChainMapper/ChainReducer:用于支持链式作业
    IdentityMapper/IdentityReducer:对于key/value不进行任何处理直接输出
    InvertMapper:交换key/value位置
    RegexMapper:正则表达式字符串匹配
    TokenMapper:将字符串分割成若干个token(单词),可做WordCount的Mapper
    LongSumReducer:以key为组,对long类型的value求累加和
    Mapper包括初始化setup,map操作(mapreduce框架会通过InputFormat的RecordReader从InputSplit获取一个个keyvalue对,交给map函数处理)和清理cleanup三部分
    新版API和旧版API区别:Mapper由接口变为抽象类,且不再继承jobConfiguration和Closeable两个接口,而是直接添加setup和cleanup两个方法
    将参数封装到Context对象中
    去掉MapperRunnable接口,在Mapper中添加run方法,以方便用户定制map()函数的调用方法,实现与原来一致。
    对于一个Mapreduce应用程序,不一定非要存在Mapper。mapreduce提供了run方法,用户可以重写该方法自己实现处理逻辑


    3.3.5 Partitioner抽象类的设计与实现
    Partitioner的作用是对Mapper产生的中间结果进行分片,以便将同一分组的数据交给同一个Reduce处理,他直接影响Reduce阶段的负载均衡
    包含一个抽象方法getPartition(KEY key, VALUE value, int numPartitions),numPartitions指reduce的个数,
    mapreduce提供了两个Partitioner实现HashPartitioner和TotalOrderPartitioner,HashPartitioner是默认实现,它是基于hash值得分片
    方式(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks。
    TotalOrderPartitioner提供了一种基于区间的分片方法,它能够按照大小将数据分成若干个区间,保证后一个区间的所有数据均大于
    前一个区间的数据。(首先数据采样后根据reduce task数量获得分割点(Hadoop自带很多采样算法IntercalSampler,RandomSampler,SplitSampler),
    ,然后map阶段,将分割点保存到trie树中,以便于快速定位查找,最后reduce阶段,每个reduce对分配的区间数据进行局部排序,最终得到全排序数据)
    基于TotalOrderPartitioner全排序的效率跟key分布规律和采样算法有直接关系,key值分布越均匀且采样越具有代表性,则reduce task负载
    越均衡,全排序效率越高。
    TotalOrderPartitioner有两个典型的应用实例:TeraSort和Hbase批量数据导入
    Hadoop中TeraSort算法分析http://dongxicheng.org/mapreduce/hadoop-terasort-analyse/
    Hbase以resion为单位划分数据,resion有序,resion内部数据有序(按key排列)
    3.4.1 Hadoop Streaming的实现原理
    Hadoop Streaming允许用户将任何可执行文件或脚本作为Mapper/Reducer,Hadoop Streaming要求用户编写的Mapper和Reducer
    从标准输入中读取数据,并将结果写到标准数据中,类似以Linux的管道。
    提交作业的命令:hadoop jar hadoop-streaming.jar -file myScript -input myInputDirs -output myOutputDirs -mapper Myscript -reducer /bin/wc
    -file 可以使可执行文件成为作业的一部分,并且会一起打包提交
    实现Hadoop Streaming的技术关键点是如何使用标准输入输出实现java与可执行文件或脚本文件之间的通信,为此Hadoop Streaming使用了JDK中的
    java.lang.ProcessBuilder类,该类提供了一整套管理操作系统进程的方法,包括创建、启动和停止进程等。
    3.4.2 Hadoop Pipes实现原理
    Hadoop Pipes是hadoop方便c/c++用户编写mapreduce程序而设计的工具。其设计思想是将应用逻辑相关的C++代码放到单独进程中,然后通过
    Socket让java代码与c++代码通信完成数据计算。
    Hadoop Streaming与Hadoop Pipes的不同之处是hadoop streaming 采用标准输入输出,而Hadoop Pipes采用Socket
    3.5.1 JobControl的实现原理
    用户只需要使用job.addDepending()函数添加作业依赖关系接口,jobControl会按照依赖关系调度各个作业
    //创建configuration对象,配置configuration
    //创建job
    //设置依赖关系
    //创建jobControl对象,jobControl.addJob(job),jobControl.run()
    jobControl由两个类组成jobControl和job,job封装了一个mapreduce作业及其对应的依赖关系,主要负责监控各个依赖作业的运行状态
    以此更新自己的状态(WAITING,REDAY,RUNNING,SUCCESS,FALDED),如果一个作业的依赖作业失败,则该作业也失败。
    jobControl封装了一系列mapreduce作业及其对应的依赖关系,它将处于不同状态的作业放入不同的hash表中,按照job的状态转移作业,直到所有作业完成
    在实现的时候,jobControl包含一个线程用于周期性的监控和更新各个作业的运行状态,调度依赖作业运行完成的作业,提交处于ready状态的作业。
    3.5.2 ChainMapper/ChainReducer的实现原理
    ChainMapper和ChainReducer主要为了解决线性链式Mapper提出的,也就是说在map或者reduce阶段存在多个Mapper,这些Mapper像Linux管道一样,
    前一个Mapper的输出结果直接重定向到下一个Mapper的输入,形成一个流水线,形式类似于[MAP+,REDUCE,MAP*]。注意对于任意一个mapreduce作业,
    map和reduce阶段可以有无限个map,但reduce只能有一个。
    3.5.3 Hadoop工作流引擎
    Hadoop之上出现了很多开源的工作流引擎,主要概括为两类:隐式工作流引擎和显式工作流引擎。
    隐式工作流引擎在mapreduce之上添加了一个语言抽象层,允许用户使用更简单的方式编写应用程序,如hive和pig
    显式工作流引擎直接面向mapreduce应用程序开发,提供了一种作业依赖关系描述,并按照这种方式进行作业调度,典型代表如oozie(采用xml)






    map reduce 个数
    调度器


    mapreduce压缩
    但可以很简单的设置mapred.compress.map.output为true 启用该功能。
    压缩所使用的库由mapred.map.output.compression.codec来设定
    mapred.output.compress=true
    mapred.output.compression.codec=org.apache.Hadoop.io.compress.GzipCode
    Using Compression in MapReduce
    MapReduce读取输入路径中的压缩文件时会自动完成数据解压(可参考CompressionCodecFactory)。
    如果MapReduce Job的结果输出需要使用压缩,可以通过设置Job的相关配置属性来实现:
    mapreduce.output.fileoutputformat.compress:true
    mapreduce.output.fileoutputformat.compress.codec:CompressionCodec全限定类名eg:org.apache.Hadoop.io.compress.GzipCode
    也可以通过FileOutputFormat提供的静态方法设置,如:
    FileOutputFormat.setCompressOutput(job, true);
    FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class);
    不同的输出文件格式可能相应的设置属性会有不同。
    Compressing map output
    Map Task的输出被写出到本地磁盘,而且需要通过网络传输至Reduce Task的节点,只要简单地使用一个快速的压缩算法(如LZO、LZ4、Snappy)就可以带来性能的提升,因为压缩机制的使用避免了Map Tasks与Reduce Tasks之间大量中间结果数据被传输。可以通过设置相应的Job配置属性开启:
    mapreduce.map.output.compress:true
    mapreduce.map.output.compress.codec:CompressionCodec全限定类名
    也可以通过Configuration API进行设置:
    new API:
    Configuration conf = new Configuration();
    conf.setBoolean(Job.MAP_OUTPUT_COMPRESS, true);
    conf.setClass(Job.MAP_OUTPUT_COMPRESS_CODEC, GzipCodec.class, CompressionCodec.class);
    Job job = new Job(conf);


    old API:
    conf.setCompressMapOutput(true);
    conf.setMapOutputCompressorClass(GzipCodec.class);
    展开全文
  • Hadoop零基础教程,该课程主要为大家详细讲解YARN和MapReduce的构造,以及YARN和MapReduce的入门使用。通过本节课程带您一步步熟悉和掌握Hadoop基础。
  • E-MapReduce

    万次阅读 2018-01-16 11:17:22
    E-MapReduce 是构建于阿里云 ECS 弹性虚拟机之上,利用开源大数据生态系统,包括 Hadoop、Spark、Kafka、Storm,为用户提供集群、作业、数据等管理的一站式大数据处理分析服务。 2. 产品优势3. 产品功能4. 应用...

    1. 产品介绍

    E-MapReduce 是构建于阿里云 ECS 弹性虚拟机之上,利用开源大数据生态系统,包括 Hadoop、Spark、Kafka、Storm,为用户提供集群、作业、数据等管理的一站式大数据处理分析服务。

    2. 产品优势

    这里写图片描述

    3. 产品功能

    这里写图片描述

    4. 应用场景

    4.1 离线数据处理

    这里写图片描述

    4.2 Ad hoc数据分析

    这里写图片描述

    4.3 海量数据在线服务

    这里写图片描述

    4.4 流式数据处理

    这里写图片描述

    展开全文
  • MapReduce2.0源码分析与编程实战》比较系统地介绍了新一代MapReduce2.0的理论体系、架构和程序设计方法。全书分为10章,系统地介绍了HDFS存储系统,Hadoop的文件I/O系统,MapReduce2.0的框架结构和源码分析,...
  • Hadoop之MapReduce编程实例完整源码

    热门讨论 2012-08-01 12:55:35
    一个自己写的Hadoop MapReduce实例源码,网上看到不少网友在学习MapReduce编程,但是除了wordcount范例外实例比较少,故上传自己的一个。包含完整实例源码,编译配置文件,测试数据,可执行jar文件,执行脚本及操作...
  • windows 10 开发mapreduce

    2017-03-04 02:00:07
    DEBUG - PrivilegedAction as:root (auth:SIMPLE) from:org.apache.hadoop.mapreduce.Job.updateStatus(Job.java:311) DEBUG - IPC Client (1676093451) connection to node3/192.168.235.130:8032 from root ...
  • MapReduce介绍

    万次阅读 多人点赞 2018-10-21 12:45:11
    MapReduce产生背景 如果让你统计日志里面的出现的某个URL的总次数,让你自己去写个单机版的程序,写个逻辑:无非就是读这个文件一行,然后把那个地方截取出来,截取出来之后,然后可以把它放到一个HashMap里面...

    场景:比如有海量的文本文件,如订单,页面点击事件的记录,量特别大,单机版很难搞定。

    怎样解决海量数据的计算?

    求和: 1 + 5 +7 + 3 +4 +9 +3 + 5 +6
    在这里插入图片描述

    MapReduce产生背景

    如果让你统计日志里面的出现的某个URL的总次数,让你自己去写个单机版的程序,写个逻辑:无非就是读这个文件一行,然后把那个地方截取出来,截取出来之后,然后可以把它放到一个HashMap里面,用Map去重,看到一条新的URL ,就把它put进去,然后+1,如果下次看到再有就直接+1,没有就put进去,单机版的话逻辑是很好实现,但是数据量一大,你觉得单机版本还能搞定吗?

    首先2T的文件,你放在单机上可能存不下来,如果再他多一点呢?比如几千个文件,几十个T,单机存都存不下,那么存在哪里-------hdfs上。
    因为放在HDFS上可以放很多很多,比如说HDFS上有100个节点,每个节点上能耐挂载8T的硬盘,那就有800T,800T,你每个文件存3个副本的话,你至少也能存100多个T文件,耗费了大概6个T的空间,但是你一旦放到HDFS上就有一个问题:你的文件就会被切散了,被切三到很多的机器上,这个时候,你再对它们进行统计,这个时候,按照原来的逻辑,会不会出现问题?

    你的任何一个节点上存的是某个文件的某些块,假设你是在那台机器上去做统计的话,你统计到的永远是局部的数据,那你专门写一个客户端,我的程序运行在这个客户端上,我去读数据,读一点统计一点,到把整个文件都读完了,统计结果也就出来了,问题是那样的话,你的程序又变成了一个单机版的,那你的内存也就不够,因为你要第一点进来统计一点,是不是要保存一些中间数据,那你可能内存也不够了,而且你因为是一个单机版的程序,所以你的速度是不是也很慢,而且你还要不断的从网络里面去拿那些数据,也会很慢,所以这个时候呢?你专门写一个客户端去做统计,肯定是不合适。

    那你是不是应该把你的程序分发到集群的每一台DN上去做统计,也就是把运算往数据去移动,而不是把数据移动到运算,把我的运算逻辑移动到数据那端去,数据在哪里,我就在哪里运算,但是这也有一个问题,因为运算也变成了一个分布式的了,你的每一份运算结果都只是局部的结果,那么这个时候也存在问题:
    1.你的代码怎么实现分发到很多机器上去运行,这件事情谁帮你做,如果是要你自己写程序的话,你是不是得有个U盘拷你的jar包,一个计算一个计算的去拷,拷完之后再启动,每个机器都启动jar,等你启动最后一台的时候,前面那台已经运行完了,最后一台才刚开始启动,这个工作你用手动去做是不是不合适啊?所以当你把一个简单的逻辑,变成这种分布式运行的时候,你发现很多问题就来了:
    1)我的代码怎么分发,怎么配置启动环境,怎么启动起来,这个是不是得有一个庞大的系统去做,也就是说你应该额外开发这么一个叫做资源分发和Java启动程序这么一个配置 的系统,这个系统你会吗?写得出来吗?你要是写的话,是不是还得花很多时间,你还要写很多东西,因为你现在的Java不一定是擅长那个领域的 ,那这个耗费的代价就很大了
    2)那个数据,比如刚才那个日志数据,是放到HDFS上面去了,但是不代表HDFS上的每一台DN上面都有这一部分数据里面的内容,因为我们这个集群很大,你这个文件存进去的时候可能只占了其中的30台节点,其中某30台节点上有你这些文件,其他节点上个根本就没有你这些文件,那我们的代码,运行逻辑,最好是放到那30台上面去做统计,你放到其他的那些机器上,它可以运行,但是它的数据必须来源于网络,是不是效率会比较低,也就是说你的代码究竟分发到哪些机器上去运行,是不是也要一个策略的问题,那么这个策略是不是也有一定的算法,那么这个时候,你为了实现你那个简单的逻辑,就再去开发这样一个系统出来是不是也是很大的开发量,再考虑一个问题,假如刚才那两个工作你都做完了,你的代码真的成功的在那30台机器上跑起来了,跑起来之后,其中假设有一台机器宕机了,那么你统计的那一部分局部数据是不是也就没有了,那个局部结果也就没有了,那个局部结果没有,假设你有个汇总的结果还正确吗?没有意义了,也就是说你还得解决一个问题,就是你时时刻刻得却监控着你的程序运行情况,那个节点正常,哪个节点不正常,这个问题也是很复杂的,假设这个问题 你也解决了,还有一个问题:
    刚才你的逻辑只是统计出中间结果,这个时候是不是还得汇总啊,汇总就是意味着,你要在那30台节点之间结果里面才能汇总,要么把它们全部调到一台机器上就能进行汇总,但是你调到一台机器上汇总的话,你那一台机器的负载是不是会很高,对吧?假设我调到多态机器汇总,逻辑就变得复杂了,比如说,只要是你们那30台机器上统计,每台机器上的那个URL有多少条,你又把那个所有那个URL的数据全部汇总到某个汇总节点,假如有两个URL,哪个URL分发到那个节点上进行汇总,这个策略是不是也会变得很复杂了,那你还得去做个中间数据的调度系统,那也很麻烦。

    那这样的话,我们就发现,哪怕是一个很简单的东西,你也要把它变成一个分布式运行的程序,是不是面临很多很多其他的问题,跟我们逻辑无关的问题,往往这些问题要比解决那个逻辑要复杂得多,那么这些问题解决不是我们擅长的,我们大量的普通程序员还没达到那些程度,这么复杂的问题要写出来是不是很麻烦呢?你不能要求每个程序员都能达到那个功力把,我们不过就是写个简单的逻辑统计这个文本里面哪个URL出现的总次数,很简单的东西,所以呢,MapReduce才是我们这些普通程序员的福音。

    就是说当我们面临海量数据处理的时候,那个逻辑也许很简单,但是面临海量数据处理,要我们这个 逻辑代码变成分布式运行,就会变得很复杂,而那些很复杂的事情又不是我们关心的,我关心的只是那个逻辑,那这个时候,就有人把你不擅长的而且又必须解决的,而且跟你的逻辑关系又不大的那些东西全部给封装起来,那么这个时候,我们是不是就直接写逻辑了,就会MapReduce的框架和Yarn,这两个是不是做运算的,由这两个框架把我们刚才讲的那些东西全部封装起来,这个就是MapReduce产生的背景,就是这个问题。

    总结

    把我们很简单的运算逻辑很方便的扩展到海量数据的场景下分布式运算,所以MapReduce程序对我们程序员来说很简单,因为它把那些东西都给封装起来了,你只要写业务逻辑,写业务逻辑还不擅长吗?业务逻辑大部分就是处理文本,处理字符串,我们学的大部分逻辑里面,大部分都是在处理这个问题:处理文本、处理字符串、查询数据库是不是得到一些东西啊。查询一下数据库,处理一下字符串,输出结果,而这个逻辑本身 不用你太多的分布式细节 ,你只要把逻辑写出来就可以了,但是你写MapReduce的时候,必须要符合人家编程的规范,你不能你的写法写,他按他的写法写,每个人的写法都不一样,那MapReduce也没法给你去分发和运行,所以你也要符合他的规范,怎样才算符合规范呢?

    就说你的代码,你的任意一个逻辑实现都要分成这么两个步骤:
    1)Map
    2)Reduce

    比如说我们统计日志文件里面,相同URL出现的总次数
    如下图:
    在这里插入图片描述

    例子:

    在这里插入图片描述

    WCMapper.java

    import java.io.IOException;
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Mapper;
    /**
     * Description: Mapper<br/>
     * Copyright (c) , 2018, xlj <br/>
     * This program is protected by copyright laws. <br/>
     * Program Name:WCMapper.java <br/>
     * 
     * @version : 1.0
     * 
     * Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
     * 它的这个Mapper让你去定义四个泛型,为什么mapper里面需要四个泛型
     * 其实读文本文件的操作不用你来实现,框架已经帮你实现了,框架可以读这个文件
     * 然后每读一行,就会发给你这个map,让你去运行一次,所以它读一行是不是把数据传给你,
     * 
     * 那他传给map的时候,这个数据就意味着类型的一个协议,我以什么类型的数据给你,我是不是得事先定好啊
     * map接收的数据类型得和框架给他的数据类型一致,不然的话就会出现类型转换异常
     * 所以map里面得定数据类型,前面两个是map拿数据的类型,拿数据是以什么类型拿的,那么框架就是以这个类型传给你
     * 
     * 另外两个泛型是map的输出数据类型,即reduce也得有4个泛型,前面两个是reduce拿数据的泛型得和map输出的泛型类型一致
     * 剩下两个是reduce再输出的结果时的两个数据类型
     */
    /*
     * 4个泛型,前两个是指定mapper端输入数据的类型,为什么呢,mapper和reducer都一样
     * 拿数据,输出数据都是以<key,value>的形式进行的--那么key,value都分别有一个数据类型
     * KEYIN:输入的key的类型
     * VALUEIN:输入的value的类型
     * KEYOUT:输出的key的数据类型
     * VALUEOUT:输出的value的数据累心
     * map reduce的数据输入输出都是以key,value对封装的
     * 至于输入的key,value形式我们是不能控制的,是框架传给我们的,
     * 框架传给我们是什么类型,我们这里就写什么数据类型
     * 
     * 默认情况下框架传给我们的mapper的输入数据中,key是要处理的文本中一行的起始偏移量,
     * 因为我们的框架是读一行就调用一次我们的偏移量
     * 那么就把一行的起始偏移量作为key,这一行的内容作为value 
     * 
     * 那么输出端的数据类型是什么,由于我们输出的数<hello,1>
     * 那么它们的数据类型就显而易见了
     * 初步定义为:
     * Mapper<Long, String, String, int>
     * 但是不管是Long还是String,在MapReduce里面运行的时候,这个数据读到网络里面进行传递
     * 即各个节点之间会进行传递,那么要在网络里面传输,那么就意味着这个数据得序列化
     * Long、String对象,内存对象走网络都得序列化,Long、String,int序列化
     * 如果自己实现Serializable接口,那么附加的信息太多了
     * hadoop实现了自己的一套序列化机制
     * 所以就不要用Java里面的数据类型了,而是用它自己的封装一套数据类型
     * 这样就有助于提高效率,实现了自己的序列化接口
     * 在序列化传输的 时候走的就是自己的序列化方法来传递,少了很多负载信息,传递数据精简,
     * Long---LongWritable
     * String也有自己的封装-Text
     * int--IntWritable
     */
    public class WCMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    //	MapReduce框架每读一次数据,就会调用一次该方法
    	@Override
    	protected void map(LongWritable key, Text value, Context context)
    			throws IOException, InterruptedException {
    		//具体业务逻辑就写在这个方法体中,而且我们业务要处理的数据已经被框架传递进来,在方法参数中
    		//key--这一行数据的其实偏移量   value--这一行数据的文本内容
    		//1.先把单词拿出来,拿到一行
    		String line = value.toString();
    		//2.切分单词,这个是按照特定的分隔符 进行切分
    		String [] words = line.split(" ");
    		//3.把里面的单词发送出去
    		/*
    		 * 怎么发出去呢?我都不知道reduce在哪里运行
    		 * 其实呢,这个不用我们关心
    		 * 你只要把你的东西给那个工具就可以了
    		 * 剩下的就给那个框架去做
    		 * 那个工具在哪-----context
    		 * 它把那个工具放到那个context里面去了,即输出的工具
    		 * 所以你只要输出到context里面就行了
    		 * 剩下的具体往哪里走,是context的事情
    		 */
    		//遍历单词数组,输出为<K,V>形式 key是单词,value是1
    		for (String word : words) {
    			//记得把key和value继续封装起来,即下面
    			context.write(new Text(word), new IntWritable(1));
    		}
    		/*
    		 * map方法的执行频率:每读一行就调一次
    		 * 最后到reduce 的时候,应该是把某个单词里面所有的1都到,才能处理
    		 * 而且中间有一个缓存的过程,因为每个map的处理速度都不会完全一致
    		 * 等那个单词所有的1都到齐了才传给reduce
    		 */
    		//每一组key,value都全了,才会去调用一次reduce,reduce直接去处理valuelist
    		//接着就是写Reduce逻辑了
    		
    	}
    }
    
    

    WCReducer.java

    import java.io.IOException;
    
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Reducer;
    
    /**
     * Description: Reducer<br/>
     * Copyright (c) , 2018, xlj <br/>
     * This program is protected by copyright laws. <br/>
     * Program Name:WCReducer.java <br/>
     * 
     * @version : 1.0
     */
    /*
     * 类型记得要对应
     */
    public class WCReducer extends Reducer<Text, IntWritable, Text, Text> {
    	//map处理之后,value传过来的是一个value的集合 
    	//框架在map处理完成之后,将所有的KV对保存起来,进行分组,然后传递一个组,调用一次reduce
    	//相同的key在一个组
    	@Override
    	protected void reduce(Text key, Iterable<IntWritable> values, Context context)
    			throws IOException, InterruptedException {
    		//遍历valuelist,进行了累加
    		int count = 0;
    		for (IntWritable value : values) {
    			//get()方法就能拿到里面的值
    			count += value.get();
    		}
    		//输出一组(一个单词)的统计结果
    		//默认输出到HDFS的一个文件上面去,放在HDFS的某个目录下
    		context.write(key, new Text(count+""));
    		//但是还差一个描述类:用来描述整个逻辑
    	
    		/*
    		 * Map,Reducce都是个分散的,那集群运行的时候不知道运行哪些MapReduce
    		 * 
    		 * 处理业务逻辑的一个整体,叫做job
    		 * 我们就可以把那个job告诉那个集群,我们此次运行的是哪个job,
    		 * job里面用的哪个作为Mapper,哪个业务作为Reducer,我们得指定
    		 * 
    		 * 所以还得写一个类用来描述处理业务逻辑
    		 * 把一个特定的业务处理逻辑叫做一个job(作业),我们就可以把这个job告诉那个集群,
    		 * 
    		 */
    	}
    }
    
    

    WCRunner.java

    import java.io.IOException;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    
    
    /**
     * Description: 用来描述一个特定的作业<br/>
     * Copyright (c) , 2018, xlj <br/>
     * This program is protected by copyright laws. <br/>
     * Program Name:WCRunner.java <br/>
     * 
     * 该作业使用哪个类作为逻辑处理的map
     * 哪个作为reduce
     * 还可以指定该作业要处理的数据所在的路径
     * 还可以指定该作业输出的结果放到哪个路径
     * 
     * @version : 1.0
     */
    
    public class WCRunner {
    	public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
    		//首先要描述一个作业,这些信息是挺多的,哪个是map,哪个是reduce,输入输出路径在哪
    		//一般来说这么多信息,就可以把它封装在一个对象里面,那么这个对象呢就是 ----Job对象
    		Job job = Job.getInstance(new Configuration());
    		
    		//job用哪个类作为Mapper 指定输入输出数据类型是什么
    		job.setMapperClass(WCMapper.class);
    		job.setMapOutputKeyClass(Text.class);
    		job.setMapOutputValueClass(IntWritable.class);
    		
    		//job用哪个类作为Reducer 指定数据输入输出类型是什么
    		job.setReducerClass(WCReducer.class);
    		job.setOutputKeyClass(Text.class);
    		job.setOutputValueClass(Text.class);
    		
    		//指定原始数据存放在哪里
    		//参数1:里面是对哪个参数进行指定
    		//参数2:文件在哪个路径下,这个路径下的所有文件都会去读的
    		FileInputFormat.setInputPaths(job, new Path("input/data1"));
    		
    		//指定处理结果的数据存放路径
    		FileOutputFormat.setOutputPath(job, new Path("output1"));
    		
    		//提交
    		int isok =  job.waitForCompletion(true)?0:-1;
    		System.exit(isok);
    	}
    }
    

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • Hadoop MapReduce

    千次阅读 2011-05-03 16:53:00
    Hadoop MapReduce是一个用于处理海量数据的分布式计算框架。这个框架解决了诸如数据分布式存储、作业调度、容错、机器间通信等复杂问题,可以使没有并行处理或者分布式计算经验的工程师,也能很轻松地写出结构简单的...
  • MapReduce优化

    千次阅读 2013-04-11 19:33:48
    同样,MapReduce计算模型的多次优化也是为了更好地解答这两个问题。 MapReduce计算模型的优化涉及了方方面面的内容,但是主要集中在两个方面:一是计算性能方面的优化;二是I/O操作方面的优化。这其中,又包含六...
  • MapReduce--2--MapReduce全局计数器

    万次阅读 2017-10-23 13:29:17
    MapReduce的全局计数器 1.1、介绍 计数器是用来记录job的执行进度和状态的。它的作用可以理解为日志。我们可以在程序的某个位置插入计数器,记录数据或者进度的变化情况。   MapReduce 计数器(Counter)为我们...
  • 初学MapReduce

    万次阅读 多人点赞 2019-11-13 08:24:52
    MapReduce计算框架 并行计算框架 一个大的任务拆分成多个小任务,将多个小任务分发到多个节点上。每个节点同时执行计算。 MapReduce核心思想 分而治之,先分后和:将一个大的、复杂的工作或任务,拆分成多个小的...
  • MapReduce编程模型

    万次阅读 2018-06-29 07:09:53
  • conf.set("mapreduce.job.jar", "hdfs://172.16.200.210:8020/user/root/testjar/hadoopTest.jar"); conf.set("mapreduce.job.output.key.class", "org.apache.hadoop.io.Text"); conf.set("mapreduce.job....
  • MapReduce进阶:多MapReduce的链式模式

    千次阅读 2016-06-18 16:20:50
    我们不可能一直沉浸在 WordCount 的成功运行当中,就像之前学习 Java 或是其他编程语言不会着迷于 HelloWord 一样。前面的 WordCount 程序只有一个 Mapper 和一个 Reducer 参与,也就是说只有一个 Job 参与。...
  • MapReduce编程案例系列篇(01-15)

    万次阅读 多人点赞 2017-10-23 18:27:32
    由于本人最开始接触大数据工作,主要以写MapReduce程序为主,虽然现在有流行的言论称MapReduce这种运行很慢的分布式计算编程框架将要被各种内存计算框架取代。但是MapRedcue也会吸收很多流行的内存计算的各种优点,...
  • 准备自己写一个代码熟悉一下mapreduce,但是写好之后发现reduce函数不执行,运行程序也没有报错,逛了很多论坛都没有解决方案,因为是初步接触mapreduce,所以对mapreduce的编程不太了解,希望各位大大帮我看下代码...
  • 15/04/23 07:12:51 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_local168934583_0001 15/04/23 07:12:51 WARN conf.Configuration: file:/home/zxy/hadoop_tmp/mapred/staging/zxy168934583/....
  • MapReduce框架源码解析

    万次阅读 2019-11-01 17:01:07
    MapReduce框架源码解析

空空如也

1 2 3 4 5 ... 20
收藏数 65,986
精华内容 26,394
关键字:

mapreduce