一、Hadoop&HIVE
1.1 HDFS读写流程
1.1.1 HDFS读流程1.1.2 HDFS写流程 1.2 HDFS文件和目录数过多问题1.3 文件压缩格式及存储格式
1.3.1 存储格式1.3.2 压缩格式 1.4 MR Shuffle过程1.5 MR任务优化
1.5.1 输入小文件过多1.5.2 数据倾斜 1.6 HIVE SQL1.7 HIVE架构及解析成MR的过程1.8 HIVE任务优化
1.8.1 数据倾斜优化 1.9 YARN JOB提交流程1.10 YARN调度器 二、Spark
2.1 spark on yarn执行作业流程,yarn-client和yarn-cluster的区别2.2 spark任务调优
2.2.1 资源(并行度)调优2.2.2 持久化调优 2.3 spark shuffle
2.3.1 HashShuffleManager2.3.2 SortShuffleManager 2.4 spark Executor统一内存模型2.5 spark算子2.6 spark实现wordcount2.7 spark实现topN2.8 spark发生OOM后如何分析与解决2.9 spark一定比HIVE快吗2.10 spark如何划分宽窄依赖 三、Hbase
3.1 hbase的物理模型和存储架构
3.1.1 habse的物理模型3.1.2 habse的存储架构 3.2 hbase读写文件流程
3.2.1 hbase写入流程3.2.2 BULKLOAD写入3.3.3 hbase读取流程 3.3 hbase文件合并机制3.4 Region分裂策略3.5 hbase性能调优
3.5.1 读优化3.5.2 写优化3.5.3 FullGC优化 3.6 hbase二级索引
3.6.1 局部二级索引3.6.2 全局二级索引 3.7 hbase rowkey怎么设计3.8 跳表3.9 布隆过滤器的使用3.10 LSM树
一、Hadoop&HIVE 1.1 HDFS读写流程 1.1.1 HDFS读流程1.1.2 HDFS写流程客户端向namenode发送读请求(文件地址),namenode将指定文件包含哪些文件块,
所在文件块的datanode信息返回,客户端到相应的datanode上请求读取文件块信息,datanode返回给客户端
1.2 HDFS文件和目录数过多问题客户端向namenode发送写请求,namenode确认文件、目录是否存在,是否有权限,返回是否可以上传,客户端
对文件进行逻辑切分,向namenode请求第一个文件块的写位置,namenode返回datanode信息,客户端向相应
的datanode写文件,副本会在datanode之间进行同步,全部分块传输完成后,通知namenode传输完成。
1.3 文件压缩格式及存储格式 1.3.1 存储格式a.文件和目录的name quota占用namenode内存,过多容易造成namenode OOM,同时读取速度会变慢
b.通过手动执行小文件合并任务对小文件进行合并
c.对开发单位实施配额,设置quota name,quota space上限,要求开发单位主动优化任务产生的文件和目录数量。
1.3.2 压缩格式a.列式存储的优势:映射下推,便于压缩,占用存储空间少,网络传输占用少
b.常用存储格式parquet、orc、avro等
1.4 MR Shuffle过程a.gzip 压缩率高,解压缩速度快,不支持split
b.bzip2 压缩率很高,解压缩速度慢,支持split
c.lzo 压缩率合理,解压缩速度合理,支持split(需要创建索引)
d.snappy 压缩率合理,解压缩速度快,不支持split
1.5 MR任务优化 1.5.1 输入小文件过多数据分片,每个分片起一个map,map处理完成后发送到环形缓冲区,在环形缓冲区内按分区,key排序,环形缓冲区阈值0.8,
达到阈值后溢写到磁盘上,在磁盘上对文件归并排序,最终形成一个分区有序的大文件,reduce到大文件中拉取相应分区的数据
1.5.2 数据倾斜CombineInputFormat
1.6 HIVE SQLa.万能方法:跑两次MR,第一次添加指定随机数的前缀,第二次把前缀去掉
b.combiner:只使用于聚合
c.增加reduce数量(可能没啥用)
d.自定义分区器(开发工作量变大,维护起来麻烦)
1.7 HIVE架构及解析成MR的过程a. order by,distribute by,sort by,cluster by区别
b. row_number(1,2,3,4,5,6),rank(1,2,2,3,4),dense_rank(1,2,2,4,5)区别
c. lag(col,n),lead(col,n)
d. between n preceding and current row
between current row and n following
between unbounded preceding and unbounded following
1.8 HIVE任务优化 1.8.1 数据倾斜优化HIVE通过给用户提供交互接口(JDBC,HIVECLI),接收到用户的SQL,结合元数据,经过Driver内的
解析器(将SQL解析为抽象语法树AST)、编译器(将AST编译成逻辑执行计划)、优化器(对逻辑执行计划
进行优化)、执行器(将逻辑执行计划转化成MapReduce)转换成mapreduce,提交给hadoop执行,最后将执行结果返回给用户交互接口。
1.9 YARN JOB提交流程a. groupby引起的数据倾斜
hive.groupby.skewdata参数,跑两次MR,第一次随机分配
b. join引起的数据倾斜
hive.optimize.skewjoin参数,跑两次MR,两个表大key剔出来单独跑mapjoin,普通key正常join,合并结果
1.10 YARN调度器客户端向rm发送请求启动AppMaster,rm在nm上启动AppMaster,把JOB的资源信息下载到本地,AppMaster按Job的资源信息向rm申请
启动container,并在container中启动任务,所有任务完成后,AppMaster向rm注销自己。
二、Spark 2.1 spark on yarn执行作业流程,yarn-client和yarn-cluster的区别a.FIFO调度器
b.容量调度器:小任务单独设置一个队列,预先占用一定资源
c.公平调度器: 当一个队列没有任务时,它的资源可以被其他队列占用
2.2 spark任务调优 2.2.1 资源(并行度)调优a. yarn-client Driver端运行在本地客户端上,yarn-cluster Driver作为AppMaster运行在NodeManager上,
所以yarn-client可以在本地打日志,一般用于调试程序
b.客户端初始化sparkContext,创建DAGScheduler和TaskScheduler,同时向RM申请启动AppMaster,AppMaster启动后,资源信息下载到
本地,向RM申请资源,申请到资源后,在NM中启动Executor,并将Executor的信息反向注册给Driver,Driver给Executor分发task,运行完成后,
AppMaster、Driver注销自己。
2.2.2 持久化调优executor数量,executor核数,executor内存这三个参数和数据的分片数、分区数匹配(分区数是总核数的2-3倍)
2.3 spark shuffle 2.3.1 HashShuffleManagera. cache,persist,checkpoint
b. RDD重复使用,或者经过很复杂的计算才得到的可以cache或persist下来
c. RDD依赖关系特别长,可以使用checkpoint,也可以使用cache或persist,但计算节点损坏,缓存或存储到磁盘
的数据丢失,需要从头计算,checkpoint把数据存储到HDFS,切断了依赖关系,避免从头计算,使用checkpoint时会在任务运行结束,
再启动一个任务把数据存储到HDFS。
2.3.2 SortShuffleManager文件数量=task数量 * reduce数量,优化后:文件数量=总核数 * reduce数量
2.4 spark Executor统一内存模型文件数量=task数量*2(文件+索引)
2.5 spark算子包括堆内内存和堆外内存
堆内内存包括Storage,用于RDD和广播变量的缓存,默认占用0.6 * 0.5,Execution,用于存储shuffle缓存,计算缓存,默认占用0.6 * 0.5,
这两部分可以动态占用,UserMomory,用于存储RDD转换操作所需要的数据,如RDD依赖信息,ReservedMemory,用于存储spark内部对象,
预留内存,这两部分默认占用0.4.内存占比的参数通过spark.memory.fraction来调解,默认为0.6,动态占用的参数通过spark.memory.storageFraction
来调解,默认为0.5
2.6 spark实现wordcounta.reduceByKey与groupByKey
b.map与mapPartitions
c.repartition与coalesce
d.aggregateBykey
aggregateByKey(“100”)(seqOp, combOp)
seqOp对同一个分区的数据进行合并
combOp对最终不同分区的数据进行合并
e.cogroup :rdd内部相同key的进行合并,两个rdd相同key进行合并
rdd1: (1,2) (1,3)
rdd2: (1,2) (1,3)
-> rdd[(1,(2,3),(2,3))]
sc.textfile().flatMap(_.split(",")).map((_,1)).reduceByKey(_+_).collect()
2.7 spark实现topN
sc.textfile().map().reduceByKey(new MyPartitioner, _+_).foreachPartition( par => par.toList.sortBy(_._2).reverse.take(2).iterator ).foreach(println)2.8 spark发生OOM后如何分析与解决
2.9 spark一定比HIVE快吗一般是Executor端的Storage或者Execution发生OOM,Storage看看是否发生了数据倾斜,Execution看看是否是代码逻辑有问题,
在确保内存足够用的情况下,通过对代码逻辑或数据本身进行处理解决OOM问题,特殊情况下也可以通过调解spark.memory.fraction
来调节。
2.10 spark如何划分宽窄依赖 三、Hbase 3.1 hbase的物理模型和存储架构 3.1.1 habse的物理模型a.Spark一个DAG可以包括多个MR,消除了多个MR间的文件读写IO
b.Spark粒度可以可以控制到现成,MR最细粒度控制到进程,Spark在并行度的优化上有更多空间
3.1.2 habse的存储架构hbase的物理模型由rowkey,列族,列,时间戳构成,本质上是一种KV结构
hbase bigtable横向按rowkey切分,划分成region,纵向按列族切分,划分成store
3.2 hbase读写文件流程 3.2.1 hbase写入流程hbase存储架构主要包括HMaster,Zookeeper, RegionServer
a. HMaster 分配region,RegionServer负载均衡,发现失效region重新分配
b. Zookeeper 保存-ROOT-表所在的位置
c. RegionSever主要包括HLog,BlockCache,Region三个组件
a). Hlog用来保证数据写入的可靠性。默认情况下,写入操作先以追加形式写入HLog,再写入MemStore,RegionServer发生宕机,
MemStore中尚未落盘的数据会丢失,需要回放HLog补数。
b). BlockCache可以将数据缓存到内存中以提高读取性能:三层LRUBlockCache,LRUBlockCache的主要缺点是在垃圾回收的过程中会
产生大量的内存碎片,碎片空间一致累积就会产生FullGC。而BucketCache预先设置好一个连续的内存空间,淘汰算法是通过标记覆盖实现,避免了频繁FullGC的问题。
实际实现中Hbase将BucketCache和LRUBlockCache搭配使用,在LRUBlockCache中 存储IndexBlock和BloomBlock,将DataBlock存储到BucketCache中。
c). Region中包括Store,Store包括一个MemStore,多个HFile
3.2.2 BULKLOAD写入写入的数据添加到本地缓冲区,到zk中找-ROOT-表,根据-ROOT-表找-meta-表,根据-meta-表找到rowkey对应的regionServer,region,
写WAL追加HLOG,写MemStore,达到MemStore阈值(128M),flush到磁盘上生成HFile
3.3.3 hbase读取流程用MR生成为每个region生成HFILE文件,用completebulkload工具导入Hbase(移动到region对应的HDFS目录,
告知region对应的RegionServer,加载HFile文件对外提供服务。
3.3 hbase文件合并机制到zk中找-ROOT-表,根据-ROOT-表找-meta-表,根据-meta-表找到rowkey对应的regionServer,region,
按照region给rowkey划分范围,每扫描一个region构成一次rpc请求,到相应的regionServer中查找BlockCache,MemStore,
没有的话,根据BlockCache文件块索引,HFile索引过滤掉没有的文件块,再扫描可能存在的文件块,获取数据,合并HFile和缓存
的数据,返回结果。
3.4 Region分裂策略a. minor compaction
flush操作后,文件数>n,触发minor compaction,选取邻近的几个小HFile,合并成更大的HFile
b. major compaction(会触发删除) :将Store所有HFile合并成一个大HFile
检查万minor compaction触发条件后,会检查文件的最早生成时间,默认7左右,早于7天,触发major compaction,也可以手动触发。
c.文件合并过程
读取待合并文件进行归并,写到临时目录,将临时目录文件写到store目录,将合并的日志写到HLog,执行同步,删除输入文件。
3.5 hbase性能调优 3.5.1 读优化a. Region中最大Store达到阈值触发分裂
b. 在a基础上,阈值会动态变化,region越多,阈值越大
c. 在b基础上,如果region个数为1,分裂阈值为flushSize*2,否则为设置的最大值
3.5.2 写优化a.服务端 读请求是否均衡,BlockCache设置是否合理,HFile文件是否太多,文件合并是否消耗资源过多
b.客户端 scan缓存设置是否合理,get是否使用批量求情,是否显示指定列族和列
c.列族设计 列族是否做优化(布隆过滤器)
3.5.3 FullGC优化a.服务端 region是否太少,写入是否均衡
b.客户端 是否可以用BulkLoad,是否可以批量提交,写入KeyValue是否太大
3.6 hbase二级索引 3.6.1 局部二级索引a.CMS 标记清除 导致内存碎片
b.G1 标记整理 增量式地处理内存碎片
3.6.2 全局二级索引在各个Region内部建立索引,保证主表和索引数据的一致性
3.7 hbase rowkey怎么设计为了保证原子性,需要可靠的跨Region跨行事务保证
3.8 跳表长度(16个字节) 唯一 散列(高位散列+低位有序,散列的方法:加盐、前缀哈希、反转)
a.保存用户操作记录里:rowkey=反转[userid]#[Long.MAX_VALUE - 当前时间戳],可以查询指定userid某段时间的记录
b.scan场景,注意读写热点
3.9 布隆过滤器的使用MemStore底层数据结构就是跳表,时间复杂度O(logN),本质上就是在链表上加多层索引,采用跳表避免了昂贵的锁开销。
3.10 LSM树bitmap+多次hash的数据,可以判断数据一定不存在或可能存在。
建表时可以设置布隆过滤器,布隆过滤器由LRUBlockCache维护,生成的HFile文件除索引外还包含布隆过滤器
包括ROW模式和ROWCOL模式,通过这两种模式过滤HFILE文件块。
举例:rowkey=userid#otherid,按userid进行前缀扫描(布隆过滤器),会直接过滤哪些不包括userid的文件块。
LSM树的索引结构本质是将写入操作全部转化为磁盘的顺序写入,极大地提高了写入性能。
内存中跳表,达到阈值将数据flush到磁盘中,保存的为顺序的KV数据
//todo



