3.1总结
MapReduce
- MapReduce是一种编程模型,用于大规模数据集,分为映射 和 归约 ,大数据量下优势明显,读写HDFS次数多
mapreduce流程
-
maptask:
- 读数据:读取源数据,获取分片数据信息, 形成key-value数据 key是偏移值;<0,hello you> <10,hello me>
- 逻辑处理:调用map方法读取每行数据进行处理;<hello,1> <you,1> <hello,1> <me,1>
- 分区:通过Partitioner类的getPartition()方法对数据进行分区,分区号相同的数据会被分发给同一reducetask;
- 排序:对不同分区中的数据进行排序(按照k)、分组。 排序默认按照字典序列,分组指的是相同key的value放到一个集合中。排序后:<hello,1> <hello,1> <me,1> <you,1> 分组后:<hello,{1,1}><me,{1}><you,{1}>
-
reducetask:
- 多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点上。
- 处理数据:对多个map的输出进行合并、排序,覆盖reduce函数,接收的是分组后的数据,实现自己的业务逻辑,<hello,2> <me,1> <you,1>
- 对reduce输出的<k,v>写到HDFS中
shuffle流程
- map端shuffle
- 分区partition,能够把map任务处理的结果**发给指定reduce执行,负载均衡,**避免数据倾斜。
- 写入环形内存缓冲区,频繁I/O操作会严重降低效率,每个map任务都会分配一个环形内存缓冲区,用于存储map任务输出的键值对,默认大小100MB,
- 执行溢出写 排序->合并->生成溢出写文件 一旦缓存区内容达到阈值,默认80%,就锁定着80%的内存,Map task的输出结果还可以往剩下的20MB内存中写,互不影响。并在每个分区中对其键值对进行sort,按照paritition和key排序,排序完后会创建一个溢出文件,然后把这部分数据溢出spill写到本地磁盘。如果客户端自定义了Combiner(相当于map阶段的reduce),则会在分区排序后到溢写出前自动调用combiner,将相同的key的value相加,这样的好处就是减少溢写到磁盘的数据量。这个过程叫“合并”)
- 归并merge,当一个maptask处理数据很大时,对同一个map任务产生的多个spill文件进行归并生成最终的一个已分区且已排序的大文件
- 合并(Combine)和归并(Merge)的区别:
两个键值对<“a”,1>
和<“a”,1>
,如果合并,会得到<“a”,2>
,如果归并,会得到<“a”,<1,1>>
- reduce端shuffle
- 复制copy,Reduce 任务通过HTTP向各个Map任务拖取它所需要的数据。
- 归并merge,Map的输出数据已经是有序的,Merge进行一次合并排序,所谓Reduce端的 sort过程就是这个合并的过程。一般Reduce是一边copy一边sort,即copy和sort两个阶段是重叠而不是完全分开的。
Hive
- hive其实本身并不是一个仓库,而是一个sql翻译工具.把sql翻译成mapreduce语句,hadoop集群去hdfs集群上执行这些mapreduce语句,在执行的过程中去yarn申请资源,
- 所谓的hive仓库,其实是顶层的一个hive转换工具+底层的HDFS+YARN资源管理器构成的.
Hive中MR(map reduce)、Tez和Spark执行引擎对比
- MapReduce是一种编程模型,用于大规模数据集,分为映射 和 归约 ,大数据量下优势明显,读写HDFS次数多
- Tez是Apache开源的支持DAG(有向图)作业的计算框架,它直接源于MapReduce框架,核心思想是将Map和Reduce两个操作进一步拆分,把多个MR任务组合成一个较大的DAG任务,减少文件存储并可以优化子过程
- Spark基于map reduce算法实现的分布式计算,Job中间输出和结果可以保存在内存中,不需要读写HDFS,以DAG方式处理数据,数据量比较大的时候比较吃内存
- Spark和Tez的区别:
- Spark与Tez都是以DAG方式处理数据
- Spark更像是一个通用的计算引擎,可以同时作为批式和流式的处理引擎,提供内存计算,实时流处理,机器学习等多种计算方式,适合迭代计算。tez作为一个框架工具,特定为hive和pig提供批量计算
- Spark属于内存计算,支持多种运行模式,可以跑在standalone,yarn上;而Tez只能跑在yarn上;
- Tez能够及时的释放资源,重用container,节省调度时间,对内存的资源要求率不高; 而spark如果存在迭代计算时,container一直占用资源;
- 使用场景:
- 如果数据需要快速处理而且资源充足,则可以选择Spark;如果资源是瓶颈,则可以使用Tez;
Mysql
- 使用count(列名)当某列出现null值的时候,count(*)仍然会计算,但是count(列名)不会。
order by 和 group by 的区别
- order by 就是行的排序方式,默认的为升序。 order by 后面必须列出排序的字段名,可以是多个字段名。
- group by是分组。必须有“聚合函数”来配合才能使用,使用时至少需要一个分组标志字段。注意:聚合函数是—sum()、count()、avg()等都是“聚合函数”,在group by 中用count(*) 获取条数 ,获取的不是总条数,而是每个组的条数,count(*)的结果是分组以后每组中的记录的条数,而不是分组的数目,
- where后面不能接聚合函数,聚合函数是针对结果集进行的,但是where条件并不是在查询出结果集之后运行,那么只能用另外一种方法:havaing。having就是专门为了应付这种情况而发明出来的
having 和where的用法区别
- having只能用在group by之后,对分组后的结果进行筛选(即使用having的前提条件是分组)
- where肯定在group by 之前。
- where后的条件表达式里不允许使用聚合函数,而having可以。
当一个查询语句同时出现了where,group by,having,order by的时候,执行顺序和编写顺序是:
- 先连接from后的数据源(若有join,则先执行on后条件,再连接数据源)。
- 执行where xx对全表数据做筛选,返回第1个结果集。
- 针对第1个结果集使用group by分组,返回第2个结果集。
- 针对第2个结果集中的每1组数据执行select xx,有几组就执行几次,返回第3个结果集。
- 针对第3个结集执行having xx进行筛选,返回第4个结果集。
- 针对第4个结果集排序。