数据--题库

文章目录

数据–题库

一、hdfs

1.1 hdfs机构体系

hdf由namenode(Active)、namenode(Standby)、datanode组成。
	1、NameNode负责管理和记录整个文件系统的元数据
	2、DataNode 负责管理用户的文件数据块,文件会按照固定的大小(blocksize)切成若干块后分布式存储在若干台datanode上 每一个文件块可以有多个副本,并存放在不同的datanode上 , Datanode会定期向Namenode汇报自身所保存的文件block信息,而namenode则会负责保持文件的副本数量
	3、HDFS的内部工作机制对客户端保持透明,客户端请求访问HDFS都是通过向namenode申请来进行
	4、namenode(Standby)负责合并日志

在这里插入图片描述

1.2 hdfs写文件的步骤

	(1)client向NameNode申请上传…/xxx.txt文件
	(2)NN向client响应可以上传文件
	(3)Client向NameNode申请DataNode
	(4)NN向Client返回DN1,DN2,DN3
	(5)Client向DN1,DN2,DN3申请建立文件传输通道
	(6)DN3,DN2,DN1依次响应连接
	(7)Client向DN1上传一个block,DN1向DN2,DN3冗余文件

在这里插入图片描述

1.3 hdfs读取文件

	(1)client向NN请求下载…/xxx.txt文件
	(2)NN向client返回文件的元数据
	(3)Client向DN1请求访问读数据blk_1
	(4)DN1向Client传输数据
	(5)Client向DN2请求访问读数据blk_2
	(6)DN2向Client传输数据

在这里插入图片描述

1.4 fsimage和edit的区别

	FSimage(文件系统镜像)类似快照,记录某一个时刻前(Cheakpiont)NameNode内存中数据的镜像保存最新的元数据的信息。
    Editslog(可编辑日志)存保存点(Cheakpiont)之后所有的写操作

    cheakpiont 生成的时间
	(1)、格式化 HDFS 时 ,生成一个空的 FSImage镜像
	(2)、每一次 启动集群时  HDFS 会把  editslog是的数据整合 到 FSImage中,并将新的写命令 写入新的editslog中

1.5 一个datanode 宕机,怎么一个流程恢复

Datanode宕机了后:
	如果是短暂的宕机,可以实现写好脚本监控,将它启动起来。
	如果是长时间宕机了,那么datanode上的数据应该已经被备份到其他机器了,那这台datanode就是
一台新的datanode了,删除他的所有数据文件和状态文件,重新启动。

1.6 hadoop 的 namenode 宕机,怎么解决

	先分析宕机后的损失,宕机后直接导致client无法访问,内存中的元数据丢失,但是硬盘中的元数据应该还存在:
	如果只是节点挂了,重启即可,
	如果是机器挂了,重启机器后看节点是否能重启,不能重启就要找到原因修复了。但是最终的解决方案应该是在设计集群的初期就考虑到这个问题,做namenode的HA。

1.7 namenode对元数据的管理

namenode对数据的管理采用了三种存储形式:
	内存元数据(NameSystem)
	磁盘元数据镜像文件(fsimage镜像)
	数据操作日志文件(可通过日志运算出元数据)(edit日志文件)

1.8 元数据的checkpoint

  每隔一段时间,会由secondary namenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge(这个过程称为checkpoint)
   namenode和secondary namenode的工作目录存储结构完全相同,所以,当namenode故障退出需要重新恢复时,可以从secondary namenode的工作目录中将fsimage拷贝到namenode的工作目录,以恢复namenode的元数据

二 mapReduce

2.1 mapReduce计算框架体系

hdfs访问地址: http://hadoop12.sxyh.com:50070
yarn访问地址: http://hadoop12.sxyh.com:8088
	监控资源,监控任务。	

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

2.2 mapReduce执行过程

	Map阶段, 将每行的数据经过切分后, 得到<key, value>, 每个切分出的单词为key, 1为value.
Mapper对获得的键值对按key进行排序.
	Reduce阶段, 经过Shuffle整合Mapping阶段输出的相关记录, 汇总整合Shuffle阶段的值
并返回单个输出.

    提交集群运行:[XXX:root] bin/yarn -jar hadoop-mr-xxyh.jar
	如果MapReduce中,只是对数据进行清洗,而不负责统计,去重的话,就没有Reduce.

在这里插入图片描述

2.4 MapReduce中有多少个Map?

	Map的数量由block决定

2.3 MapReduce中有多少个Reduce?

一个reduce就是一个分区:

Reduce个数可以设置,默认情况 reduce的个数是 1.
	1. 为什么要设置多个Reduce?
	   提高MR的运行效率
	2. 多个Reduce的输出结果是多个文件,可以再次进行Map的处理,进行汇总.
	3. Partion分区
	   由分区决定Map输出结果,交给那个Reduce处理。默认有HashPartitioner实现
	   k2.hashCode()%reduceNum(2) = 0,1 

2.5 hadoop的shuffle过程

	(1)从maptask中收集我们的map方法输出的kv数据对,放到内存缓冲区中
	(2)从内存缓冲区不断溢出本地磁盘文件,但是由于内存缓冲区的大小,可能会多次溢出,也就会溢出多个文件。
	(3)多个溢出文件会被合并成大的溢出文件。
	(4)在溢出过程和合并过程中,都要调用Partitioner进行分区和针对key进行排序。
	(5)ReduceTask根据自己的分区号,去各个maptask机器上取得相对应的结果分区数据
	(6)reducetask会取到同一个分区的来自不同的maptask的结果文件,reducetask会将这些文件进行合并,也就是归纳排序。
	(7)合并成大文件之后,shuffle的过程结束,然后进入reducetask的逻辑运算过程。也就是从文件中取出一个个键值对,调用用户自定义的reduce方法。reducetask这里的数据是key排序完成之后的数据。

在这里插入图片描述

2.6 yarn资源调度流程

