Hadoop
- hdfs适用的场景
- 存储量非常大,TB级,高吞吐量,对延时无要求
- 流式数据访问,一次写入,多次读取
- 运行在普通机器,节约成本
- 高容错性
- hdfs不适用的场景
- 低延时数据访问,如ms级
- 大量小文件,文件系统的文件数量受限于NameNode的内存大小(100万个文件,元数据占据空间300M)
- HDFS采用追加(append-only)方式写入数据,不支持文件随机写和并发写
- hdfs上的每个块,为什么要存储多个副本?
- 冗余存储,提高可靠性
- 提高文件随机读和并发读效率
- NameNode会做哪些工作
- 保存文件元数据信息
- 决定数据块存在哪个DataNode上
- 接收心跳信息和块的状态报告,若某个DataNode宕机,则将其数据进行新的复制
- 抽象成数据块的好处
- 一个文件可能大于集群中的磁盘
- 用块作为文件的逻辑单位,可简化存储子系统
- 适用于数据备份,提高容错能力
- 机架感知策略
- 第一个副本块存本机
- 第二个副本块存本机同机架内的其他服务节点
- 第三个副本块存不同机架的节点上
- 文件写入过程
- Client发起文件上传请求,通过RPC与NameNode建立通讯
- NameNode根据机架感知原理进行文件分配
- Client请求3台DataNode中的一台node1上传数据,node1调用node2,node3建立连接
- Client向node1发送block,再水平复制到node2,node3
- 文件读取流程
- Client向NameNode发送RPC请求,确定文件block所在位置
- NameNode返回block列表,根据距离排序
- Client选取排序靠前的DataNode,并行完成bolck块的读取
- 将读取的block合并成一个完整的文件
- SecondaryNamenode作用
- 保证元数据的高效检索(存到内存)
- 保证元数据的安全持久(元数据存到fsimage文件,元数据操作记录保存到edits)
- SecondaryNamenode辅助NameNode完成fsimage和edits的合并
- 合并条件:edits中的操作记录超过100w条,或超过60min
- 一般开始时对namenode的操作都放在edits中,为什么不放在fsimage中?
- 因为fsimage是namenode的完整的镜像,内容很大
- 如果每次都加载到内存的话生成树状拓扑结构,非常耗内存和CPU
- MapReduce执行过程
- Map:映射
- Reduce:规约
- Shuffle包括哪些步骤,具体作用?
- 分区(Partitioner):将map输出的结果按key的hash运算结果,分发给不同reduce(避免数据倾斜),可通过指定分区,将同一分区的数据发送到一个reduce task中处理(默认分区1)
- 排序(Sortting):默认按Key排序,可通过自定义比价器改变排序规则
- 归约(Combiner):分区之后,对map端的输出做一次合并,减少map和reduce之间的网络数据传输,某些场景(平均值、中位数不可使用)
- 分组(Grouping):分区之后,决定哪些数据作为一组,一组调用一次reduce方法,如自定义对象,根据属性分组(默认按key分组)(例:求每个订单中金额最大的商品)
- 谈谈Yarn
- 统一:资源不与计算框架绑定,资源对应用无差别,包括长应用、短应用、数据库、后端服务等
- 资源管理:CPU、内存、磁盘、网络带宽等
- 调度器:集中式调度器、双层调度器、状态共享调度器
- ResourceManager:主节点,包括Application Master 和 YARN Scheduler
- NodeManager:从节点,管理Container生命周期
- Application Master:二级调度器,运行在Container中
- Container:资源表示模型,YARN资源表示模型
- Task:计算任务,运行在Container
- 作业流程
- 客户端向ResourceManager提交MapReduce作业
- RM向NM发出指令,为该作业启动Container,并启动AM
- AM向RM注册
- AM采用轮询方式向RM申请资源
- AM申请到资源后,与NM通信,启动计算任务
- NM根据资源量大小,运行环境在Container中启动任务
- 各任务向AM汇报自己的状态和进度
- 应用程序运行完后,AM向RM注销并关闭任务
- 分区与分组的区别
- 相同key的数据会落到同一个分区
- 同一个分区中,可能有多种key的数据(如2,5,8 mod 3)
- 分组比分区粒度更细
HBase
- 特点
- 海量存储,列式存储,易扩展,高并发,稀疏,数据多版本
- 数据模型
- 列族,列,行,时间戳
- 架构模型
- client:通过RPC与HRegionServer通信
- hdfs:存储数据
- HMaster:管理表和HRegionServer
- HRegionServer:响应客户端读写请求,管理Region
- zookeeper:实现HMaster高可用,保存HBase元信息meta表,监控HMaster和HRegionServer
- HBase和HDFS关系
- HBase存储数据到HDFS
- HBase和Hive区别
- hive是数仓工具,用于数据分析
- HBase是nosql数据库,用于海量数据实时插入、查询
- HBase写入数据后,Hive进行分析
- HBase和es关系
- es适合海量数据检索
- HBase数据量太大时,查询效率变低,可使用二级索引加快查询,二级索引可保存到es中
- 应用场景
- 交通:船舶GPS,全长江传播GPS,每天1kw数据
- 金融:消费,贷款,信用卡信息
- 电商:交易,物流,游览信息
- 电信:通话,语音信息
- Region Server组成
- HLog:一个或多个,保证数据写入的可靠性
- BlockCache:一个,将数据块缓存在内存中提高读取性能
- Region:多个,每个都包含所有列簇数据(水平切分)
- Store:多个,存放不同列簇数据(垂直切分)
- MemStore:一个,在内存中存放列簇数据
- HFile:多个,将数据存放在HDFS上
- Store:多个,存放不同列簇数据(垂直切分)
- HBase读流程
- client与zookeeper通信,找到meta表的region位置
- 读取meta表数据,获得要写入表数据所在region的位置信息
- client与regionserver通信,查找对应的region,如果没有,再到blockcache上查找
- 如果没有,再到storefile上查找
- 读到数据后,先把数据写入blockcache,再返回给客户端
- HBase写流程
- client与zookeeper通信,找到meta表的region位置
- 读取meta表数据,获得要写入表数据所在region的位置信息
- client与regionserver通信,将数据写入hlog和Memstore
- Memstore容量超过阈值后,执行flush操作,将内存数据写入文件,形成hfile
- 将数据导入HBase有哪些方式,各有什么特点
- bulkload:可将现有文件直接转换成HFile格式,可加载大量数据,速度快
- kakfa-->spark streaming-->hbase:用于实时数据
- rowkey设计原则
- 长度:太长占空间,太端重复概率大
- 散列:将高位作为散列字段,提高数据均衡性(查询效率降低)
- 唯一:按字典顺序排列,保证唯一
- 如何解决热点
- 预分区:让表的数据均匀分散在集群中
- 加盐:在rowkey前增加随机数
- 哈希:使负载分散到整个集群
- 反转:使rowkey中经常改变的部分放在前面
Hive
- 为什么会有Hive,优缺点
- MapReduce编程复杂,不易满足变化的需求
- 基于Hadoop的数仓工具,做海量离线数据统计分析,将SQL转化为MapReduce,容易上手
- Hive本身不存储任何数据,用hdfs存储任务数据,用Mysql存储元数据
- 延迟严重,不支持事务
- 内部表和外部表的区别
- 外部表创建时加==external==关键字
- 内部表删除后,表的元数据和真实数据都被删除;外部表删除后,仅把元数据删除,真实数据在HDFS中
- 内部表用于数仓的DW层,外部表用于ODS层
- 分区和分桶的区别
- 每个分区表对应一个HDFS文件(夹)
- 分桶将某个数据内容取hash值,相同hash值的数据进入一个文件中
- 分桶粒度更细
- Hive和HBase的关系
- 两种基于Hadoop的不同技术
- Hive是类SQL引擎,HBase是NoSQL数据库
- Hive适合分析、join,HBase适合实时查询或写入
- Hive表中分析结果保存到HBase表中(Hive中创建映射表作为中介)
- 创建Hive外部表,映射HBase中已有的表模型,分析其数据
- 数据存两份,可不考虑整合
Zookeeper
- 简述ZAB协议以及zookeeper
数仓
- 数仓特点
- 面向主题:分析具体某个业务方向的数据
- 集成:多种数据源,如不同的日志服务器、库等
- 非易失:数据进入后就不会轻易修改或删除
- 随时间变化:通过分析历史数据,得到趋势
- 数仓与数据库区别
- 内容是当前数据 / 历史数据
- 面向业务,程序 / 面向主题,分析
- 动态变化 / 静态,不能直接更新
- 结构化,复杂 / 简单,适合分析
- 数仓分层架构
- ods(Operation Data Store):原始层,直接从原始数据得来
- dw(Data Warehouse):中间层,存放数仓明细数据,数据整合和ETL处理后得到
- res:结果层,从中间层查询后,输出到关系型数据库中,提供给业务人员或报表使用
- 数据仓库和数据库、中台的区别
- 数据库是OLTP,面向事务设计,存取业务数据,考虑范式避免冗余,用于捕获数据,实时性,优先考虑效率
- 数据仓库是OLAP,面向主题设计,存取历史数据,有意引入冗余,本身不生产数据,用于分析数据,事后性
- 中台汇聚数据更多更广
- 数据仓库一般分几层
- ODS层:保存源数据,作为后续数仓加工数据的来源
- DWD和DWS层:数仓明细及数仓汇总层,数据平台主要内容,ODS层数据经ETL得到
- ADS层:各部门基于DWD和DWS建立的数据集市
- OSM模型
- 目标(Objective):用户使用产品的目标
- 业务策略(Strategy):为达成目标采取的策略
- 业务度量(Measurement):策略带来的数据指标变化
- 如何构建用户画像
- 数据收集
- 给用户打标签
- 构建画像
Spark
- Spark结构
- executor:
- broker:
- 与MapReduce的不同,使用场景
- MR 以进程为单位,速度较慢,用于数据量大,离线计算
- Spark 以线程为单位,速度较快,用于迭代计算,机器学习,实时计算
- 谈谈RDD
- 转换算子(transform):改变、切分、过滤、组合
- 行动算子(action):
- 将转换算子放入有向无环图DAG中,不立刻执行,以避免无谓的计算开销,优化执行计划
- groupByKey和reduceByKey区别
- groupByKey:没有分区内的聚合逻辑,性能较差
- reduceByKey:有分区内聚合逻辑,聚合之后shuffle,全局聚合
- Spark on hive 和 Hive on Spark 区别
- Spark on Hive:SparkSQL处理Hive数据
- Hive on Spark:Hive的引擎是Spark
- SparkSQL优化
- 谓词下推+列裁剪:减少数据量
- 常量替换+常量累加:减少计算量
- SparkStreaming结构
- SparkStreaming常见数据源
- Flume
- Kafka
- TCP套接字
- 什么时候做checkpoint持久化
- spark core 依赖很长,计算复杂(迭代,shuffle)
- 有状态的计算,需要持久化存储历史状态信息
- driver失败,持久化元数据
- SparkStreaming和Kafka如何整合
- receiver模式:
- 直接读取模式:
- 数据的三种消费模式
- at least once:至少消费一次(可能出现数据重复)
- at most once:至多消费一次(可能出现数据丢失)
- Exactly-Once:保证数据消费一次,且仅消费一次(at least once + 幂等)
- SparkStreaming如何保证Exactly-Once
- 接收数据:从Source接收数据
- 转换数据:用DStream和RDD算子转换
- 存储数据:将结果保存至外部系统
- SparkStreaming调优
- 调整BlockReceiver数量
- 调整Block数量
- 调整Receiver接受速率
- 调整数据处理并行度
- 数据序列化
- 内存调优
- Output Operations
- Backpressure(背压机制)
- Elastic Scalling(资源动态分配)
- 数据倾斜调优
- SparkStreaming和StructStreaming的区别
- SparkStreaming:基于批次流处理数据
- StructStreaming:基于无界表,基于SparkSQL实时处理数据
Kafka
- 介绍一下Kafka的特点
- 分布式,基于发布--订阅模式的消息队列,主要用于大数据实时处理领域
- 高吞吐、低延迟:收发消息速度快(每秒几十万条)
- 高伸缩性:每个主题包含多个分区
- 持久性、可靠性:允许数据持久化存储
- 容错性:允许集群中某个节点失效
- 高并发:支持数千个客户端同时读写
- 主要功能
- 发布/订阅:对流数据进行读写
- 实时处理:对流数据进行处理
- 存储:存储流数据
- 为什么引入消息队列
- 异步:用户注册后,发送注册邮件和注册短信
- 串行方式:注册信息写入数据库->发送注册邮件->发送注册短信(150ms)
- 并行方式:注册信息写入数据库->发送注册邮件,发送注册短信(100ms)
- 消息队列:注册信息写入数据库->写入消息队列(55ms)
- 解耦:用户下单后,订单系统需要通知库存系统
- 加入库存系统无法访问,则订单减库存将失败,从而导致订单失败
- 在订单系统和库存系统间增加消息队列,实现解耦
- 流量削峰:秒杀活动,流量过大
- 在前端增加消息队列,控制活动人数
- 异步:用户注册后,发送注册邮件和注册短信
- Kafka集群组件
- client:客户端
- topic:每条发布到kafka集群的消息属于的类型,用于对消息进行分类
- producer:消息生产者,向主题发布消息的客户端
- consumer:消息消费者,订阅主题消息的客户端
- broker:一台部署了kafka的服务器
- partition:每个topic有多个分区
- replica:每个分区有多个副本
- leader:领导者副本,与客户端交互
- follower:追随者副本,不能与客户端交互
- Kafka为什么快
- 顺序读写:将消息持久化到本地磁盘,顺序读写
- 页缓存:利用操作系统本身的内存,而不是JVM内存
- 零拷贝:减少不必要的拷贝次数
- 聊一下ISR
- 保存和leader一致的follower集合
- follower长时间未向leader同步数据,则该follower将被踢出ISR
- 若leader失效,则从ISR列表中选举一个新的leader,保持数据一致性
- 聊一下hw
- 一个分区对消费者可见的下一条数据的offset
- 所有副本中最小的LEO
- 帮助Kafka完成副本同步
- Kafka如何保证数据消费的有序性
- 多个partition时,无法做到全局有序
- 只有在一个partition中可做到局部有序
- Kafka数据分区方式
- 指定key进行分区,key.hashCode % 分区个数
- 直接指定分区号进行分区
- 使用轮询方式进行分区
- 自定义分区规则
- 连接Kafka的两种方式
- Receiver:采用WAL(预写日志),在数据写入内存前进行持久化,防止数据丢失,不能满足“恰好一次”
- Direct:消费者定期轮询Kafka,得到每个topic中每个分区的最新偏移量,作业恢复后直接从Kafka读取数据,Spark Streaming会为每个Kafka分区创建对应的RDD分区,可保证“恰好一次”
- 如何保证数据有序性
- 一个topic一个分区
- 自定义数据的rowkey,保证每个用户的数据有序
参考
mapreduce原理 分区 分组
https://www.cnblogs.com/netskill/p/3912808.html
IntValue & Integer.MAX_VALUE的作用