Hadoop
仅完善了Yarn、Hive、kettle部分,其余待完善
HDFS
设计思想
优缺点
NameNode
DataNode
SecondaryNameNode
hdfs的读写流程
NameNode和snn的工作机制
可靠性策略
块的副本放置策略
checkPoint
动态增删节点
离开安全模式
Yarn
ResourceManager
-
职责
- 1、资源调度
- 2、资源监视
- 3、Application提交
-
组件
-
Scheduler
- 提交到集群的应用程序分配资源
-
ApplicationsManager
- 用于管理整个集群应用的ApplicationMaster
- 负责接收用用程序的提交
- 为AM的启动提供资源
- 监控程序进度及状态,维护程序故障
-
NodeManager
- 1、主要做节点上的资源管理
- 2、启动Container运行Task计算
- 3、上报资源、Container情况给RM,上报任务处理情况给AM
ApplicationMaster
- 应用程序级别,管理在YARN上的应用程序
- 负责与RM Scheduler协商资源,与NodeManager通信运行相应的task
Container
- 包含了内存、CPU、磁盘等逻辑资源
流程图
MapReduce
Job
- 代表用户的一个计算请求,也称作业;下分Task
Task
-
由Job拆分而来,作业分为多个阶段,交由多个主机来完成、拆分出来的执行单位就是Task
-
分类
-
MapTask
- 负责map阶段的数据处理流程
-
ReduceTask
- 负责Reduce阶段的数据处理流程
-
AppMaster
- 负责整个程序的过程调度以及状态协调
-
编写MR程序
- 1、程序一般分三个部分:Mapper、Reducer、Driver
- 2、Mapper程序的输入数据是KV类型,输出数据为KV类型
- 3、Mapper类中的业务逻辑要写在map( )方法中,map()方法的调用是对每一个KV进行的
- 4、Reducer的输入输出类型是KV类型
- 5、Mapper的输出数据输入到Reducer
- 6、Reducer的业务逻辑写在reduce()方法中
- 7、程序的提交通过Driver类,提交的是一个描述了各种必要信息的Job对象
shuffle
-
Map端的shuffle
-
spill过程
-
输出Collect
每个Map任务不断地以对的形式把数据输出到在内存中构造的一个环形数据结构中。使用环形数据结构是为了更有效地使用内存空间,在内存中放置尽可能多的数据。
Kvbuffer的大小虽然可以通过参数设置,但是总共就那么大,和索引不断地增加,加着加着,Kvbuffer总有不够用的那天,那怎么办?把数据从内存刷到磁盘上再接着往内存写数据,把Kvbuffer中的数据刷到磁盘上的过程就叫Spill,多么明了的叫法,内存中的数据满了就自动地spill到具有更大空间的磁盘。
关于Spill触发的条件,也就是Kvbuffer用到什么程度开始Spill,还是要讲究一下的。如果把Kvbuffer用得死死得,一点缝都不剩的时候再开始Spill,那Map任务就需要等Spill完成腾出空间之后才能继续写数据;如果Kvbuffer只是满到一定程度,比如80%的时候就开始Spill,那在Spill的同时,Map任务还能继续写数据,如果Spill够快,Map可能都不需要为空闲空间而发愁。两利相衡取其大,一般选择后者。
Spill这个重要的过程是由Spill线程承担,Spill线程从Map任务接到“命令”之后就开始正式干活,干的活叫SortAndSpill,原来不仅仅是Spill,在Spill之前还有个颇具争议性的Sort。 -
排序sort
先把Kvbuffer中的数据按照partition值和key两个关键字升序排序,移动的只是索引数据,排序结果是Kvmeta中数据按照partition为单位聚集在一起,同一partition内的按照key有序。
-
溢写spill
Spill线程为这次Spill过程创建一个磁盘文件:从所有的本地目录中轮训查找能存储这么大空间的目录,找到之后在其中创建一个类似于“spill12.out”的文件。Spill线程根据排过序的Kvmeta挨个partition的把数据吐到这个文件中,一个partition对应的数据吐完之后顺序地吐下个partition,直到把所有的partition遍历完。一个partition在文件中对应的数据也叫段(segment)。
-
合并merge
从所有的本地目录上扫描得到Index文件,然后把索引信息存储在一个列表里。然后为merge过程创建一个叫file.out的文件和一个叫file.out.Index的文件用来存储最终的输出和索引。
一个partition一个partition的进行合并输出。对于某个partition来说,从索引列表中查询这个partition对应的所有索引信息,每个对应一个段插入到段列表中。也就是这个partition对应一个段列表,记录所有的Spill文件中对应的这个partition那段数据的文件名、起始位置、长度等等。
然后对这个partition对应的所有的segment进行合并,目标是合并成一个segment。当这个partition对应很多个segment时,会分批地进行合并:先从segment列表中把第一批取出来,以key为关键字放置成最小堆,然后从最小堆中每次取出最小的输出到一个临时文件中,这样就把这一批段合并成一个临时的段,把它加回到segment列表中;再从segment列表中把第二批取出来合并输出到一个临时segment,把其加入到列表中;这样往复执行,直到剩下的段是一批,输出到最终的文件中。 -
流程图
-
-
-
Reduce端的shuffle
-
copy过程
Reduce任务通过HTTP向各个Map任务拖取它所需要的数据。每个节点都会启动一个常驻的HTTP server,其中一项服务就是响应Reduce拖取Map数据。当有MapOutput的HTTP请求过来的时候,HTTP server就读取相应的Map输出文件中对应这个Reduce部分的数据通过网络流输出给Reduce。
-
sort过程
这里使用的Merge和Map端使用的Merge过程一样。Map的输出数据已经是有序的,Merge进行一次合并排序,所谓Reduce端的sort过程就是这个合并的过程。一般Reduce是一边copy一边sort,即copy和sort两个阶段是重叠而不是完全分开的。
Reduce端的Shuffle过程至此结束
-
-
流程图
Job的提交流程
- 1、客户机向RM申请运行一个MR的Job
- 2、RM返回一个Job Id,提交资源用的HDFS路径 hdfs://XXX/tmp/hadoop-yarn…
- 3、提交程序所需的资源文件到hdfs指定的目录下,包括:
job.jar
job.spilt
job.conf… - 4、资源提交完成
- 5、MR初始化任务Task,将任务放在任务队列中
- 6、NodeManager从MR处领取到任务
- 7、NodeManager初始化资源容器(包含CPU、ram、disk…)
- 8、启动MrAppMaster
- 9、MrAppMaster向RM申请资源运行MapTask
- 10、RM创建任务加入队列
- 11、领取到任务,创建资源容器,启动maptask
- 12、申请资源启动ReduceTask
- 13、reducetask拉去属于自己分区的数据,有一个MapTask执行完成,ReduceTask就可以启动拉取数据
- 15、通知RM,任务完成,注销自己,释放资源
Task任务分配过程
MR运行全流程
- 1、对HDFS文件系统存储的文件进行分片,分片的信息包括文件的路径,分片起始位置,分片的大小,分片数据所在的块的信息,块所在的主机列表
- 2、启动MapTask,实例数量由分片的数量决定
- 3、每读一行数据就会调用一次createRecordReader,返回键值对类型数据
- 4、一个键值对调一次map(k,v,context)方法,然后将数据交由MapTask写回到磁盘
- 5、数据的分发按照k的hash值%redece数量
- 6、reduce的数量
job.setNumReduceTask(5); - 7、reduce保存数据到本地磁盘,按照key相同分组
- 8、分组读取数据,一组数据调用一次reduce方法,reduce(k,迭代器v,context)
- 9、reduce执行完之后将数据交由OutPutFormat组件去写
分片的细节
-
分片是一种逻辑概念,分片信息包括起始偏移量,分片大小,分片数据所在快的信息,块所在的主机列表。每一个分片对应这样一个MapTask,通过调整分片的大小可以调整MapTask的数量,即调整Map阶段的并行度
-
分片的读取规则
- 1、第一个分片冲第一行开始读取,读到分片末尾,再读取下一个分片的第一行
- 2、中间的分片第一行数据舍去,读到分片的末尾多读一行
- 3、最后一个分片舍去第一行,读到分片末尾
-
分片大小的设置
- 1、FileInPutFormat.setMinInputSplitSize(job,1000);
- 2、FileInPutFormat.setMaxInputSplitSize(job,1000000);
GroupingComparetor的机制原理
Combiner组件
-
简介
- 相当于一个Reduce,在Map端后,可以大大减少IO
MapTask和ReduceTask数量的控制
MR中可干预的组件
-
1、combiner
-
2、partition:分区,解决数据倾斜
自定义分区:继承Partitioner类,重写getPartition()分区的方法,可以解决数据倾斜问题
-
3、group:分组
继承WritableComparetor类,重写conpare()方法,自定义分组,定义reduce输入的数据分组规则
-
4、sort:排序
继承WritableComparetor类,重写conpare()方法,根据自定义的排序方法,将reduce的输出结果进行排序
-
5、分片,调整客户端的设置,包括:
blocksize
minsize
maxsize
HA高可用
ZooKeeper
应用场景
- 节点的动态上下线
- 高可用的配置
- 主从选举,解决单点故障
- 统一配置管理
分布式锁的实现原理
服务器动态上下线感知
主从协调
配置管理
选举机制
特性
Flume
Flume的架构
如何保证数据完整性
Sqoop
HBase
简介
特点
应用场景
HBase的架构
HBase的关键字
HBase与Hadoop的关系
HBase的安装
Java API
HBase的四大比较器
HBase与MR的整合
HBase与Hive的整合
HBase的高级特性
Hive
简介
- 基于hadoop的数据仓库,可以通过类SQL语句来对数据进行读写管理
特点
架构
-
用户连接的客户端
- cli
- jdbc/odbc
- web UI
-
meatastroe
- 存储hive的元数据(包括:库、表、字段、数据类型、分区、分桶、创建时间、创建人)
-
解释器
- 将HQL语句抽象成表达式树
-
编译器
- 对HQL语句进行语法、词法、语言的编译(需要关联元数据进行查找),编译后会生成一个有向无环的执行计划
-
优化器
- 将执行计划进行优化,减少一些不必要的列、使用分区等
-
执行器
- 将优化好的执行计划提交给Hadoop的mapredce框架去执行
Hive与Hadoop的关系
- hive是基于Hadoop的
- hive本身没有存储和分析功能,它相当于Hadoop基础上的封装
Hive的安装
- 本地模式
- 远程模式(本地元数据)
- 远程模式(远程元数据)
Hive的使用
-
hive的数据库名、表名不区分大小写
-
创建库的本质
- 在hive的数据仓库目录(/user/hive/warehouse/)下创建了一个子目录(库名.db)
-
创建表的本质
- 在数据库的目录下创建了一个表目录
-
加载数据的本质
- 将数据文件copy(不完全是)到表目录下
- 若是本地文件加载则是copy
- hdfs上的文件加载是移动
Hive的命名规则
- 不能数字开头
- 不能用关键字
- 不用特殊字符
Hive表的类型
-
内部表
- 表目录会创建在相应的数据库目录下
- drop时会将元数据清除,表目录删除
-
外部表
- 根据建表时location关键字指定的路径创建表目录,未指定将创建到数据库目录下
- drop时删除元数据,表结构不会被删除
Hive的DLL操作
分区表
-
分区的意义
- hive通常为全表扫描,表的数据量越来越大会导致不必要的数据扫描降低查询效率
- 分区的技术避免了hive的全表扫描,提升查询的效率
- 可以让用户在做数据分析统计时缩小数据扫描的范围,可以在select里指定要统计的分区
-
与mysql分区的区别
- hive分区使用的是表外字段
- MySQL分区使用的是表内字段
-
分区的技术
- hive的分区名区分大小写
- hive的分区的本质是在表目录下创建子目录,但是该分区字段是一个伪列,不真实存在于数据中
- 一张表可以有一个或多个分区,分区下可另设分区
-
分区类型
-
静态分区
- 加载数据时指定分区的值
-
动态分区
- 数据未知,根据分区的值确定创建分区
-
混合分区
- 静态和动态的都有
-
-
注意事项
- hive的分区使用表外字段,分区字段是一个伪列但是可以做select查询时的过滤
- 分区字段不建议使用中文
- 不建议使用动态分区,,动态分区将会使用MR来查询数据,如果分区数过多,将导致NameNode和Yarn的性能瓶颈,建议动态分区前尽可能的预知分区的数量
- 分区属性修改可以使用手动元数据+hdfs数据目录
分桶表
-
分桶的意义
- 单个分区或者表的数据量越来越大,不能细度划分数据时,采用分桶技术细分数据和管理数据
- 为了保存分桶查询结果的分桶结构(数据已经按照分桶字段进行hash散列)
- 分桶表数据进行抽样和join是可以提高MR的查询效率
-
分桶的技术
-
分桶关键字
-
分桶总结
自定义函数
Hive的高级查询
复杂数据类型
kettle
安装和启动
-
常见问题
-
点击spon.bat无反应
- 1、Java的环境
- 2、Java的版本
- 3、缺少环境变量
-
mysql缺少驱动包
- 导包到lib文件夹
-
-
安装
- 解压
- 添加环境变量
- 修改spoon.bat
元数据的管理
- 资源库
- 关系型数据库管理元数据,如MySQL
- 文件系统管理元数据
增量导入数据
- 1、触发器:用一个临时表记录数据的增删改的变化情况
- 2、通过时间戳:数据表中包含时间戳字段,还得有个记录时间范围的中间表
设置Kettle的任务
- 更新结束时间
- 从表中读取数据,加时间戳条件,将数据输出到文本文件
- 同步完毕,更新times表
使用时间戳的原理
假设A表是业务表,times是记录时间范围的表
1、times表的原始记录(T0,T0),开始同步,更新数据为(T0,NOW)
2、取出A表中的时间在times的时间范围内的数据where A.lastupdate >= T0 and A.lastupdate < NOW
3、同步完成,更新times表(NOW,NOW)
4、重复上述步骤