在这里插入图片描述

  • 1、用户向 Yarn 中提交应用程序。
  • 2、ResourceManager 为该程序分配第一个 Container ,并与对应的 NodeManager 通讯,要求它在这个Container 中启动应用程序 AppMaster。
  • 3、AppMaster 首先向 ResourceManager 注册,这样用户可以直接通过 RescourceManager 查看应用程序的运行状态,然后将为各个应用申请资源,并监控它的运行状态,直到运行结束,重复 4 到 7 的步骤。
  • 4、AppMaster 向 ResourceManager 申请和领取资源。
  • 5、一旦 AppMaster 申请到资源后,便与对应的NodeManager 通讯,要求它启动任务。
  • 6、NodeManager 为应用设置好运行环境(包括环境变量,Jar包,二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务。
  • 7、各个应用通过某个 RPC 协议向 AppMaster 汇报自己的状态和进度,以让 RAppMaster 随时掌握各个任务的运行状态,从而可以在任务失败的时候重新启动任务。
  • 8、应用程序运行完成后,MRAppMaster 向 ResourceManager 注销并关闭自己。

在这里插入图片描述

2.6.1 ResourceManager
  负责协调和管理整个集群(所有 NodeManager)的资源.
  由两个部分组件:
    调度器(Scheduler)
    应用程序管理器(ApplicationsManager,ASM)
作用:
   1、处理客户端请求
   2、启动或监控 MRAppMaster
   3、监控 NodeManager
   4、资源的分配与调度
    
  ResourceManager 
   会为每一个Application 启动一个MRAppMaster,
   并且MRAppMaster 分散在各个NodeManager节点
2.6.2 Scheduler
  • 调度器根据应用程序的资源需求进行资源分配,不参与应用程序具体的执行和监控等工作
  • 资源分配的单位就是Container,调度器是一个可插拔的组件,用户可以根据自己的需求实现自己的调度器。
  • Yarn本身为我们提供了多种直接可用的调度器,FIFO,Fair,Scheduler 和 Capacity Scheduler 等
2.6.3 ApplicationsManager(Resource节点)
应用程序管理器:
	负责管理整个系统中所有应用程序。
	包括应用程序提交。
	与调度器(Scheduler)协商资源,以启动MRAppMaster。
	监控MRAppmaster 运行状态并在失败时重新启动它,等等
2.6.4 NodeManager
NodeManager:
  是 Yarn 集群当中真正资源的提供者.
  是真正执行应用程序的容器的提供者,监控应用程序的资源使用情况(CPU,内存,硬盘,网络),
  通过心跳向集群资源调度器 ResourceManager 进行汇报以更新自己的健康状态.

 1、管理单个节点上的资源
 2、处理来自 ResourceManager 的命令
 3、处理来自 MRAppMaster 的命令

2.6.5 Container(存在NodeDate节点)
包括了该节点上的一定量CPU,内存,磁盘,网络等信息.
MapReduce 程序的所有 Task 都是在一个容器里执行完成的,容器的大小是可以动态调整的。
2.6.6 AppMaster(存在NodeDate节点)
MRAppMaster对应一个应用程序.
职责是:
   向资源调度器申请执行任务的资源容器,
   运行任务,监控整个任务的执行,跟踪整个任务的状态.
   处理任务失败及异常情况.

三、hive

3.1 主要架构及解析成MR的过程

Hive通过给用户提供一系列交互接口,接收到用户的指令(sql语句),结合元数据(metastore),经过Driver内的解析器,编译器,优化器,执行器转换成mapreduce(将sql转换成抽象语法树AST的解析器,将AST编译成逻辑执行计划的编译器,在对逻辑执行计划进行优化的优化器,最后将逻辑执行计划转换成mapreduce),提交给hadoop中执行,最后将执行返回的结果输出到用户交互接口。

3.1 hive中存放的是什么?

表:
	存的是和hdfs的映射关系
	hive是逻辑上的数据仓库
	实际操作的都是hdfs上的文件
	HQL就是用SQL语法来写的MR程序。

3.2 hive中Sort By、Order By、Cluster By,Distribute By各代表什么意思

order by:
	会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)。
	只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。
	
sort by:
	不是全局排序,其在数据进入reducer前完成排序。
	
distribute by:
	按照指定的字段对数据进行划分输出到不同的reduce中。
	
cluster by:
	除了具有 distribute by 的功能外还兼具 sort by 的功能。

3.3 管理表和外部表的区别

	drop table t_users_as;
	   删除管理表时,直接删除metastore,同时删除hdfs的目录和数据文件
	drop table t_user_ex; 
	   删除外部表时,删除metastore的数据。

3.4 hive调优

3.4.1 小文件会造成资源的多度占用
问题:
	小文件在HDFS中存储本身就会占用过多的内存空间。
	会造成启动过多的Mapper Task, 每个Mapper都是一个后台线程,会占用JVM的空间。
	动态分区会造成在插入数据过程中,生成过多零碎的小文件
   不合理的Reducer Task数量的设置也会造成小文件的生成

解决方案:
	1、做好数据的校验工作,比如通过脚本方式检测hive表的文件数量,并进行文件合并。
	2、合并多个文件数据到一个文件中,重新构建表。
	3、减少reduce的数量。
	4、采用Sequencefile作为表存储格式,不要用textfile,在一定程度上可以减少小文件
	5、慎重使用动态分区,最好在分区中指定分区字段的val值。
3.4.2 请慎重使用SELECT *
	使用 SELECT * 方式去查询数据,会造成很多无效数据的处理,会占用程序资源,造成资源的浪费。
	
    在查询数据表时,指定所需的待查字段名,而非使用 * 号。
3.4.3 慎重使用COUNT(DISTINCT col);
原因:
	distinct会将b列所有的数据保存到内存中,形成一个类似hash的结构,速度是十分的块;
	但是在大数据背景下,因为b列所有的值都会形成key的值,极有可能发生OOM。

解决方案:
	可以考虑使用Group By 代替COUNT(DISTINCT col)

3.4.4 不要在表关联后面加WHERE条件
原因:

比如以下语句:
	SELECT * FROM stu as t
		LEFT JOIN course as t1
			ON t.id=t2.stu_id
		WHERE t.age=18;

谓词下推:
  通过嵌套的方式,将底层查询语句尽量推到数据底层去过滤。

解决方案:
 SELECT * FROM (SELECT * FROM stu WHERE age=18) as t
   LEFT JOIN course AS t1
   on t.id=t1.stu_id
		
3.4.5 处理掉字段中带有空值的数据
原因:
	一个表内有许多空值时会导致MapReduce过程中,空成为一个key值,
	对应的会有大量的value值, 而一个key的value会一起到达reduce
	造成内存不足

解决方式:	
1、在查询的时候,过滤掉所有为NULL的数据,比如:
	select n.* from
	(select * from res where id is not null ) n
	left join org_tbl o on n.id = o.id;

2、查询出空值并给其赋上随机数,避免了key值为空
create table res_tbl as
	select n.* from res n
	full join org_tbl o on
	case when n.id is null then concat('hive', rand()) else n.id end = o.id

3.4.6 设置并行执行任务数
	通过设置参数 hive.exec.parallel 值为 true,就可以开启并发执行。	
	不过,在共享集群中,需要注意下,如果 job 中并行阶段增多,那么集群利用率就会增加。

set hive.exec.parallel=true; //打开任务并行执行
set hive.exec.parallel.thread.number=16; //同一个 sql 允许最大并行度,默认为 8
3.4.7 设置合理的Reducer个数
原因:	
	过多的启动和初始化 reduce 也会消耗时间和资源
	有多少个Reduer就会有多少个文件产生,如果生成了很多个小文件,
	那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题。


Reducer设置的原则:
	每个Reduce处理的数据默认是256MB
	hive.exec.reducers.bytes.per.reducer=256000000
	
	每个任务最大的reduce数,默认为1009
	hive.exec.reducers.max=1009

计算reduce数的公式
	N=min(参数2,总输入数据量/参数1)
	设置Reducer的数量

set mapreduce.job.reduces=n

三、Hbase

3.1.Hbase调优

3.1.1 解决热点效应
1. 预分区(依据: 基于Rowkey进行预分区)
   在创建表时,不按照默认的策略,为表只创建一个Region,而是
 根据需要,为一张表创建多个Region,从而避免热点效应
  语法:
    create 't1', 'f1', SPLITS => ['10', '20', '30', '40']
    create 't1', 'f1', SPLITS_FILE => 'splits.txt'
       splits.txt
       10
       20
       30
       40
   create 't2', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
   
2.rowkey设置(合理的设计rewkey能避免热点效应)
3.1.2 如何提高检索效率
1、rowkey 相对连续 那么检索效率一定高
2、设置Memstore大小 , Block Cache大小 
  hbase-site.xml 设置 :
  	//Memstore 全局堆空间的40%刷新 
  	//(regionserver占用JVM 对空间)
    hbase.regionserver.global.memstore.size 0.4 
    
    //每一个memstore达到128M flush 
    hbase.hregion.memstore.flush.size  128M  
    hfile.block.cache.size 0.4 (regionserver占用JVM 对空间)
 
  让数据尽可能多的放置在内存中,提高检索效率.
  避免flush memstore 阻塞client操作   
  
