mapreduce源码分析
Ⅰ java9都快发布了,Java8的十大新特性你了解多少呢
一、Lambda表达式
Lambda表达式可以说是Java 8最大的卖点,她将函数式编程引入了Java。Lambda允许把函数作为一个方法的参数,或者把代码看成数据。
一个Lambda表达式可以由用逗号分隔的参数列表、–>符号与函数体三部分表示。例如:
Arrays.asList( "p", "k", "u","f", "o", "r","k").forEach( e -> System.out.println( e ) );
1 Arrays.asList( "p", "k", "u","f", "o", "r","k").forEach( e -> System.out.println( e ) );
为了使现有函数更好的支持Lambda表达式,Java
8引入了函数式接口的概念。函数式接口就是只有一个方法的普通接口。java.lang.Runnable与java.util.concurrent.Callable是函数式接口最典型的例子。为此,Java
8增加了一种特殊的注解@FunctionalInterface:
1 @FunctionalInterface
2 public interface Functional {
3 void method();
4 }
二、接口的默认方法与静态方法
我们可以在接口中定义默认方法,使用default关键字,并提供默认的实现。所有实现这个接口的类都会接受默认方法的实现,除非子类提供的自己的实现。例如:
1 public interface DefaultFunctionInterface {
2 default String defaultFunction() {
3 return "default function";
4 }
5 }
我们还可以在接口中定义静态方法,使用static关键字,也可以提供实现。例如:
1 public interface StaticFunctionInterface {
2 static String staticFunction() {
3 return "static function";
4 }
5 }
接口的默认方法和静态方法的引入,其实可以认为引入了C++中抽象类的理念,以后我们再也不用在每个实现类中都写重复的代码了。
三、方法引用
通常与Lambda表达式联合使用,可以直接引用已有Java类或对象的方法。一般有四种不同的方法引用:
构造器引用。语法是Class::new,或者更一般的Class< T >::new,要求构造器方法是没有参数;
静态方法引用。语法是Class::static_method,要求接受一个Class类型的参数;
特定类的任意对象方法引用。它的语法是Class::method。要求方法是没有参数的;
特定对象的方法引用,它的语法是instance::method。要求方法接受一个参数,与3不同的地方在于,3是在列表元素上分别调用方法,而4是在某个对象上调用方法,将列表元素作为参数传入;
四、重复注解
在Java 5中使用注解有一个限制,即相同的注解在同一位置只能声明一次。Java
8引入重复注解,这样相同的注解在同一地方也可以声明多次。重复注解机制本身需要用@Repeatable注解。Java
8在编译器层做了优化,相同注解会以集合的方式保存,因此底层的原理并没有变化。
五、扩展注解的支持
Java 8扩展了注解的上下文,几乎可以为任何东西添加注解,包括局部变量、泛型类、父类与接口的实现,连方法的异常也能添加注解。
六、Optional
Java 8引入Optional类来防止空指针异常,Optional类最先是由Google的Guava项目引入的。Optional类实际上是个容器:它可以保存类型T的值,或者保存null。使用Optional类我们就不用显式进行空指针检查了。
七、Stream
Stream
API是把真正的函数式编程风格引入到Java中。其实简单来说可以把Stream理解为MapRece,当然Google的MapRece的灵感也是来自函数式编程。她其实是一连串支持连续、并行聚集操作的元素。从语法上看,也很像linux的管道、或者链式编程,代码写起来简洁明了,非常酷帅!
八、Date/Time API (JSR 310)
Java 8新的Date-Time API (JSR 310)受Joda-Time的影响,提供了新的java.time包,可以用来替代
java.util.Date和java.util.Calendar。一般会用到Clock、LocaleDate、LocalTime、LocaleDateTime、ZonedDateTime、Duration这些类,对于时间日期的改进还是非常不错的。
九、JavaScript引擎Nashorn
Nashorn允许在JVM上开发运行JavaScript应用,允许Java与JavaScript相互调用。
十、Base64
在Java 8中,Base64编码成为了Java类库的标准。Base64类同时还提供了对URL、MIME友好的编码器与解码器。
除了这十大新特性之外,还有另外的一些新特性:
更好的类型推测机制:Java 8在类型推测方面有了很大的提高,这就使代码更整洁,不需要太多的强制类型转换了。
编译器优化:Java 8将方法的参数名加入了字节码中,这样在运行时通过反射就能获取到参数名,只需要在编译时使用-parameters参数。
并行(parallel)数组:支持对数组进行并行处理,主要是parallelSort()方法,它可以在多核机器上极大提高数组排序的速度。
并发(Concurrency):在新增Stream机制与Lambda的基础之上,加入了一些新方法来支持聚集操作。
Nashorn引擎jjs:基于Nashorn引擎的命令行工具。它接受一些JavaScript源代码为参数,并且执行这些源代码。
类依赖分析器jdeps:可以显示Java类的包级别或类级别的依赖。
JVM的PermGen空间被移除:取代它的是Metaspace(JEP 122)。
Ⅱ 做大数据分析一般用什么工具呢
Java :只要了解一些基础即可,做大数据不需要很深的Java 技术,学java SE 就相当于有学习大数据。基础
Linux:因为大数据相关软件都是在Linux上运行的,所以Linux要学习的扎实一些,学好Linux对你快速掌握大数据相关技术会有很大的帮助,能让你更好的理解hadoop、hive、hbase、spark等大数据软件的运行环境和网络环境配置,能少踩很多坑,学会shell就能看懂脚本这样能更容易理解和配置大数据集群。还能让你对以后新出的大数据技术学习起来更快。
好说完基础了,再说说还需要学习哪些大数据技术,可以按我写的顺序学下去。
Hadoop:这是现在流行的大数据处理平台几乎已经成为大数据的代名词,所以这个是必学的。Hadoop里面包括几个组件HDFS、MapRece和YARN,HDFS是存储数据的地方就像我们电脑的硬盘一样文件都存储在这个上面,MapRece是对数据进行处理计算的,它有个特点就是不管多大的数据只要给它时间它就能把数据跑完,但是时间可能不是很快所以它叫数据的批处理。
记住学到这里可以作为你学大数据的一个节点。
Zookeeper:这是个万金油,安装Hadoop的HA的时候就会用到它,以后的Hbase也会用到它。它一般用来存放一些相互协作的信息,这些信息比较小一般不会超过1M,都是使用它的软件对它有依赖,对于我们个人来讲只需要把它安装正确,让它正常的run起来就可以了。
Mysql:我们学习完大数据的处理了,接下来学习学习小数据的处理工具mysql数据库,因为一会装hive的时候要用到,mysql需要掌握到什么层度那?你能在Linux上把它安装好,运行起来,会配置简单的权限,修改root的密码,创建数据库。这里主要的是学习SQL的语法,因为hive的语法和这个非常相似。
Sqoop:这个是用于把Mysql里的数据导入到Hadoop里的。当然你也可以不用这个,直接把Mysql数据表导出成文件再放到HDFS上也是一样的,当然生产环境中使用要注意Mysql的压力。
Hive:这个东西对于会SQL语法的来说就是神器,它能让你处理大数据变的很简单,不会再费劲的编写MapRece程序。有的人说Pig那?它和Pig差不多掌握一个就可以了。
Oozie:既然学会Hive了,我相信你一定需要这个东西,它可以帮你管理你的Hive或者MapRece、Spark脚本,还能检查你的程序是否执行正确,出错了给你发报警并能帮你重试程序,最重要的是还能帮你配置任务的依赖关系。我相信你一定会喜欢上它的,不然你看着那一大堆脚本,和密密麻麻的crond是不是有种想屎的感觉。
Hbase:这是Hadoop生态体系中的NOSQL数据库,他的数据是按照key和value的形式存储的并且key是唯一的,所以它能用来做数据的排重,它与MYSQL相比能存储的数据量大很多。所以他常被用于大数据处理完成之后的存储目的地。
Kafka:这是个比较好用的队列工具,队列是干吗的?排队买票你知道不?数据多了同样也需要排队处理,这样与你协作的其它同学不会叫起来,你干吗给我这么多的数据(比如好几百G的文件)我怎么处理得过来,你别怪他因为他不是搞大数据的,你可以跟他讲我把数据放在队列里你使用的时候一个个拿,这样他就不在抱怨了马上灰流流的去优化他的程序去了,因为处理不过来就是他的事情。而不是你给的问题。当然我们也可以利用这个工具来做线上实时数据的入库或入HDFS,这时你可以与一个叫Flume的工具配合使用,它是专门用来提供对数据进行简单处理,并写到各种数据接受方(比如Kafka)的。
Spark:它是用来弥补基于MapRece处理数据速度上的缺点,它的特点是把数据装载到内存中计算而不是去读慢的要死进化还特别慢的硬盘。特别适合做迭代运算,所以算法流们特别稀饭它。它是用scala编写的。Java语言或者Scala都可以操作它,因为它们都是用JVM的。
Ⅲ 大数据分析应该掌握哪些基础知识
Java基础语法
· 分支结构if/switch
· 循环结构for/while/do while
· 方法声明和调用
· 方法重载
· 数组的使用
· 命令行参数、可变参数
IDEA
· IDEA常用设置、常用快捷键
· 自定义模板
· 关联Tomcat
· Web项目案例实操
面向对象编程
· 封装、继承、多态、构造器、包
· 异常处理机制
· 抽象类、接口、内部类
· 常有基础API、集合List/Set/Map
· 泛型、线程的创建和启动
· 深入集合源码分析、常见数据结构解析
· 线程的安全、同步和通信、IO流体系
· 反射、类的加载机制、网络编程
Java8/9/10/11新特性
· Lambda表达式、方法引用
· 构造器引用、StreamAPI
· jShell(JShell)命令
· 接口的私有方法、Optional加强
· 局部变量的类型推断
· 更简化的编译运行程序等
MySQL
· DML语言、DDL语言、DCL语言
· 分组查询、Join查询、子查询、Union查询、函数
· 流程控制语句、事务的特点、事务的隔离级别等
JDBC
· 使用JDBC完成数据库增删改查操作
· 批处理的操作
· 数据库连接池的原理及应用
· 常见数据库连接池C3P0、DBCP、Druid等
Maven
· Maven环境搭建
· 本地仓库&中央仓库
· 创建Web工程
· 自动部署
· 持续继承
· 持续部署
Linux
· VI/VIM编辑器
· 系统管理操作&远程登录
· 常用命令
· 软件包管理&企业真题
Shell编程
· 自定义变量与特殊变量
· 运算符
· 条件判断
· 流程控制
· 系统函数&自定义函数
· 常用工具命令
· 面试真题
Hadoop
· Hadoop生态介绍
· Hadoop运行模式
· 源码编译
· HDFS文件系统底层详解
· DN&NN工作机制
· HDFS的API操作
· MapRece框架原理
· 数据压缩
· Yarn工作机制
· MapRece案例详解
· Hadoop参数调优
· HDFS存储多目录
· 多磁盘数据均衡
· LZO压缩
· Hadoop基准测试
Zookeeper
· Zookeeper数据结果
· 内部原理
· 选举机制
· Stat结构体
· 监听器
· 分布式安装部署
· API操作
· 实战案例
· 面试真题
· 启动停止脚本
HA+新特性
· HDFS-HA集群配置
Hive
· Hive架构原理
· 安装部署
· 远程连接
· 常见命令及基本数据类型
· DML数据操作
· 查询语句
· Join&排序
· 分桶&函数
· 压缩&存储
· 企业级调优
· 实战案例
· 面试真题
Flume
· Flume架构
· Agent内部原理
· 事务
· 安装部署
· 实战案例
· 自定义Source
· 自定义Sink
· Ganglia监控
Kafka
· 消息队列
· Kafka架构
· 集群部署
· 命令行操作
· 工作流程分析
· 分区分配策略
· 数据写入流程
· 存储策略
· 高阶API
· 低级API
· 拦截器
· 监控
· 高可靠性存储
· 数据可靠性和持久性保证
· ISR机制
· Kafka压测
· 机器数量计算
· 分区数计算
· 启动停止脚本
DataX
· 安装
· 原理
· 数据一致性
· 空值处理
· LZO压缩处理
Scala
· Scala基础入门
· 函数式编程
· 数据结构
· 面向对象编程
· 模式匹配
· 高阶函数
· 特质
· 注解&类型参数
· 隐式转换
· 高级类型
· 案例实操
Spark Core
· 安装部署
· RDD概述
· 编程模型
· 持久化&检查点机制
· DAG
· 算子详解
· RDD编程进阶
· 累加器&广播变量
Spark SQL
· SparkSQL
· DataFrame
· DataSet
· 自定义UDF&UDAF函数
Spark Streaming
· SparkStreaming
· 背压机制原理
· Receiver和Direct模式原理
· Window原理及案例实操
· 7x24 不间断运行&性能考量
Spark内核&优化
· 内核源码详解
· 优化详解
Hbase
· Hbase原理及架构
· 数据读写流程
· API使用
· 与Hive和Sqoop集成
· 企业级调优
Presto
· Presto的安装部署
· 使用Presto执行数仓项目的即席查询模块
Ranger2.0
· 权限管理工具Ranger的安装和使用
Azkaban3.0
· 任务调度工具Azkaban3.0的安装部署
· 使用Azkaban进行项目任务调度,实现电话邮件报警
Kylin3.0
· Kylin的安装部署
· Kylin核心思想
· 使用Kylin对接数据源构建模型
Atlas2.0
· 元数据管理工具Atlas的安装部署
Zabbix
· 集群监控工具Zabbix的安装部署
DolphinScheler
· 任务调度工具DolphinScheler的安装部署
· 实现数仓项目任务的自动化调度、配置邮件报警
Superset
· 使用SuperSet对数仓项目的计算结果进行可视化展示
Echarts
· 使用Echarts对数仓项目的计算结果进行可视化展示
Redis
· Redis安装部署
· 五大数据类型
· 总体配置
· 持久化
· 事务
· 发布订阅
· 主从复制
Canal
· 使用Canal实时监控MySQL数据变化采集至实时项目
Flink
· 运行时架构
· 数据源Source
· Window API
· Water Mark
· 状态编程
· CEP复杂事件处理
Flink SQL
· Flink SQL和Table API详细解读
Flink 内核
· Flink内核源码讲解
· 经典面试题讲解
Git&GitHub
· 安装配置
· 本地库搭建
· 基本操作
· 工作流
· 集中式
ClickHouse
· ClickHouse的安装部署
· 读写机制
· 数据类型
· 执行引擎
DataV
· 使用DataV对实时项目需求计算结果进行可视化展示
sugar
· 结合Springboot对接网络sugar实现数据可视化大屏展示
Maxwell
· 使用Maxwell实时监控MySQL数据变化采集至实时项目
ElasticSearch
· ElasticSearch索引基本操作、案例实操
Kibana
· 通过Kibana配置可视化分析
Springboot
· 利用Springboot开发可视化接口程序
Ⅳ 如何在代码中提交Maprece作业
MapRece作业提交源码分析
我们在编写MapRece程序的时候,首先需要编写Map函数和Rece函数。完成mapper和recer的编写后,进行Job的配置;Job配置完成后,调用Job.submit()方法完成作业的提交。那我们思考一下,Job最终如何完成作业(job)的提交呢?粗略想一下,Job必然需要通过某种方式连接到JobTracker,因为只有这样才能将job提交到JobTracker上进行调度执行。还需要考虑一下,我们自己编写的mapper和recer,即Jar文件如何传送到JobTracker上呢?其中有一种最简单也比较直观的方法,直接通过socket传输给JobTracker,由JobTracker再传输给TaskTracker(注意:MapRece并没有采用这种方法)。第三个需要考虑的内容是,JobTracker如何将用户作业的配置转化成map task和rece task。下面我们来分析一下MapRece这些功能的实现。
首先在class Job内部通过JobClient完成作业的提交,最终由JobClient完成与JobTracker的交互功能。在JobClient的构造函数中,通过调用RPC完成与JobTracker连接的建立。
完成建立后,JobClient首先确定job相关文件的存放位置(我们上面提到maprece没有采用将jar即其他文件传输给JobTracker的方式,而是将这些文件保存到HDFS当中,并且可以根据用户的配置存放多份)。至于该存放目录的分配是通过调用RPC访问JobTracker的方法来进行分配的,下面看一下JobTracker的分配代码:
final Path stagingRootDir = new Path(conf.get(
"maprece.jobtracker.staging.root.dir",
"/tmp/Hadoop/mapred/staging"));
final FileSystem fs = stagingRootDir.getFileSystem(conf);
return fs.makeQualified(new Path(stagingRootDir, user + "/.staging")).toString();
注意上面代码所生成的stagingRootDir是所有job文件的存放目录,是一个根目录,并不单指当前job。
完成job存放目录的分配后,JobClient向JobTracker申请一个JobID(通过RPC,注意基本上JobClient与JobTracker的所有通信都是通过RPC完成的,如果下文没有显示着名也应该属于这种情况)。
JobID jobId = jobSubmitClient.getNewJobId();
下面是JobTracker.getNewJobId的具体实现:
publicsynchronized JobID getNewJobId() throws IOException {
returnnew JobID(getTrackerIdentifier(), nextJobId++);
}
获得JobID后,将该JobID与上面的stagingRootDir组合就构成了Job文件的具体存放地址的构建。进行这些相关工作后,JobClient将相关的文件存储到HDFS当中。