大数据
2021-08-20 13:32:33 2 举报
AI智能生成
登录查看完整内容
大数据面试总结
作者其他创作
大纲/内容
YarnScheduler
Applications Manager
处理客户端请求
启动和监控Application Master
监控NodeManager
资源分配与调度
资源管理器
ResourceManager
管理节点所有事情
NodeManager
管理任务所有事情
job生命周期内的
ApplicationMaster
Container
服务角色
FIFO(一条队列)
Capacity(多条队列,队列内可以嵌入fair)
Fair(资源共享)
调度器
job id
作业提交
MRAppMaster
作业初始化
分配Maptask
任务分配
运行Maptask,完成后再申请ReduceTask
任务运行
其他的任务进度与作业完成
提交任务流程
Yarn(使用oozie)
Agent:核心组件
source 负责数据的产生或搜集
source与channel之间存在拦截器
读写块,但容量小,依赖内存,服务挂掉会导致数据丢失
Memory Channel
无数据丢失风险
File Channel
借助kafka做队列功能
Kafka Channel
HDFS Sink
Kafka Sink
sink 负责数据的转发
channel->sink->source
启动流程
Flume
写入os cache与磁盘顺序写入
写入
零拷贝技术
读出
子主题
架构
使用回调函数写入,带上ack,retries,factor参数;消费手动提交offset以及采用redis set进行辅助存储
前中后丢数
丢数
后期做等幂操作
重复消费
同用户,同orderi放到同个partition
顺序消费
异常
Broker注册
Topic注册
生产者负载均衡
zookeeper在kafka中的使用
Kafka
ZAB协议中多次用到“过半”设计策略 ,该策略是zk在A(可用性)与C(一致性)间做的取舍
选主
选主后的数据同步
任何时候都需要保证只有一个主进程负责进行事务操作
Zookeeper原子广播
牺牲可用性与一致性
分布式一致性算法
paxos
paxos偏向理论,raft偏向实践
raft
拜占庭将军算法
数据如何保持一致性?
一致性C
可用性A
分区容错性P
CAP
ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能
持久节点
临时节点
持久顺序节点
临时顺序节点
Znode
zab 协议也就是paxos 算法的变种
Zookeeper Watcher 机制
管理Kafka原始数据
使用场景
统一配置管理(例如:统一管理配置文件)
统一命名服务(例如:负载均衡,但nginx的吞吐更好)
分布式锁
抽象场景
每个znode节点上限1M
最小节点2N+1
细节点
定位:高可用、高性能,读多写少的场景
分布式协调服务
Parquet的列式存储是最优存储方式
MPP SQL
解耦,提升扩展性
在Catalog与impalad之间,做消息传递用,维护impalad进程转态
Statestore(发布订阅系统)
元数据服务
Catalog
query planner
query coordinator
query executor
Sql解析,执行计划生产,数据查询,聚合,返回
Impalad
Impala
开辟永久flink集群资源(yarn-session.sh)
临时yarn集群,一个job一个flink集群,集群的生命周期就是job的生命周期
flink on yarn
Actor系统
调度
保证容错性的核心
检查点
Jobmanager(包括任务调度,检查点管理,失败恢复)
包含多个task slots,每个卡槽就是一个executors,每个taskmanager就一个jvm,jvm的内存平均分给每个task slot
Taskmanager
Job Client负责提交任务给Job manager
架构:Jobmanager与Taskmanager
算子如Dataset
Tumbling window(滚动窗口)
Sliding Windows(滑动窗口)
Session window(会话窗口)
Global window(所有数据放到一个窗口)
Window
窗口函数就是这四个:ReduceFunction,AggregateFunction,FoldFunction,ProcessWindowFunction
WindowAll
DataStream(三大逻辑结构:source、transform、sink)
fromCollection
readTextFile(文件、目录、压缩文件都可)
source算子
Map
flatMap
mapPartition
filter
reduce
reduceGroup
minBy和maxBy
Aggregate
distinct
first
join
leftOuterJoin
cross
union
rebalance
partitionByHash
partitionByRange
sortPartition
Transform
collect
writeAsText
KafkaSink
RedisSink
ElasticsearchSink
自定义Sink
Sink算子
DataSet
两大api
广播变量
预加载
热存储
维表Join
flink的时间有三个:事件时间、接入时间、处理时间;默认是处理时间;接入时间和处理时间都不会出现迟到的数据
state
checkpoint
watermark
概念点
flink(练习API的同时练习重写source与sink)
如何做到近实时抽取
列式存储
如何做到近实时分析
两大优势:更新删除、时间漫游
写时复制,读时合并
Hudi数据湖(个人理解:整合了列式存储+增量更新);Hadoop Upserts Delete Incrementals
hive更新 ? 答:分区覆盖法 ;Hudi的优势就出来了,可以直接更新(通过写时复制,读时合并)
Hbase更新?答:比较简单,直接覆盖即可
es更新? 答:没什么好办法,查询删除
大数据更新思考
row_number
连续登陆三天以上用户
遍历
hash大文件变小文件
bigmap和布隆过滤器
海量数据找数据
问题
Hue管理平台
Azkaban
Oozie调度平台
sqoop数据同步工具
datax数据同步工具
其他
eidt logs编辑日志
fsimage镜像文件
NameNode(保存文件目录快照由以下组成,Hadoop1.0由secondaryNamenode定期合并两者数据)
定期向NameNode汇报信息
DataNode
hadoop2.0以后不在使用这种方法,双namenode随时切换,使用journalNode进行数据同步,同时journalNode记录最近edits
SecondaryNameNode
负责将数据切块
Client
client请求namenode分配写入地址,client直接流式写入datanode数据块,写完返回给client,client向namenode汇报
client请求namenode获取数据块地址,然后client直接从datanode读取数据
读取
读写流程
内存上的影响
单namenode的解决方案
Federation
Federation layer中的router服务对外提供服务,会将block访问引致对应子集群
Router-Based Federation
Federation
Router-Based Federation 方案
HDFS
Split
环形缓存使用逻辑(equaltor,kvindex,bufferindex)
输出到环形缓存
Spill/Sort(排序并且溢写到磁盘)
合并文件并且Partitioner,将不同数据分到不同reduce(默认hash(key) mod R进行分区)
Shuffle(分map端与reduce端)
Reduce
小表关联使用:Distributed Cache
MR会逐步被Spark代替,MR过于笨重,执行DAG(有向无环图)才是大势所趋。但是稳定性能MR还是比较好,数据也存盘
MapReduce
partitioner分区数量就是reduce数量也是形成文件数据量
将key分配到不同reduce中,默认是hashParitipner,可以自己实现分区机制,以满足业务或者数据平衡
Partitioner
本地合并,减少网络传输;本地先来个合并,属于优化操作;比如在做统计的时候,自己本地先合并一次
combine
combainer、partition、多个mr
mr
hive.map.aggr,嵌套sql,以达到多个mr效果
hive
数据倾斜
Hadoop RPC
NameNode
HistoryServer
任务历史服务器,默认不开启
JobHistoryServer
进程
Hadoop(最新3.1)
弹性分布式数据集,实际运算过程就是有向无环图,惰性求值
Spark RDD两大操作
发生shuffle,会进行数据重分区,并以此划分stage,一个stage包含一个或多个task
宽依赖
父辈RDD只能被一个子RDD相关联,不会发生shuffle
窄依赖
RDD依赖
根据前后关系再执行一遍
Linage
在关键点出进行checkpoint,再执行一遍
Checkpoint
Spark故障恢复
以action边界生成DAG图,从末端开始以shuffle划分stage
根据宽分区划分Stage
DAGScheduler
把stage里面的taskSet分配到Executor运行,(遵循\"计算向数据靠拢\")(调度模式可以FIFO,也可以是fair)
TaskScheduler
Spark Core
Spark SQL
数据输入需要可靠的sources和可靠的receivers
应用metadata必须通过应用driver checkpoint
WAL(write ahead log)
receivers与Kafka direct
消费Kafka保证数据不丢失
Spark Streaming
MLlib
GraphX
框架
Spark的Shuffle
概念:1.一次action操作会触发RDD的延迟计算,我们把这样的一次计算称作一个Job。2.Spark将宽依赖为划分界限,将Job换分为多个Stage,Stage有TaskSet=多个task
Spark
store又memstore与storeFile(小B+树/HFile)组成
一个region里面有一个或者多个Store,每个store表示一个列族
一个regionserver里面有多个region,每个region对应一个表。region会不断切分
HFile结构
一个master,多个regionserver
(数据模型)逻辑结构与物理结构
LSM树就是一堆小树,在内存中的小树即memstore,每次flush,内存中的memstore变成磁盘上一个新的storefile,最终Compact也将合并成一棵大树
zookeeper(meta-region-server)->meta->region->LSM(root表已经取消)
从Meta表中找到具体Region
从Root表找到Meta Region
从ZooKeeper中找到Root region
HBase读取流程(读写流程基本一致)
当多个StoreFile达到固定大小会合并成一个StoreFile(Compact合并操作),StoreFile过大将会Region拆分
MemStore达到一定大小生成StoreFile
zookeeper->meta->region->写入HLog,再写入MemStore
WAL
HBase写入流程
HFile的Bulkload
建表的时候跟进数据规律提取分开区
预分区
散列值
读写优化
HBase协处理器
Root表与Meta表结构相同,区别在于:当meta大到需要划分region的时候,那么meta表就会存在于不同的两个服务器,遍历复杂,所以就引入root表。默认root表不会超过一个region,确保三次跳转可以定位到region
zookeeper->meta->region->LSM
做范围查询时会产生随机读取IO,进而影响效率
随机写也会产生大量写IO,进而影响效率
B+树,hbase不使用B+树应该是,要旋转树,使其保持平衡
通过批量存储避免大量随机读写
多棵小树
LSM与B+树的存储引擎一致
hbase 跳跃表实现有序,空间换时间
SSTable
LSM
https://zhuanlan.zhihu.com/p/181498475
https://zhuanlan.zhihu.com/p/98751989
LSM(日志结构合并,日志写和B+树的折中,hbase是使用跳跃表组织数据)
让一个region host在多个regionserver上
数据最终在HDFS上,某一个regionserver的主region挂了,其他region replica启用
Region Replica
拆分日志,把各个region日志放在region旁边(recovered.edits目录)
拆分
读取recovered.edits目录进行数据恢复,基于序号ID读取,小于等于就忽略
恢复
RegionServer挂掉,HMaster会重新分配Region到新的RegionServer上
和es差不多,先恢复region,再恢复log
Region恢复
Region合并
最大长度64KB,实际应用中一般为10~100bytes
ASCII编码;中文两个字节,英文一个字节
编码
key设计相关
主ID作为Key
列=标签名称;value=分数值
从Hive层的DW层导入
标签存储思考
HBase
Hive底层基于MR
Hive Metastore Federation
Hive元数据服务
Hive服务
字符函数
数字函数
日期函数
...
sum
count
avg
max
min
collect_list
collect_set
聚合函数
常规函数
搭配聚合函数
row_number over(组内排序)(row_number() over(partition by sex order by age desc))
排序,比如分数排名的场景;并列第一,有间隔(1,1,3)
rank over(组内排序)
dense_rank over(组内排序)
LAG窗口之前N个数
LEAD窗口之后N个数
FIRST_VALUE组内排序第一个
LAST_VALUE组内排序第二个
窗口函数(over)
列转行-concat_ws
行转列/列转行
get_json_object
JSON解析
row_number后,算差值,然后再做group by + having
实现连续3天登录
高阶函数
Hive函数
分区
Join字段建表的时候定义桶
桶内数据也可以排序(clustered by(id) sorted by (id) into 4 buckets)
实际生产中分桶策略使用频率较低
分桶
Parquet
不支持分块
ORC
LZO
所以在实际生产中,使用Parquet存储,lzo压缩的方式更为常见;数据量不大可以使用ORC(几个G)
存储格式
压缩方式
表设计优化
列裁剪
分区裁剪
set hive.merge.mapfiles = true
合并小文件
控制map/reduce数量
小表放前面
join优化
group by 优化
order by 优化
采用group by代替count(distinct)
count distinct优化
一次读取多次插入
启动压缩
hive.groupby.skewindata为true;hive.map.aggr=true
语法与参数的优化
hive.map.aggr 本地聚合;嵌套sql,以达到多个mr效果;多个mr,hive.groupby.skewindata = true
过滤异常Key
拆分表减少数据
打散Key分布
如何可以加内存就加内存
Join数据倾斜三板斧
Hive优化
DM(data mark)/ADS
DWM(middle)(中间表)
DWS(service)(轻度汇聚表)
DWD(detail)(数据明细表)
DIM(维度/字典)
DW(按照主题进行建模)
ODS(operational data store/不等同于原始数据,要做清洗去噪)
流向清晰、减少重复开发
数仓分层依据
数仓分层
清晰的层级,尽可能少交叉,减少重复开发
指标治理
流程规范
数据规范以及数据安全
数据质量
数据治理
Lambda(离线andT+0的实时)
kafka是ods层-》flink sql的清洗是dwd层-》flink sql的聚合得到ads层;ads数据存储到es中
完全使用flink进行计数,数据全部存储再kafka中
Kappa,相对于Lambda是移除了离线部分
clickhouse
es
实时OLAP(依赖于引擎来实现)
不能完全照搬层级
有界数据
无界数据
JobManager与taskManager组成,client提交数据
flink小拓展
实时数仓
Hive
Filesystem Cache
数据预热
冷热分离
避免使用复杂的查询语句(Join 、聚合),就是提前设计好合理doc,利于查询
Document模型设计
不允许深度分页
只支持遍历分页
分页性能优化
普通搜索
聚合搜索
term Query与Filter,filter有缓存,而且不计算相关性
查询语句优化
搜索优化
构造分片迭代器,确定搜索策略
构造异步请求action,转发到各个节点
在节点上ShardSearchTransportRequest,进行查询操作
执行查询,确定是否查询缓存
计算文档相关性
Fetch阶段,合并各个分片数据,返回结果给客户端
搜索流程
get是实时的,直接读取tranlog
查询的大部分都在lucene中
都是声明.del文件,查询再过滤
小segment不断合并
合并过程中会根据del文件内把声明删除数据不进行删除,从而达到删除效果
segment合并相关
删除与更新
默认分片是5,副本是1
分片大小最好是50G以内,副本随意
分片数与机器数持平
elasticsearch分片与副本的思考
Java head分配更小,6.25%到25%
使用聚合
Java head分配50%,留给lucene50%
不使用聚合
es内存分配思考
String,5.0版本以后,不在支持String
text与keyword,要分词使用text,不分词使用keyword
字符串类型
byte
short
integer
long
float
double
half_float
scaled_float
数字类型
日期类型
布尔类型
二进制类型
范围类型
核心数据类型
数组类型
对象类型
嵌套类型
复杂数据类型
地理点类型
地理形状类型
地理数据类型
IP类型
计数数据类型
专门数据类型
elasticsearch数据类型
replica
p_shard
c_node(route)(协调节点)
client
分布式的写流程:一主多副,直到最后一个副本写完才算成功
写入内存buffer同时写入translog(每5s fsync刷新到磁盘)--->1s后refresh刷入segment(segment会定时合并)--->30分钟后会把数据flush从os cache持久化到 disk。数据库先写log再写内存,es是先写内存再写log。es内存里面的东西每1秒(最低可为300ms)转换成segment,这时才会被搜索到。
RestController会绑定所有action,所有就走到了RestBulkAction(guice绑定这个),然后通过nodeclient转发到Transport层(TransportAction对应的具体对象是TransportBulkAction)--TransportShardBulkAction--indexShard--engine(InternalEngine)--最终调用到(实现从es到Lucene的转变)--Lucene的IndexWriter
具体写入与优化
假如要求极高可靠性,那就要把translog每次有请求都需要刷新到磁盘
写入流程(写入流程至关重要)
拿到内存中加锁操作,最后写入segment的时候将之前的同id数据删除掉
合并字段后使用agg,大于1就是重复
es去重
删除操作
使用G1垃圾收集(相比CMS更加容易控制GC停顿时间。 另外G1不会像CMS那样产生内存碎片,对于大堆回收垃圾的效率更高)
对于时间段细微变化的查询,缓存是累赘。1.要么更改时间,不要太多细微2.要么修改源码去除缓存
GC算法改为G1或者ZGC
JVM堆内存不要分配超过31G
关闭linux交换分区
配置专门的协调节点
其他优化
查询子语句缓存,以便下次同样的查询语句直接取缓存数据
filter cache/query cache
1.dsl的缓存2.分片级别缓存 3.默认不开启 4.分片有改变的情况下很快失效(默认情况下1s失效)(Request Cache缓存失效是自动的,当索引refresh时就会失效)5.缓存大小为jvm1% ,对于实时应用基本没有什么优化余地
request cache
JVM 内存堆
使用于analyzed的String分词字段
fielddata cache
是倒排索引的一种补充
聚合,排序、脚本、子父文档关系
之前,我们会建议分配机器内存的 50% 来给 JVM Heap。但是对于 Doc Values,这样可能不是最合适的方案了。 以 64gb 内存的机器为例,可能给 Heap 分配 4-16gb 的内存更合适,而不是 32gb
因为 Doc Values 不是由 JVM 来管理,而是由操作系统的内存来管理
使用堆外内存
列式存储压缩
script访问doc属性
各种方法缩小数据,以便可以放到内存里面进行计算
Global Ordinals(映射结构)
doc_values
桶(bucket)和指标(metric)
group by源码解析
前面两种的聚合原理:
fielddata cache与doc_values正排索引用于聚合排序
三种缓存
elasticsearch script(做些特殊需求,搜索聚合满足不了的需求)
在ElasticSearch里面有filter cache这个过滤器缓存,大部分使用filter这个查询的语句都会缓存下来。但是在index不断增大的时候,缓存就会无用?那如何解决?答:Segment合并或者被删除时,缓存失效
一般多少次查询会构建缓存,有2次的,5次的,4次的,详情看源码UsageTrackingQueryCachingPolicy
分片恢复:先对比meta,meta不同进行segment的对比。将不同的segment发送到待恢复节点,第二阶段发送tranlog到目标节点
分片恢复并发数配置过高造成占用线程过多(node_concurrent_recoveries )
通用线程池用满,增删操作卡死
(ES 6.4.3)分片恢复造成的分布式死锁
疑问总结
全文检索原理
主要内容:索引与检索
TF/IDF
BM25
相识度评分算法
lucene
逻辑结构:index-》type-》docment-》fieid
物理结构:index-》分片-》segment;请求将doc写入index buffer与tranlog此时不能搜索,然后写入file cache(以segment段形式存在)可以搜索,然后写入磁盘并删除tranlog
Segment info,filed name,term dic
https://lucene.apache.org/core/7_3_0/core/org/apache/lucene/codecs/lucene70/package-summary.html
Segment有哪些文件,都可以在这找到
其中有一个.tip文件就是FST文件
一个ES index包含多个分片,每个分片也是一个lucene索引,一个分片里面有很多分段(segment)。默认每秒生成一个segment
tiered
log_byte_size
log_doc
segment合并策略
segment memory
filter cache
field data cache
bulk queue
indexing buffer
state buffer
超大搜索聚合结果集的fetch
对高cardinality字段做terms aggregation
https://www.jianshu.com/p/4a99886ba785
ES的heap是如何被瓜分掉的
elasticsearch存储结构
图片二
倒排索引
DocId实际上并不在Index内唯一,而是Segment内唯一,所有Segment的DocId都是从0开始取值,如何做到index唯一呢?答案:会根据所在Segment进行一次二次转换,这样做,每个Segment内的Docid基本一样(除非删除导致差异),方便压缩优化。但取值的时候会进行转换变为唯一
Sequence Number(DocId)
基本概念
term非常多的时候,如何定位到term呢?(解决办法:term的查找定位从二分查找-->hashmap-->FST)
核心就是基于term的反向链表
倒排索引的模型
共用前缀
FST
SkipList做多层索引,减少对比次数
使用FST和SkipList实现了底层存储:FST前缀搜索和压缩率都有优势,SkipList则用空间换取时间
使用FST定位到term反向链表后,反向链表内部使用跳跃表(SkipList)存储数据
FST慢于HashMap
FST在ES7中存储在了堆外内存
term的查找定位从二分查找-->hashmap-->FST
二重for循环法,X
拉链法
水平分桶,X
bitmap,X
跳表
理解跳跃表的前提下,做倒排合并
倒排合并
KDB-Tree实际是一棵特殊的多维度B+Tree
segment合并的过程类似HBase StoreFile合并
类似LSM树
BKDTree:用于范围查询
利于做聚合统计和排序等,不利于事务类型操作,属于OLAP
便于压缩存储
1.最小公约数2.小于255对应表,3.做差值
映射表将数据尽可能映射小,然后方便做聚合
global ordinals
Doc'Value
查询原理
IndexWriterConfig
核心的增删查改操作+flush+commit+merge
数据路径
并发模型
add & update
delete
IndexWriter
索引结构(1)
索引结构(2)
lucene原理
数据模型
查询
elasticsearch功能
cluster
allocation
discovery
gateway
indices
http
transport
engine
elasticsearch主要模块
选举主节点
选举集群元数据
选举主分片与副分片
index recovery(恢复)
集群启动流程
Discovery
bully选举算法
选主流程
分布式一致性原理:node
分布式一致性原理:meta
分布式一致性原理:data
3个将军都有一个随机倒计时( 150ms 到 300ms),前面倒计时结束的将军封自己为大将军候选人,并且通知询问其他人可否当选(多数赞成即可)。当选后,定期发送心跳重置TimeOut维持现状
简化版拜占庭将军问题
分布式选举\\共识算法:Raft
Paxos
elasticsearch架构
根据metadata确定是否需要恢复,先复制差异的segment,在复制tratranlog
分片恢复
segments merge 流程分析
segment如何使用堆外内存
源码架构
源码分析
Lucene
Elasticsearch
聚合分析使用clickhouse
多维搜索/全文检索使用es
主流趋势:es迁移到clickhouse,es优势是倒排索引,docvalue的列式存储相对于clickhouse反而是鸡肋。分析型还是需要使用分析类数据库clickhouse(OLAP)
整体架构
写入流程
查询流程
{column_name}.bin文件
primary.idx
{column_name}.mrk2
列式存储(Clickhouse存储和查询数据的核心基础)
CompressionMethod_CompressedSize_UncompressedSize
压缩块中的元数据
64KB~1MB
数据已排序
压缩块中的压缩数据
LZ4和ZSTD
数据分块压缩(列式存储中,数据是分块的,一个bin中是有多个压缩块)
数据块索引
ClickHouse快的原因
ClickHouse
大数据
0 条评论
回复 删除
下一页