3、hbase内部的块数据索引,布隆过滤器 
3.1.3 JVM参数配置
1. JVM Java进程 
2. JVM (堆空间) HBase
   新生代 1/3                             老年代 2/3  永久代(静态,常量)
   eden survivor(from)  survivor(to)
    8      1                1
   ParNewGC                              ConcMarkSweepGC
    -Xmx8g -Xms8G -Xmn128m -XX:UseParNewGC 
    -XX:UseConcMarkSweepGC 
    -XX:CMSInitiatingOccupancyFraction=70  
    -verbose:gc 
    -XX:+PrintGCDetails 
    -XX:+PrintGCTimeStamps 
    -Xloggc:$HBASE_HOME/logs/gc-${hostname}-hbase.log

   hbase-env.sh
   export HBASE_REGIONSERVER_OPTS=-Xmx8g -Xms8G  -Xmn128m -XX:UseParNewGC     -XX:UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70  -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps    -Xloggc:$HBASE_HOME/logs/gc-${hostname}-hbase.log

3.1.4 防止内存泄露(设置mslab)
 防止内存碎片,内存碎片过多,内存泄露,发生FullGC,导致STW.
 
 memStrom达到阀值值 
 (5个中,其中一个:很小,flush后不能更好的利用)
hbase.hregion.memstore.mslab.enabled  true
hbase.hregion.memstore.mslab.chunksize  2M --> 调整为: 4,5M 6M等 
3.1.5 自动化处理的功能变成手工处理
hbase tools 
  手工操作 compact split(占用系统资源)

结合定时,shell脚本 完成处理
	test.sh
	/opt/install/hbase-0.98.6-hadoop2/bin/hbase shell 
	/root/hbase/test

3.2 hbase的rowkey设计

HBase相关的查询操作,95%上都是对RowKey查询。
1. 设计过程 
   2.1 将主键设置成复合rowkey,下划线做分割。
   2.2 查询内容作为rowkey组成
2.避免rowKey的长度过长(支持rowkey 64K) 建议 10--100字节唯一。
3. rowkey结合自己的实际需求
   3.1  区域查询多,建议 rowkey 连续    
   3.2  区域查询少,对散列 hash算法,加密算法(原始数据)、UUID等

3.3 HBase的体系结构

   一张t_user表存在一个reglon中
   reglon通过store来存对应的列簇(多少个列簇就有多少个store)
   		store包含 MemStore、StoreFile
		写数据先往MemStore中写,达到阀值进行Flush---->StoreFile中写(StoreFile对应文件类型为Hfile类型  映射Hdfs文件)
		
应该是每一个 RegionServer 就只有一个 HLog,而不是一个 Region 有一个 HLog。
Hlog(数据先写入预写日志,在MemStore中写,防止数据丢失)

在这里插入图片描述

3.4 HBase宕机如何处理

1、HMaster宕机:
	HMaster没有单点问题,HBase中可以启动多个HMaster,
	通过ZooKeeper的选举机制保证总有一个HMaster运行及对外提供服务
2、HRegionServer宕机
	当HRegionServer宕机时,HMaster会将其所管理的region重新分布到其他活动的HRegionServer上。
	同时将该HRegionServer上存在MemStore中还未持久化到磁盘中的数据通过WAL重播进行恢复,由于数据和日志都持久在HDFS中,该操作不会导致数据丢失所以数据的一致性和安全性是有保障的。
	重新分配的region需要根据日志恢复原RegionServer中的内存MemoryStore表,这会导致宕机的region在这段时间内无法对外提供服务。
	宕机的节点重新启动后就相当于一个新的RegionServer加入集群,为了平衡,需要再次将某些region分布到该server。

3.5 hive跟hbase的区别

hive:
	Hive是基于Hadoop的一个数据仓库工具,
	Hive将hdfs上结构化的数据文件映射为一张数据库表,
	Hive本身不存储和计算数据,它完全依赖于HDFS和MapReduce。
	hive是map-reduce的一个包装。
		可以提供简单的sql查询功能。
		本质就是把好写的hive的sql转换为复杂难写的map-reduce程序
	
HBase:
    HBase是Hadoop的数据库,一个分布式、可扩展、大数据的存储。
	hbase是物理表,不是逻辑表。
	hbase可以认为是hdfs的一个包装。他的本质是数据存储,是个NoSql数据库。
    hbase部署于hdfs之上,并且克服了hdfs在随机读写方面的缺点。
    
二者联系:
	Hbase主要解决实时数据查询问题,
	Hive主要解决数据处理和计算问题,一般是配合使用。

Hive和HBase是协作关系,数据流一般如下图:
	通过ETL工具将数据源抽取到HDFS存储;
	通过Hive清洗、处理和计算原始数据;
	HIve清洗处理后的结果,如果是面向海量数据随机查询场景的可存入Hbase
	数据应用从HBase查询数据;

在这里插入图片描述

3.6 hbase写流程

1、Client访问zookeeper,获取元数据存储所在的regionserve的地址
2、去表所在的regionserver进行数据的添加
3、查找对应的region,在region中寻找列族,先向memstore中写入数据
4、当memstore写入的值变多,触发溢写操作(flush),进行文件的溢写,成为一个StoreFile
5、当溢写的文件过多时,会触发文件的合并(Compact)操作,合并有两种方式(major,minor)

3.7 hbase读流程

	1.Client访问zookeeper,获取元数据存储所在的regionserver的地址。
	2.去表所在的regionserver进行数据的读取.
	3.查找对应的region,在region中寻找列族,先memstore找,
找不到去blockcache中寻找,再找不到就进行storefile的遍历
	4.找到数据之后会先缓存到blockcache中,再将结果返回,blockcache逐渐满
了之后,会采用LRU的淘汰策略。

3.8 hbase数据flush、合并过程

在这里插入图片描述

3.9 Hmaster和Hgionserver职责

1、管理用户对Table表的CRUD
2、管理redion
	Region分裂后,分配 Region到RegionServer ,保证 RegionServer 的负载均衡
	RegionServer 宕机后,并重新分配其上的 Region
管理 Region,响应用户对这些 Region 的 IO 请求
Split 过大的 Region,负责 Compact 操作

Hgionserver:
	响应用户对这些 Region 的 IO 请求
	Split 过大的 Region,负责 Compact 操作

3.10 HBase列族和region的关系

   一张t_user表存在一个reglon中
   reglon通过store来存对应的列簇(多少个列簇就有多少个store).
   通常一张表对应一个列簇。

3.11 hbase二级索引相关

为什么需要HBse二级索引?(目的非rowkey字段检索也能做到秒级响应)
	HBase里面只有rowkey作为一级索引。
	对非rowkey字段进查询,往往要通过MapReduce/Spark等分布式计算框架进行,
硬资源消耗和时间延迟都会比较高。
  • 设计思路:
  • 本质:建立各列值与行键之间的映射关系
	当要对F:C1这列建立索引时,只需要建立F:C1各列值到其对应行键的映射关系,如C11->RK1等,
	这样就完成了对F:C1列值的二级索引的构建.
	当要查询符合F:C1=C11对应的F:C2的列值时(即根据C1=C11来查询C2的值,1青色部分)

在这里插入图片描述

其查询步骤如下:
1. 根据C1=C11到索引数据中查找其对应的RK,查询得到其对应的RK=RK1
2. 得到RK1后就自然能根据RK1来查询C2的值了 这是构建二级索引大概思路,其他组合查询的联合索引的建立也类似。

四、kafka

4.1 Kafka基本组件

  broker:  kafka集群的server,负责处理消息读、写请求,存储消息
  producer:消息生产者
  consumer:消息消费者
  topic:   消息队列/分类
  Record:   一条记录(key/val)。
  
	Kafka集群以Topic(内部分区)形式负责管理集群中的Record.每一个Record属于一个Topic,Topic以日志分区形式持久化Record。
   在Kafka集群中:Topic的每一个分区都一定会有1个Borker担当该分区的Leader,其他的Broker担当该分
区的follower(取决于分区的副本因子)。
   一旦对应分区的Lead宕机,kafka集群会给当前的分区指定新的Borker作为该分区的Leader。分区的
Leader的选举是通过Zookeeper一些特性实现的。
	broker(Leader)  负责对应分区的读写操作,
	broker(Follower)负责数据备份操作。

