目录
1 . 简述下分布式和集群的区别
2. Hadoop的三大组件是什么?
3. 请简述hive元数据服务配置的三种模式?
4. 数据库与数据仓库的区别?
5. 简述下数据仓库经典三层架构?
6. 请简述内部表和外部表的区别?
7. 简述Hive的特点,以及Hive 和RDBMS有什么异同
8. hive中无update语法,如何进行数据更新
9. 简述下分区表和分桶表的区别
10. 说一下行转列,列转行用到的方法
11. 简述下行存储和列存储的区别
12. 简述下hive调优的手段
13 . 简述下HDFS写入原理
14. 简述下HDFS读取的原理
15. 简述MapReduce中MapTask的工作流程机制
16. 简述Yarn提交MapReduce任务流程
17. 简述Zookeeper的Watch监听机制
18. 简述下集群选举中用到的Zookeeper知识点以及对应选举流程
19 . 请简单描述HIve udf、udtf、udaf的区别
集群和分布式,都是描述的一组计算机。集群的所有节点跑的是同样的任务,集群本质是多台服务器联合起来独立做相同的任务(多个服务器分担客户端发来的请求) 。而分布式系统的节点跑的是分解后的任务,分布式本质是多台服务器协同配合完成同一个大任务(每个服务器都只完成大任务拆分出来的单独1个子任务)
以修手机为例:维修手机要分为检测、维修、测试三个环节,当多部手机都需要维修的时候,为了提高效率,雇了10位工程师。如果每个工程师维修时,对每台手机进行检测、维修和测试,这就是集群的工作方式。如果2位工程师负责检测,5位工程师负责维修,剩下的3位工程师负责测试,这就是分布式的工作方式。
首先hadoop技术栈由HDFS , MapReduce ,YARN三大组件组成
其次三大组件核心知识如下:
HDFS是(分布式文件系统),解决海量数据存储
元数据是描述核心数据的数据
NameNode是集群当中的主节点,主要用于管理集群当中的各种数据
SecondaryNameNode是主要能用于辅助NameNode进行文件块元数据存储
DataNode是集群当中的从节点,主要用于存储真实的海量的业务数据
YARN是(作业调度和集群资源管理的框架),解决资源任务调度
ResourceManager是接收用户的计算请求任务,并负责集群的资源管理和分配
NodeManager是 负责执行主节点分配的任务(给MR的计算程序提供资源)
MapReduce是(分布式运算编程框架),解决海量数据计算
核心思想就是分而治之 Map负责分解,Reduce负责合并
最后概括下MapReduce计算需要的数据和产生的结果需要HDFS来进行存储,MapReduce的运行需要由Yarn集群来提供资源调度。
内嵌模式:
优点: 配置简单 hive命令直接可以使用
缺点: 不适用于生产环境,derby和Metastore服务都嵌入在主Hive Server进程中,一个服务只能被一个客户端连接(如果用两个客户端以上就非常浪费资源),且元数据不能共享
本地模式:
优点:可以单独使用外部的数据库(mysql),元数据共享
缺点:相对浪费资源,metastore嵌入到了hive进程中,每启动一次hive服务,都内置启动了一个metastore。
远程模式:
优点:可以单独使用外部库(mysql),可以共享元数据,本地可以连接metastore服务也可以连接hiveserver2服务,增加了扩展性(其他依赖hive的软件都可以通过Metastore访问hive)
缺点:需要注意的是如果想要启动hiveserver2服务需要先启动metastore服务
数据仓库与数据库的区别:实际讲的是OLTP与OLAP的区别,OLTP(On-Line Transaction Processin):叫联机事务处理,也可以称面向用户交易的处理系统,主要面向用户进行增删改查,OLAP(On-Line Analytical Processing):叫联机分析处理,一般针对某些主题的历史数据进行分析 主要面向分析,支持管理决策。
数据仓库的出现,并不是要取代数据库,主要区别如下:数据库是面向事务的设计,数据仓库是面向主题设计的。数据库是为捕获数据而设计,数据仓库是为分析数据而设计.数据库一般存储业务数据,数据仓库存储的一般是历史数据。数据库设计是尽量避免冗余,一般针对某一业务应用进行设计,比如一张简单的User表,记录用户名、密码等简单数据即可,符合业务应用,但是不符合分析。数据仓库在设计是有意引入冗余,依照分析需求,分析维度、分析指标进行设计。
数据仓库是一个面向主题的、集成的、持久的(非易失的)、反映历史变化(随时间变化),用来支持管理人员决策的数据集合,按照数据流入流出的过程,数据仓库架构可分为三层——源数据层、数据仓库层、数据应用层。
源数据层(ODS-Operational Data Store):此层数据无任何更改,直接沿用外围系统数据结构和数据,不对外开放;为临时存储层,是接口数据的临时存储区域,为后一步的数据处理做准备。
数据仓库层(DW-Data Warehouse):也称为细节层,DW层的数据应该是一致的、准确的、干净的数据,即对源系统数据进行了清洗(去除了杂质)后的数据。
数据应用层(DA-Data Application):前端应用直接读取的数据源;根据报表、专题分析需求而计算生成的数据。
内部表:
内部表类型: MANAGED_TABLE
未被external关键字修饰的即是内部表, 即普通表。 内部表又称管理表,还可以叫托管表
删除内部表:直接删除元数据(metadata)和存储数据本身
外部表:
外部表类型: EXTERNAL_TABLE
被external关键字修饰的即是外部表, 即关联表。 还可以叫非管理表或非托管表
删除外部表:仅仅是删除元数据(metadata),不会删除存储数据本身
hive是数据仓库处理工具 , rdbms是关系型数据库语言,Relational Database Management System:RDBMS
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的sql
查询功能,可以将sql语句转换为MapReduce任务进行运行。其优点是学习成本低,可以通过类SQL语句快速实现
简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析,但是Hive不支持实时
查询。
可以使用INSERT OVERWRITE语句来实现数据更新的效果。具体步骤如下:
分区表
创建表的时候使用关键字: partition by (分区字段名 分区字段类型)
分区字段名注意事项: 是一个新的字段,需要指定类型,且不能和其他字段重名
分区表好处: 使用分区字段作为条件的时候,底层直接找到对应的分区目录,能够避免全表扫描,提升查询效率
分区表最直接的效果: 在hfds表目录下,分成多个分区目录(year=xxxx,month=xx,day=xx)
不建议直接上传文件在hdfs表根路径下: 分区表直接不能识别对应文件中数据,因为分区表会找分区目录下的数据文件
使用load方式加载hdfs中文件: 本质是移动文件到对应分区目录下
分桶表
创建表的时候使用关键字: clustered by (分桶字段名) into 桶数量 buckets
分桶字段名注意事项: 是指定一个已存在的字段,不需要指定类型
分桶表好处: 使用分桶字段做抽样等特定操作的时候,也能提升性能效率
分桶表最直接的效果: 在hdfs表目录或者分区目录下,分成多个分桶文件(000000_0,000001_0,000002_0...)
不建议直接上传文件在hdfs表根路径下: 分桶表可以识别对应文件中数据,但是并没有分桶效果,也是不建议的
使用load方式加载hdfs中文件: 本质是复制数据到各个分桶文件中
行转列,collet_list , 有序并且重复 ,collet_set 是 无序并且去重,concat_ws进行字符串拼接, cast函数进行字符串转换
列转行 ,replace,split把内容一个个切割,再使用expole炸裂函数,并给炸裂后的列起别名;使用LATERAL VIEW创建出虚拟表
最后select 后的字段带上虚拟表.炸裂后的列名
行存储的特点: 查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
列存储的特点: 因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。
行存储: textfile和squencefile
优点: 每行数据连续存储 select * from 表名; 查询速度相对较快
缺点: 每列类型不一致,空间利用率不高 select 列名 from 表名; 查询速度相对较慢
列存储: orc和parquet
优点: 每列数据连续存储 select 列名 from 表名; 查询速度相对较快
缺点: 因为每行数据不是连续存储 select * from 表名;查询速度相对较慢
注意: ORC文件格式的数据, 默认内置一种压缩算法:zlib , 在实际生产中一般会将ORC压缩算法替换为 snappy使用,格式为: STORED AS orc tblproperties ("orc.compress"="SNAPPY")
Hive数据压缩
Hive数据存储格式
fetch抓取策略
本地模式
join优化操作
SQL优化(列裁剪,分区裁剪,map端聚合,count(distinct),笛卡尔积)
动态分区
MapReduce并行度调整
并行执行严格模式
JVM重用
推测执行
执行计划explain
1.客户端发起写入数据的请求给namenode
2.namenode接收到客户端请求,开始校验(是否有权限,路径是否存在,文件是否存在等),如果校验没问题,就告知客户端可以写入
3.客户端收到消息,开始把文件数据分割成默认的128m大小的的block块,并且把block块数据拆分成64kb的packet数据包,放入传输序列
4.客户端携带block块信息再次向namenode发送请求,获取能够存储block块数据的datanode列表
5.namenode查看当前距离上传位置较近且不忙的datanode,放入列表中返回给客户端
6.客户端连接datanode,开始发送packet数据包,第一个datanode接收完后就给客户端ack应答(客户端就可以传入下一个packet数据包),同时第一个datanode开始复制刚才接收到的数据包给node2,node2接收到数据包也复制给node3(复制成功也需要返回ack应答),最终建立了pipeline传输通道以及ack应答通道
7.其他packet数据根据第一个packet数据包经过的传输通道和应答通道,循环传入packet,直到当前block块数据传输完成(存储了block信息的datanode需要把已经存储的块信息定期的同步给namenode)
8.其他block块数据存储,循环执行上述4-7步,直到所有block块传输完成,意味着文件数据被写入成功(namenode把该文件的元数据保存上)
9.最后客户端和namenode互相确认文件数据已经保存完成(也会汇报不能使用的datanode)
1.客户端发送读取文件请求给namenode
2.namdnode接收到请求,然后进行一系列校验(路径是否存在,文件是否存在,是否有权限等),如果没有问题,就告知可以读取
3.客户端需要再次和namenode确认当前文件在哪些datanode中存储
4.namenode查看当前距离下载位置较近且不忙的datanode,放入列表中返回给客户端
5.客户端找到最近的datanode开始读取文件对应的block块信息(每次传输是以64kb的packet数据包),放到内存缓冲区中
6.接着读取其他block块信息,循环上述3-5步,直到所有block块读取完毕(根据块编号拼接成完整数据)
7.最后从内存缓冲区把数据通过流写入到目标文件中
8.最后客户端和namenode互相确认文件数据已经读取完成(也会汇报不能使用的datanode)
1) 第一阶段是把输入目录下文件按照一定的标准逐个进行逻辑切片,形成切片规划,默认情况下Split size 等于 Block size。每一个切片由一个MapTask处理(当然也可以通过参数单独修改split大小)
2) 第二阶段是对切片中的数据按照一定的规则解析成对。默认规则是把每一行文本内容解析成键值对。key是每一行的起始位置(单位是字节),value是本行的文本内容。
3) 第三阶段是调用Mapper类中的map方法。上阶段中每解析出来的一个,调用一次map方法。每次调用map方法会输出零个或多个键值对
4) 第四阶段是按照一定的规则对第三阶段输出的键值对进行分区。默认是只有一个区。分区的数量就是Reducer任务运行的数量。默认只有一个Reducer任务
5) 第五阶段是对每个分区中的键值对进行排序。首先,按照键进行排序,对于键相同的键值对,按照值进行排序。比如三个键值对<2,2>、<1,3>、<2,1>,键和值分别是整数。那么排序后的结果是<1,3>、<2,1>、<2,2>。如果有第六阶段,那么进入第六阶段;如果没有,直接输出到文件中
6) 第六阶段是对数据进行局部聚合处理,也就是combiner处理。键相等的键值对会调用一次reduce方法。经过这一阶段,数据量会减少。本阶段默认是没有的。
1.客户端提交一个MR程序给ResourceManager(校验请求是否合法...)
2.如果请求合法,ResourceManager随机选择一个NodeManager用于生成appmaster(应用程序控制者,每个应用程序都单独有一个appmaster)
3.appmaster会主动向ResourceManager的应用管理器(application manager)注册自己,告知自己的状态信息,并且保持心跳
4.appmaster会根据任务情况计算自己所需要的container资源(cpu,内存...),主动向ResourceManager的资源调度器(resource scheduler)申请并获取这些container资源
5.appmaster获取到container资源后,把对应指令和container分发给其他NodeManager,让NodeManager启动task任务(maptask任务,reducetask任务)
6.NodeManager要和appmaster保持心跳,把自己任务计算进度和状态信息等同步给appmaster,(注意当maptask任务完成后会通知appmaster,appmaster接到消息后会通知reducetask去maptask那儿拉取数据)直到最后任务完成
7.appmaster会主动向ResourceManager注销自己(告知ResourceManager可以把自己的资源进行回收了,回收后自己就销毁了)
watch监听机制过程: 客户端向服务端注册Watcher 服务端事件发生触发Watcher 客户端回调Watcher得到触发事件情况
Watch监听机制注册格式: get /节点绝对路径 watch
Watch监听机制特点:
先注册再触发: Zookeeper中的watch机制,必须客户端先去服务端注册监听,这样事件发送才会触发监听,通知给客户端
一次性触发: 事件发生触发监听,一个watcher event就会被发送到设置监听的客户端,这种效果是一次性的,后续再次发生同样的事件,不会再次触发。
异步发送: watcher的通知事件从服务端发送到客户端是异步的。
通知内容: 通知状态(keeperState),事件类型(EventType)和节点路径(path)
在分布式环境下,不管是主从架构集群,还是主备架构集群,要求在服务的时候有且有一个正常的对外提供服务,我们称之为master。
当master出现故障之后,需要重新选举出的新的master。保证服务的连续可用性。zookeeper可以提供这样的功能服务。
主要用到知识点: znode唯一性、临时节点短暂性、监听机制。
选举要求: 过半原则,所以搭建集群一般奇数,只要某个node节点票数过半立刻成为leader
集群第一次启动: 启动follower每次投票后,他们会相互同步投票情况,如果票数相同,谁的myid大,谁就当选leader,一旦确定了leader,后面来的默认就是follower,即使它的myid大,leader也不会改变(除非leader宕机了)
leader宕机后启动: 每一个leader当老大的时候,都会产生新纪元epoch,且每次操作完节点数据都会更新事务id(高32位_低32位) ,当leader宕机后,剩下的follower就会综合考虑几个因素选出最新的leader,先比较最后一次更新数据事务id(高32位_低32位),谁的事务id最大,谁就当选leader,如果更新数据的事务id都相同的情况下,就需要再次考虑myid,谁的myid大,谁就当选leader
UDF:(User-Defined-Function)普通函数: 特点是一进一出(输入一行数据输出一行数据) 举例: split
UDAF:(User-Defined Aggregation Function)聚合函数: 特点是多进一出(输入多行输出一行) 举例: count sum max min avg
UDTF:(User-Defined Table-Generating Functions)表生成函数: 特点是一进多出(输入一行输出多行) 举例: explode