在这里插入图片描述

4.2.Consumer与topic关系

	1、一个group中会包含多个consumer。某个consumer失效那么其消费的partitions将会有其
他consumer自动接管。
	2、Topic中的一条消息,只会被订阅此Topic的每个group中的其中一个consumer消费。
    3、一个Topic中的每个partions,只会被一个"订阅者"中的一个consumer消费,一个consumer可
以同时消费多个partitions中的消息。
	4、kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer
同时消费,否则将意味着某些consumer将无法得到消息。

4.3 如何保证kafka不丢数据

1、使用 send(msg, callback)来发送消息.
2、设置生产者acks机制 :
   acks=0生产者将完全不会管服务器是否收到消息(式具有最大的吞吐量,一般建议直接配合 send(msg)使用)
   acks=1      当leader接受到消息就会直接给客户端返回成功。
   acks=all/-1  当leader接受到消息,并同步到了 所有数量的follower,才向生产者发生成功的消息。

3、设置生产者重试机制 
   配置生产者 发送消息的重试次数,一般为三。
   

4.4 如何保证kafka不重复消费数据

kafka重复消费产生原因:
     poll出新的数据,在指定的时间内,没有进行kafka的位移提交。导致kafka重复消费数据。

	改为代码中就是,代码中会指定一个session-time来进行kafka数据的poll,供consumer进行消费处理..一次进行poll的数据量由maxpoolrecordsconfig来决定,这个数值就是决定了一次poll的数据量大小...
	手动提交offset时,当第一次poll出maxrecords条记录给程序时,程序需要进行处理(数据清理什么的),在session-time内,程序没有处理完这些数据,即还没有进行offset的commit,kafka又会根据上一次的offset进行poll出数据,其实这个数据就是我们刚刚没有消费处理完成的,这就导致了我们这次会有maxrecords条数据是重复的了

决这个问题的简单方法:
   就是调整session-time和
      max.poll.records.config的值,这个的均值,
	即最优化的方程式就是:
      maxpollrecordsconfig/代码处理单条数据时间=session-time.

4.5 列举Kafka的优点,

        高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒;
       可扩展性:kafka集群支持热扩展;
       持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失;
       容错性:允许集群中节点故障(若副本数量为n,则允许n-1个节点故障);
       高并发:支持数千个客户端同时读写。

4.6 Kafka为什么能那么快?

	partition 并行处理。
	顺序写磁盘,充分利用磁盘特性。
	利用了现代操作系统分页存储 Page Cache 来利用内存提高 I/O 效率
	采用了零拷贝技术
	Producer 生产的数据持久化到 broker,采用 mmap 文件映射,实现顺序的快速写入
	Customer 从 broker 读取数据,采用sendfile,将磁盘文件读到 OS 内核缓冲区后,转到 NIO buffer进行网络发送,减少 CPU 消耗。

4.7 Kafka与传统的消息队列服务有很么不同

   1.首先kafka会将接收到的消息分区(partition),每个主题(topic)的消息有不同的分区,
这样一方面消息的存储就不会受到单一服务器存储空间大小的限制,另一方面消息的处理也可以在多个服务器上并行。
	2.其次为了保证高可用,每个分区都会有一定数量的副本(replica)。这样如果有部分服务器不可用,副本所在的服务器就会接替上来,保证应用的  可靠性。
  3.能保证分区内部消息的消费有序性。
  4.Kafka还具有consumer group的概念,每个分区只能被同一个group的一个consumer消费,但可以被多个group消费。
  

4.8 Kafka api low-level与high-level有什么区别,使用low-level需要处理哪些细节

	从开放的功能服务看,highlevel的配置与使用相对简单,分布式管理功能由Kafka集群与zookeeper自行管理,消费
者只要从头或者从最新处获取数据即可,服务重启,能从上次消费位置开始,leader故障,能够自行rebalance。
	lowlevel更为为灵活也更复杂,这些都是开放给自己的应用来管理。

4.9 Kafka的ISR副本同步机制原理

	ISR:
	1、ISR是Kafka为某个分区维护的一组同步集合。每个分区都有一个ISR集合。
	2、一条 Kafka 消息,只有被 ISR 中的副本都接收到,才被视为“已同步”状态	。
    3、follower 副本与 leader 副本保持同步状态一致时,才有资格被选举为 leader。

    leader 副本永远领先 follower 副本,且各个 follower 副本之间的消息最新位移也不尽相同,
    Kafka 必须要定义一个落后 leader 副本位移的范围,使得处于这个范围之内的 follower 副本被认为与 leader 副
本是处于同步状态的,即处于 ISR 集合中。

	0.9.0.0 版本之前的设计:
	主要是靠参数 replica.lag.max.messages 决定的,即允许 follower 副本落后 leader 副本的消息数量,超过
这个数量后,follower 会被踢出 ISR。
	replica.lag.max.messages 也很难在生产上给出一个合理值(存在问题,会导致数据丢失不合理的将flolower进行移除)

   0.9.0.0 版本之后,Kafka 给出了一个更好的解决方案,去除了 replica.lag.max.messages,用 replica.lag.time.max.ms 
参数来代替,该参数的意思指的是允许 follower 副本不同步消息的最大时间值,即只要在 replica.lag.time.max.ms 
时间内 follower 有同步消息,即认为该 follower 处于 ISR 中,这就很好地避免了在某个瞬间生产者一下子发送大
量消息到 leader 副本导致该分区 ISR 频繁收缩与扩张的问题了。

4.10 Kafka消息数据积压,Kafka消费能力不足怎么处理

	1)如果是Kafka消费能力不足,增加Topic的分区数,增加消费者数量,消费者数=分区数。(两者缺一不可)

  2)如果是下游的数据处理不及时:
    批次拉取数据过少(拉取数据/处理时间<生产速度),使处理的数据小于生产的数据,也会造成数据积压。
    提高每批次拉取的数量。

4.11 Kafka中的ISR、AR又代表什么

ISR:副本同步队列 ISR (In Sync Replicas)
AR(Assigned Replicas):分区中的所有副本统称。

ISR 集合是 AR 集合的一个子集。消息会先发送到leader副本,然后follower副本才能从leader中拉取消息进行同步。
同步期间,follow副本相对于leader副本而言会有一定程度的滞后。由于leader副本同步滞后过多的副本(不包括leader副本)将组成 OSR (Out-of-Sync Replied)由此可见,AR = ISR + OSR。
正常情况下,所有的follower副本都应该与leader 副本保持 一定程度的同步,即AR=ISR,OSR集合为空。

4.11 Kafka中的HW、LEO等分别代表什么?

	HW (High Watermark)俗称高水位
	 它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个offset之前的消息。
	 
	下图表示一个日志文件,这个日志文件中只有9条消息,第一条消息的offset(LogStartOffset)为0,
最有一条消息的offset为8,offset为9的消息使用虚线表示的,代表下一条待写入的消息。日志文件的 HW 
为6,表示消费者只能拉取offset在 05 之间的消息,offset为6的消息对消费者而言是不可见的。

     LEO (Log End Offset):
     标识当前日志文件中下一条待写入的消息的offset。下图中offset为9的位置即为当前日志文件的 LEO,
LEO 的大小相当于当前日志分区中最后一条消息的offset值加1.分区 ISR 集合中的每个副本都会维护自身的 LEO ,
而 ISR 集合中最小的 LEO 即为分区的 HW,对消费者而言只能消费 HW 之前的消息。

	LEO:每个副本的最后条消息的offset
	HW:一个分区中所有副本最小的offset

在这里插入图片描述

4.12 哪些情景会造成消息漏消费?

先提交offset,后消费,有可能造成数据的重复

4.13 当你使用kafka-topics.sh创建了一个topic之后,Kafka背后会执行什么逻辑?

    1)会在zookeeper中的/brokers/topics节点下创建一个新的topic节点,如:/brokers/topics/first
    2)触发Controller的监听程序
    3)kafka Controller 负责topic的创建工作,并更新metadata cache
    

4.14 topic的分区数可不可以增加?如果可以怎么增加?如果不可以,那又是为什么?

可以增加
	bin/kafka-topics.sh --zookeeper localhost:2181/kafka --alter --topic01 topic-config --partitions 3

4.15 topic的分区数可不可以减少?如果可以怎么减少?如果不可以,那又是为什么?

	不可以减少,被删除的分区数据难以处理

4.16 Kafka有内部的topic吗?如果有是什么?有什么所用?

 __consumer_offsets,保存消费者offset。

4.17 聊一聊Kafka Controller的作用?

	负责管理集群broker的上下线,
	所有topic的分区,副本分配和leader选举等工作。

4.18失效副本是指什么?有那些应对措施?

	不能及时与leader同步,暂时踢出ISR,等其追上leader之后再重新加入

4.19 Kafka 分区的目的?

  分区对于 Kafka 集群的好处是:
     实现负载均衡。分区对于消费者来说,可以提高并发度,提高效率。

4.20 你知道 Kafka 是如何做到消息的有序性?

	kafka 中的每个 partition 中的消息在写入时都是有序的,而且消息带有offset偏移量,消费者按偏移量的顺序从
前往后消费,从而保证了消息的顺序性。但是分区之间的消息是不保证有序的.

4.21 Kafka 的高可靠性是怎么实现的?

	依靠 分区多副本架构  Kafka 可靠性保证的核心。
	把消息写入多个副本可以使 Kafka 在发生崩溃时仍能保证消息的持久性。

4.22 请谈一谈 Kafka 数据一致性原理

在这里插入图片描述

	不论是老的 Leader 还是新选举的 Leader,Consumer 都能读到一样的数据:

	假设分区的副本为3,其中副本0是 Leader,副本1和副本2是 follower,并且在 ISR 列表里面。

	虽然副本0已经写入了 Message4,但是 Consumer 只能读取到 Message2。因为所有的 ISR 都同步了 Message2,

	只有 High Water Mark 以上的消息才支持 Consumer 读取,而 High Water Mark 取决于 ISR 列表里面偏移量最
小的分区,对应于上图的副本2

	这样做的原因是还没有被足够多副本复制的消息被认为是“不安全”的,如果 Leader 发生崩溃,另一
个副本成为新 Leader,那么这些消息很可能丢失了。
    如果我们允许消费者读取这些消息,可能就会破坏一致性。试想,一个消费者从当前 Leader(副本0) 
读取并处理了 Message4,这个时候 Leader 挂掉了,选举了副本1为新的 Leader,这时候另一个消费者再
去从新的 Leader 读取消息,发现这个消息其实并不存在,这就导致了数据不一致性问题。

	当然,引入了 High Water Mark 机制,会导致 Broker 间的消息复制因为某些原因变慢,那么消息到达
消费者的时间也会随之变长(因为我们会先等待消息复制完毕)。延迟时间可以通过参数 replica.lag.time.max.ms
 参数配置,它指定了副本在复制消息时可被允许的最大延迟时间。

4.22 ISR、OSR、AR 是什么?

AR:Assigned Replicas 所有副本
ISR:In-Sync Replicas 副本同步队列
OSR:Out-of-Sync Replicas

	ISR是由leader维护,follower从leader同步数据有一些延迟,超过相应的阈值会把 follower 剔除出 ISR,
 存入OSR(Out-of-Sync Replicas )列表,新加入的follower也会先存放在OSR中。AR=ISR+OSR。
 

4.23 LEO、HW、LSO、LW等分别代表什么

LEO:
 是 LogEndOffset 的简称,代表当前日志文件中下一条。
 
HW:
   水位或水印(watermark)一词,它表示的就是位置信息,即位移(offset)。
   取 partition 对应的 ISR中 最小的 LEO 作为 HW,consumer 最多只能消费到 HW 所在的位置上一条信息。

LSO:是 LastStableOffset 的简称,对未完成的事务而言,LSO 的值等于事务中第一条消息的位置(firstUnstableOffset),对已完成的事务而言,它的值同 HW 相同

LW:
  Low Watermark 低水位, 代表 AR 集合中最小的 logStartOffset 值。

4.24 Kafka 在什么情况下会出现消息丢失?

在follow 同步lead数据未同步完成时,lead宕机的情况下回丢少量的数据。

4.25 .怎么尽可能保证 Kafka 的可靠性

合理地配置flollow同步消息的 延迟时间:replica.lag.time.max.ms

4.26 消费者和消费者组有什么关系?

在这里插入图片描述

4.27 Kafka 的每个分区只能被一个消费者线程,如何做到多个线程同时消费一 个分区?

4.28 数据传输的事务有几种?

	最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输
	最少一次: 消息不会被漏发送,最少被传输一次,但也有可能被重复传输.
	精确的一次(Exactly once): 不会漏传输也不会重复传输,每个消息都传输被

4.29 Kafka 消费者是否可以消费指定分区消息?

	Kafa consumer消费消息时,向broker发出fetch请求去消费特定分区的消息
consumer指定消息在日志中的偏移量(offset),就可以消费从这个位置开始的消息,
customer拥有了offset的控制权,可以向后回滚去重新消费之前的消息,这是很有意义的

4.30 Kafka消息是采用Pull模式,还是Push模式?

	Kafka选取了传统的pull模式。
	Pull模式的另外一个好处是consumer可以自主决定是否批量的从broker拉取数据。
	Pull模式下,consumer就可以根据自己的消费能力去决定这些策略。
	Pull有个缺点是,如果broker没有可供消费的消息,将导致consumer不断在循环中轮询,直到新消息到t达
	为了避免这点,Kafka有个参数可以让consumer阻塞直到新消息到达。

4.31.Kafka 高效文件存储设计特点

	Kafka把topic中一个parition大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经
消费完文件,减少磁盘占用。
	通过索引信息可以快速定位message和确定response的最大大小。
	通过index元数据全部映射到memory,可以避免segment file的IO磁盘操作。
	通过索引文件稀疏存储,可以大幅降低index文件元数据占用空间大小

4.32.Kafka创建Topic时如何将分区放置到不同的Broker中

1、副本因子不能大于 Broker 的个数;
2、第一个分区(编号为0)的第一个副本放置位置是随机从 brokerList 选择的;
	其他分区的第一个副本放置位置相对于第0个分区依次往后移。
	也就是如果我们有5个 Broker,5个分区,
	假设第一个分区放在第四个 Broker 上,
	那么第二个分区将会放在第五个 Broker 上;
	第三个分区将会放在第一个 Broker 上;
	第四个分区将会放在第二个 Broker 上,依次类推;
剩余的副本相对于第一个副本放置位置其实是由 nextReplicaShift 决定的,而这个数也是随机产生的;

4.33 .Kafka新建的分区会在哪个目录下创建

在启动 Kafka 集群之前,我们需要配置好 log.dirs 参数,其值是 Kafka 数据的存放目录

4.34.谈一谈 Kafka 的再均衡

	在Kafka中,当有新消费者加入或者订阅的topic数发生变化时,会触发Rebalance
(再均衡:在同一个消费者组当中,分区的所有权从一个消费者转移到另外一个消费者)机制,Rebalance顾名思义就是重新均衡消费者消费。Rebalance的过程如下:

    第一步:所有成员都向coordinator发送请求,请求入组。一旦所有成员都发送了请求,
 coordinator会从中选择一个consumer担任leader的角色,并把组成员信息以及订阅信息发给leader。
    第二步:leader开始分配消费方案,指明具体哪个consumer负责消费哪些topic的哪些partition。
 一旦完成分配,leader会将这个方案发给coordinator。
    coordinator接收到分配方案之后会把方案发给各个consumer,这样组内的所有成员就都知道自己应该消费哪些分
 区了。所以对于Rebalance来说,Coordinator起着至关重要的作用。
 

4.35 谈谈 Kafka 分区分配策略

 Kafka 内部存在两种默认的分区分配策略:
 	Range 和 RoundRobin
 	
当同一个Consumer Group 内新增消费者,Kafka 将会进行一次分区分配:
消费者离开当前所属的Consumer Group,包括shuts down 或 crashes Kafka 将会进行一次分区分配:
订阅的主题新增分区,Kafka 将会进行一次分区分配:

重新平衡(rebalance):将分区的所有权从一个消费者移到另一个消费者

Range策略:
	假设我们有个名为 T1 的主题,其包含了10个分区,然后我们有两个消费者(C1,C2)来消费这10个分区里面
的数据,而且 C1 的 num.streams = 1,C2 的 num.streams = 2。
	排完序的分区将会是0, 1, 2, 3, 4, 5, 6, 7, 8, 9
	消费者线程排完序将会是C1-0, C2-0, C2-1。
	partitions的个数除于消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费
者线程将会多消费一个分区。
	10个分区,3个消费者线程, 10 / 3 = 3,而且除不尽,那么消费者线程 C1-0 将会多消费一个分区,所以最后分区分配的结果看起来是这样的:
	C1-0 将消费 0, 1, 2, 3 分区C2-0 将消费 4, 5, 6 分区C2-1 将消费 7, 8, 9 分区
	
	假如我们有11个分区,那么最后分区分配的结果看起来是这样的:
C1-0 将消费 0, 1, 2, 3 分区C2-0 将消费 4, 5, 6, 7 分区C2-1 将消费 8, 9, 10 分区
	
	假如我们有2个主题(T1和T2),分别有10个分区,那么最后分区分配的结果看起来是这样的:
C1-0 将消费 T1主题的 0, 1, 2, 3 分区以及 T2主题的 0, 1, 2, 3分区C2-0 将消费 T1主题的 4, 5, 6 分区以及 T2主题的 4, 5, 6分区C2-1 将消费 T1主题的 7, 8, 9 分区以及 T2主题的 7, 8, 9分区

	可以看出,C1-0 消费者线程比其他消费者线程多消费了2个分区,这就是Range strategy的一个很明显的弊端。

RoundRobin策略:
	使用RoundRobin策略有两个前提条件必须满足
		同一个Consumer Group里面的所有消费者的num.streams必须相等
		每个消费者订阅的主题必须相同。
	假设前面提到的2个消费者的num.streams = 2。
	RoundRobin策略的工作原理:将所有主题的分区组成 TopicAndPartition 列表,然后对 TopicAndPartition 
列表按照 hashCode 进行排序
	在我们的例子里面,假如按照 hashCode 排序完的topic-partitions组依次为T1-5, T1-3, T1-0, T1-8, 
T1-2, T1-1, T1-4, T1-7, T1-6, T1-9,我们的消费者线程排序为C1-0, C1-1, C2-0, C2-1,
	最后分区分配的结果为:
		C1-0 将消费 T1-5, T1-2, T1-6 分区;
		C1-1 将消费 T1-3, T1-1, T1-9 分区;
		C2-0 将消费 T1-0, T1-4 分区;
		C2-1 将消费 T1-8, T1-7 分区;
		
	根据上面的详细介绍相信大家已经对Kafka的分区分配策略原理很清楚了。不过遗憾的是,目前我们还不能自定义分区分配策略,只能通过partition.assignment.strategy参数选择 range 或 roundrobin。
	partition.assignment.strategy参数默认的值是range

4.36.Kafka 是如何实现高吞吐率的?

	顺序读写;
	零拷贝:
	文件分段
	批量发送
	数据压缩。

4.37.Kafka 监控都有哪些?

KafkaManager

4.38 谈谈你对 Kafka 事务的了解?

4.39 谈谈你对 Kafka 幂等的了解?

4.40 Kafka 缺点?

	由于是批量发送,数据并非真正的实时;
	对于mqtt协议不支持;
	不支持物联网传感数据直接接入;
	仅支持统一分区内消息有序,无法实现全局消息有序;
	监控不完善,需要安装插件;
	依赖zookeeper进行元数据管理;

4.41 Kafka 分区数可以增加或减少吗?为什么?

	我们可以使用 bin/kafka-topics.sh 命令对 Kafka 增加 Kafka 的分区数据,但是 Kafka 不支持减少分区数

4.42 kafka消息的存储机制

 kafka通过 topic来分主题存放数据,主题内有分区,分区可以有多个副本,
 分区的内部还细分为若干个 segment。都是持久化到磁盘,采用零拷贝技术。

56.相比较于传统消息队列,kafka的区别

	1、分区性:存储不会受单一服务器存储空间的限制
	2、高可用性:副本1 leader选举
	3、消息有序性:一个分区内是有序的。
	4、负载均衡性:分区内的一条消息,只会被消费组中的一个消费者消费,主题中的消息,会均衡的发送给消费者组中的所有消费者进行消费。

4.43 消息丢失和消息重复

同步:
	这个生产者写一条消息的时候,它就立马发送到某个分区去。
异步:
	这个生产者写一条消息的时候,先是写到某个缓冲区,这个缓冲区里的数据还没写到 broker集群里的某
个分区的时候,它就返回到 client去了


针对消息丢失:同步模式下,确认机制设置为-1,即让消息写入 Leader和 Fol lower之后再确认消息发送成功:
异步模式下,为防止缓冲区满,可以在配置文件设置不限制阻塞超时时间,当缓冲区满时让生产者一直处于阻塞状态
针对消息重复,将消息的唯一标识保存到外部介质中,每次消费时判断是否处理过即可.

4.44 kafka写生产数据流程

	producer 先从 zookeeper 的 "/brokers/.../state"节点找到该 partition 的 leader
	producer 将消息发送给该 leader
	leader 将消息写入本地 log
	
	followers 从 leader pull 消息,写入本地 log 后向 leader 发送 ACK
	
	leader 收到所有 ISR 中的 replication 的 ACK 后,
增加 HW(high watermark,最后 commit的 offset)并向producer 发送 ACK

在这里插入图片描述

4.45 kafka消费数据流程

	1、cousumer 向boker 集群提交连接请求,返回 broker 的通信url
	2、consumer 指定要消费的topic 后, 向broker提交 消息请求
	3、broker 将consumer 分配一个或者多个 partition leader 。并且将对应的parittion的offset 发送给 consumer
	4、consumer 消费完消息后,消费者会向broker 发送一个消息被消费的反馈。也就是提交 该消息的offset
	5、当broker 接收到 offset 后,会更新到对应的consumer_offset中

五、scala


六、spark

6.1 什么事rdd

1.rdd的属性
~~~java
	RDD可以理解是一个弹性的,分布式、不可变的、带有分区的数据集合。(跨越多个节点)
    所谓的Spark的批处理,实际上就是正对RDD的集合操作。
	 RDD特点:
		- 任意一个RDD都包含分区数(决定程序某个阶段计算并行度)
		- RDD所谓的分布式计算是在分区内部计算的
		- 因为RDD是只读的,RDD之间的变换存着依赖关系(宽依赖、窄依赖)
		- 针对于k-v类型的RDD,一般可以指定分区策略(一般系统提供) 
		        	HashPartitioner,另外一个是基于范围的RangePartitioner
		- 针对于存储在HDFS上的文件,系统可以计算最优位置,计算每个切片。(了解)

6.2 算子分为哪几类(RDD支持哪几种类型的操作)

转换(Transformation):
	 现有的RDD通过转换生成一个新的RDD。lazy模式,延迟执行。
	 包括:map,filter,flatMap,groupByKey,reduceByKey,aggregateByKey,union,join, coalesce 等等。

动作(Action):
	在RDD上运行计算,并返回结果给驱动程序(Driver)或写入文件系统。
	包括:reduce,collect,count,first,take,countByKey以及foreach等等
	
所有的transformation只有遇到action才能被执行。
当触发执行action之后,数据类型不再是rdd了,数据就会存储到指定文件系统中,或者直接打印结 果或者收集起来。

6.3 创建rdd的几种方式

1.集合并行化创建(有数据)
	val arr = Array(1,2,3,4,5)
	val rdd = sc.parallelize(arr)
	val rdd =sc.makeRDD(arr)
	
2.读取外部文件系统,如hdfs,或者读取本地文件(最常用的方式)(没数据)
	val rdd2 = sc.textFile("hdfs://hdp-01:9000/words.txt")

	// 读取本地文件
	val rdd2 = sc.textFile(“file:///root/words.txt”)

3、从父RDD转换成新的子RDD
	调用Transformation类的方法,生成新的RDD

6.4 spark运行流程

	1、Driver 向ClusterManager 申请计算资源。(进程Executor,任务运行之前就申请好)
	2、ClusterManager 分配Executor进程,即在WorkNode启动 Executor(注意:一个WorkNode可以启动多个Excutor)
	3、资源(Excutor)反向注册到Driver中。一个进程只能被注册到一个Driver,一个Driver(程序)可管理1一到多个Excutor计算资源。
	4、通过DGASchedule 将job划分为多个计算阶段(迭代State),将每个阶段的Sate封装成一个TaskSet。在由TaskSchedual将TaskSet(阶段性任务集)提交集群进行计算。(即有三个进程来运行我们的线程)Excutor计算结果存入cache。

在这里插入图片描述

6.5 Spark中coalesce与repartition的区别

1)关系:
	两者都是用来改变 RDD 的 partition 数量的,
	repartition 底层调用的就是 coalesce 方法:coalesce(numPartitions, shuffle = true)

2)区别:
	repartition 一定会发生 shuffle,
	coalesce 根据传入的参数来判断是否发生 shuffle

	一般情况下增大 rdd 的 partition 数量使用 repartition,
	减少 partition 数量时使用coalesce。。

6.6.sortBy 和 sortByKey的区别

	sortBy既可以作用于RDD[K] ,还可以作用于RDD[(k,v)]
	sortByKey  只能作用于 RDD[K,V] 类型上。

6.7 map和mapPartitions的区别

在这里插入图片描述

	mapPartitions:一次拿一个分区的数据。
	map 一次拿一个数据进行迭代。

6.8 数据存入Redis 优先使用map mapPartitions、foreach、foreachPartions哪个

1,map mapPartition:是转换类的算子, 有返回值
2, 写mysql,redis 的连接
   foreach  * 100100万次的连接
   foreachPartions * 200 个分区     200次连接  一个分区中的数据,共用一个连接
 
  foreachParititon 每次迭代一个分区,foreach每次迭代一个元素
  在写入到redis,mysql的时候,优先使用foreachPartititon

6.9 reduceByKey和groupBykey的区别

	reduceByKey会传一个聚合函数, 相当于  groupByKey + mapValues
	reduceByKey 会有一个分区内聚合,而groupByKey没有  最核心的区别 

	结论:
	reduceByKey有分区内聚合,更高效,优先选择使用reduceByKey。

6.10 cache和checkPoint的比较

1.缓存,是在触发action之后,把数据写入到内存或者磁盘中。不会截断血缘关系
2.checkpoint 也是在触发action之后,执行任务。单独再启动一个job,负责写入数据到hdfs中。
3.某一个RDD被checkpoint之后,他的父依赖关系会被删除,血缘关系被截断,该RDD转换成了

	CheckPointRDD,以后再对该rdd的所有操作,都是从hdfs中的checkpoint的具体目录来读取数据。
	缓存之后,rdd的依赖关系还是存在的。

6.11 spark streaming流式统计单词数量代码

/**
  *  1、环境 linux--数据来源  netcat
  *     --[root@CentOS ~]# yum install -y nc
  *     --启动nc服务[root@CentOS ~]# nc -lk 9999
  *
  *  2、结果:完成数据的统计计数(程序启动开始的,所有的数据)
  *   如:
  *      this is book
  *         (this 1)
  *         (is 1)
  *         (book 1)
  *      this is book
  *         (this 2)
  *         (is   2)
  *         (book 2)
  *      this is book
  *        (this 2)
  *        (is   2)
  *        (book 2)
  * 3、数据的储存 hdfs
  * --(缺点)关闭程序,数据丢失无法从hdfs中获取
  * */
object SparkStreamWordCounts01 {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setMaster("local[2]").setAppName("KafkaStreamWordCount")
    val ssc = new StreamingContext(conf, Seconds(5))

    //将状态临时存入HDFS目录中。//在JVM启动参数中添加-DHADOOP_USER_NAME=root(解决权限的问题).
    ssc.checkpoint("hdfs://CentOS61:9000/checkpoints")

    def updateFun(newValues: Seq[Int], runningCount: Option[Int]): Option[Int] = {
      var total = newValues.sum + runningCount.getOrElse(0)
      Some(total)
    }

    ssc.socketTextStream("CentOS61", 9999)
      .flatMap(_.split("\\s+"))
      .map((_, 1))
      .updateStateByKey(updateFun) //状态的 从初始开始计数 保存当前系统的数据
      .print()

    ssc.sparkContext.setLogLevel("FATAL") //关闭日志打印
    ssc.start()
    ssc.awaitTermination()
  }
}

6.12 简述map和flatMap的区别和应用场景

	map是对每一个元素进行操作,
	flatmap是对每一个元素操作后并压平.
		//将一个元素转换成元素的数组,然后对数组展开。
		//def flatMap[U](f: T=> TraversableOnce[U]): org.apache.spark.rdd.RDD[U]
		scala>  sc.parallelize(List("ni hao","hello spark"),3)
					.flatMap(line=>line.split("\\s+"))
					.collect
		res4: Array[String] = Array(ni, hao, hello, spark)

6.13 分别列出几个常用的transformation和action算子

	转换算子:
		map,map,filter,reduceByKey,groupByKey,groupBy
		
	行动算子:
		foreach,foreachpartition,collect,collectAsMap,take,top,first,count,countByKey

6.14 按照需求使用spark编写以下程序,要求使用scala语言

  • 当前文件a.txt的格式,请统计每个单词出现的次数
  • A,b,c
  • B,b,f,e
	object WordCount {
	  def main(args: Array[String]): Unit = {
	    val conf = new SparkConf()
	      .setAppName(this.getClass.getSimpleName)
	      .setMaster("local[*]")
	    val sc = new SparkContext(conf)
	
	    var sData: RDD[String] = sc.textFile("a.txt")
	    val sortData: RDD[(String, Int)] = sData.flatMap(_.split(","))
	    										.map((_,1))
	    										.reduceByKey(_+_)
	    sortData.foreach(print)
	  }
	}

6.15 .spark应用程序的执行命令是什么?

6.16 Spark应用执行有哪些模式,其中哪几种是集群模式

	本地local模式
	standalone模式
	spark on yarn模式	
	
	其中,standalone模式,spark on yarn模式,spark on mesos模式是集群模式

6.17 .请说明spark中广播变量的用途

	使用广播变量,每个 Executor 的内存中,只驻留一份变量副本,
	而不是对 每个 task 都传输一次大变量,省了很多的网络传输, 对性能提升具有很大帮助,
而且会通过高效的广播算法来减少传输代价。

6.18 以下代码会报错吗?如果会怎么解决

* val arr = new ArrayList[String];
*  arr.foreach(println)

需要改成 :
	val arr: Array[String] = new Array[String](10)
	arr.foreach(println)打印不会报空指针

6.19 写出你用过的spark中的算子,其中哪些会产生shuffle过程

	reduceBykey:
	groupByKey:

6.20 请写出创建Dateset的几种方式

1、Case-Class 获取DateSet:
				case class Person(id:Int,name:String,age:Int,sex:Boolean)
			def main(args: Array[String]): Unit = {
			    val spark = SparkSession.builder()
			    .appName("hellosql")
			    .master("local[10]")
			    .getOrCreate()
			    
			    import spark.implicits._
			    
			    val dataset: Dataset[Person] = List(Person(1,"zhangsan",18,true),Person(2,"wangwu",28,true)).toDS()
			    dataset.select($"id",$"name").show()
			
			    //关闭Spark日志
			    spark.sparkContext.setLogLevel("FATAL")
			    spark.stop()
			}

2、元组 获取DateSet
				case class Person(id:Int,name:String,age:Int,sex:Boolean)
				 def main(args: Array[String]): Unit = {
				     val spark = SparkSession.builder()
				         .appName("hellosql")
				         .master("local[10]")
				         .getOrCreate()
				     import spark.implicits._
				
				   val dataset: Dataset[(Int,String,Int,Boolean)] = List((1,"zhangsan",18,true),(2,"wangwu",28,true)).toDS()
				     dataset.select($"_1",$"_2").show()
				
				   //关闭Spark日志
				   spark.sparkContext.setLogLevel("FATAL")
				   spark.stop()
				 }
	 
3、加载json数据 获取DateSet
	{"name":"张三","age":18}
	{"name":"lisi","age":28}
	{"name":"wangwu","age":38}
				
				case class Person(name: String, age: Long)
				def main(args: Array[String]): Unit = {
				  val spark = SparkSession.builder()
				  .master("local[5]")
				  .appName("spark session")
				  .getOrCreate()
				  spark.sparkContext.setLogLevel("FATAL")
				  import spark.implicits._
				
				  val dataset = spark.read.json("D:///Persion.json").as[Person]
				  dataset.show()
				
				  spark.stop()
				}

6.20 描述一下RDD,DataFrame,DataSet的区别?

1)RDD
	优点:
		编译时类型安全
		编译时就能检查出类型错误
		面向对象的编程风格
		直接通过类名点的方式来操作数据
	缺点:
		序列化和反序列化的性能开销
		无论是集群间的通信, 还是 IO 操作都需要对对象的结构和数据进行序列化和反序列化。
		GC 的性能开销,频繁的创建和销毁对象, 势必会增加 GC

2)DataFrame
  DataFrame 引入了 schema 和 off-heap
  schema : RDD 每一行的数据, 结构都是一样的,这个结构就存储在 schema 中。
 Spark 通过 schema 就能够读懂数据, 因此在通信和 IO 时就只需要序列化和反序列化数据, 而结构的部分就可以省略了

3)DataSet
	DataSet 结合了 RDD 和 DataFrame 的优点,并带来的一个新的概念 Encoder。
	当序列化数据时,Encoder 产生字节码与 off-heap 进行交互,能够达到按需访问数据的效果,
而不用反序列化整个对象。Spark 还没有提供自定义 Encoder 的 API,但是未来会加入。

6.21 描述一下Spark中stage是如何划分的?描述一下shuffle的概念

	按照RDD的lineage关系,逆向生成stage的过程.
	划分依据(从后往前推):
	   遇到一个shuffle操作就划分为前后两个stage. shuffle前一个,shuffle后一个
	   如果整个过程没有产生shuffle那就只会有一个stage,1)、sc.textFile("hdfs:///t_words") 产生hadoopRDD,经过fiatMap/map/reduceBykey/collect
(2)、sc调用DAGSchedule ——runJob方法,将任务封装成 JobSubmitter并提交到evertProcessLoop
(3)、DGASchedule 收到队列事件后,调用handleJobSubmitter 开始处理job
(4)、根据最后一个 RDD 封装Resultstate
(5)、调用DGASchedule  的 submitState 方法根据 Resultstate反推出 其他的state
(6)、将当前的state 转化为TaskSet ,然后调用TaskSchedule 提交任务给集群

在这里插入图片描述

25.Spark 在yarn上运行需要做哪些关键的配置工作?如何kill -个Spark在yarn运行中Application

26.通常来说,Spark与MapReduce相比,Spark运行效率更高。请说明效率更高来源于Spark内置的哪些机制?请列举常见spark的运行模式?

27.RDD中的数据在哪?

	RDD中的数据在数据源,RDD只是一个抽象的数据集,我们通过对RDD的操作就相当于对数据进行操作。

28.如果对RDD进行cache操作后,数据在哪里?

	数据在第一执行cache算子时会被加载到各个Executor进程的内存中,
	第二次就会直接从内存中读取而不会区磁盘。

29.Spark中Partition的数量由什么决定

	和Mr一样,但是Spark默认最少有两个分区。

30.Scala里面的函数和方法有什么区别

31.SparkStreaming怎么进行监控?

32.Spark判断Shuffle的依据?

 父RDD的一个分区中的数据有可能被分配到子RDD的多个分区中

33.Scala有没有多继承?可以实现多继承么?

35.Sparkcontext的作用

	SparkContext是spark功能的主要入口。其代表与spark集群的连接,能够用来在集群上创建RDD、累加器、广播变量。
每个JVM里只能存在一个处于激活状态的SparkContext,在创建新的SparkContext之前必须调用stop()来关闭之前的SparkContext

36.Sparkstreaming读取kafka数据为什么选择直连方式

37.离线分析什么时候用sparkcore和sparksql

38.Sparkstreaming实时的数据不丢失的问题

39.简述宽依赖和窄依赖概念,groupByKey,reduceByKey,map,filter,union五种操作哪些会导致宽依赖,哪些会导致窄依赖

40.数据倾斜可能会导致哪些问题,如何监控和排查,在设计之初,要考虑哪些来避免

43.共享变量和累加器

	用广播变量可以使程序高效地将一个很大的只读数据发送给多个worker节点,而且对每个worker节点只需要
传输一次,每次操作时executor可以直接获取本地保存的数据副本,不需要多次传输。
		val conf = new SparkConf().setAppName("demo").setMaster("local[2]")
	val sc = new SparkContext(conf)
	
	val userList = List(
	    "001,张三,28,0",
	    "002,李四,18,1",
	    "003,王五,38,0",
	    "004,zhaoliu,38,-1"
	)
	val genderMap = Map("0" -> "女", "1" -> "男")
	val bcMap = sc.broadcast(genderMap)
	
	sc.parallelize(userList,3)
	.map(info=>{
	    val prefix = info.substring(0, info.lastIndexOf(","))
	    val gender = info.substring(info.lastIndexOf(",") + 1)
	    val genderMapValue = bcMap.value
	    val newGender = genderMapValue.getOrElse(gender, "未知")
	    prefix + "," + newGender
	}).collect().foreach(println)
	
	sc.stop() 

累加器;
	Spark提供的Accumulator,主要用于多个节点对一个变量进行共享性的操作。
Accumulator只提供了累加的功能。但是确给我们提供了多个task对一个变量并行操作的功能。但是task只能对Accumulator进行累加操作,不能读取它的值。只有Driver程序可以读取Accumulator的值。
	scala> var count=sc.longAccumulator("count")
scala> sc.parallelize(List(1,2,3,4,5,6),3).foreach(item=> count.add(item))
scala> count.value
res1: Long = 21
	

44.当 Spark 涉及到数据库的操作时,如何减少 Spark 运行中的数据库连接数?

45.特别大的数据,怎么发送到excutor中?

46.spark调优都做过哪些方面?

47.spark任务为什么会被yarn kill掉?

48.Spark on Yarn作业执行流程?yarn-client和yarn-cluster有什么区别?

  1. spark_1.X与spark_2.X区别

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值