大数据面试题
注:所有答案来源于网络,仅做整理!!
Flink的高可用
Flink是一种高性能、分布式处理大规模数据的流处理框架,其主要特点是具有高可用性和可扩展性。Flink集群高可用性是指在出现故障的情况下,系统能够自动切换到备用节点,保证系统的稳定性和可靠性。
Flink集群高可用原理主要涉及以下几个方面:
1、Master节点选举机制。Flink集群中的Master节点是负责管理和协调整个集群的节点,其选举机制采用Zookeeper实现。当Master节点发生故障或失效时,Zookeeper会自动选举新的Master节点,确保集群的稳定性。
2、Jobmanager高可用性。Flink集群中的Jobmanager节点是负责调度和执行任务的节点,其具有高可用性。当Jobmanager节点发生故障或失效时,备用Jobmanager节点会自动接替其工作,以保证任务的正常执行。
3、Taskmanager高可用性。Flink集群中的Taskmanager节点是负责处理数据和运行任务的节点,其也具有高可用性。当Taskmanager节点发生故障或失效时,备用Taskmanager节点会自动接替其工作,以保证任务的正常执行。
4、数据持久化和恢复。Flink集群中的数据持久化和恢复机制可以保证任务的数据不会丢失。当节点发生故障或失效时,系统会自动将任务状态和数据进行持久化,并在回复后重新执行任务。
综上所述,Flink集群高可用原理主要是通过选举机制、备用节点、数据持久化和恢复等机制来保证集群的稳定性和可靠性。对于企业而言,选择具有高可用性的flink集群可以提高数据处理效率和减少故障率,有助于提升企业的竞争力和业务价值。
Flink的架构(Flink的组件都有哪些/Flink运行时组件有哪些)
书上总结如下:
分层API(SQL、Table API、DataStream/DataSet API、Stateful Stream Prossessing)、JobManager、TaskManager、Client
网上查找如下:
1.1 Flink架构模型
主要包含四个不同的组件:
作业管理器(JobManager)
资源管理器(ResourceManager)
任务管理器(TaskManager)
分发器(Application)
Flink首先是由Scala和Java实现的,所有的组件都会运行在jvm上,当flink集群启动的时候,首先会启动一个JobManager和一个或多个TaskManager。由client提交任务给JobManager,JobManager再调度任务到一个或多个TaskManager上,然后TaskManager将心跳和统计信息汇报给JobManager,JobManager和TaskManager以流的形式进行数据传输。以上为一个独立的jvm进程。
1.2 角色分配
1.2.1 JobManager
作业管理器是管理整个应用程序执行的主进程
作业管理器首先会接收到各种需要执行的程序,包括作业图(JobGrap)、逻辑数据流图(logical dataflow Grap)和打包起来的各种jar包、类库等。
然后作业管理器会把JobGrap转换成一个物理层面的数据流图,这个图被称为执行图(ExecutionGrap),包含了可以并发执行的任务。
之后作业管理器会向资源管理器申请资源,一旦JobManager获取到所需的资源,就会将执行流图发送给TaskManager去执行。
在执行的过程种,作业管理器会负责所有需要中央协调的工作,比如说检查点的协调。
1.2.2 ResourceManager
资源管理器主要负责管理TaskManager种的slot。
作用:
资源管理器可以向JobManager分配有空闲solt的TaskManager。
如果ResourceManager无法满足作业管理器所需的资源的时候,Resource会向资源提供平台发起会话,以提供启动TaskManager的容器。
ResourceManager还负责结束终止空闲的TaskManager,释放计算机资源。
1.2.3 TaskManager
任务管理器是Flink种的工作进程。
TaskManager启动之后会向ResourceManager注册它的插槽
收到资源管理器的指令后,TaskManager会向JobManager提供一个或多个插槽,作业管理器就可以向JobManager插槽分配任务。
在执行过程中,一个TaskManager可以和同一应用程序种的其它TaskManager交换数据。
1.2.4 Dispatcher
分发器可以跨作业运行,它为应用提供了REST接口。
当一个应用被提交时,分发器就会启动并将移交给作业管理器。
由于是REST接口,所以Dispatcher可以作为集群的一个HTTP接入点,这样就能不受防火墙的阻碍。
Flink的程序模型
1、程序和数据流
程序即是留和转化组成的数据流。
2、并行数据流
3、窗口
聚合事件
4、事件
5、有状态的计算
状态:至少一次、之多一次、精确一次
不仅依赖当前数据,还依赖上个窗口的结果即为:有状态
6、容错检查点
7、状态后端
存状态的地方
8、保存点
手动触发的检查点
Flink的程序组成(Flink编程结构/编程模型)
书本总结如下:
获取执行环境,加载/创建数据源,数据转换操作,价格结果Sink入下游,触发程序运行
网上查找如下:
3.1)ExecutionEnvironment
运行Flink程序的第一步就是获取相应的执行环境,执行环境决定了程序是在本地环境执行还是集群环境运行。批量处理和流处理分别使用不同的ExecutionEnvironment。有三种方式获取程序的执行环境
以官方提供的流处理案例:
获取ExecutionEnvironment方式(一):
默认的执行环境创建方式,它会根据上下文去创建正确的ExecutionEnvironment,如果你在IDE中执行程序或者将程序作为一个常规的Java/Scala程序执行,那么它将为你创建一个本地的环境,你的程序将在本地执行。如果你将你的程序打成jar包,并通过命令行调用它,那么Flink集群管理器将执行你的main方法并且getExecutionEnvironment()方法将为你的程序在集群中执行生成一个执行环境。所以getExecutionEnvironment方法在本地执行或者集群执行都可用这个方法。
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
获取ExecutionEnvironment方式(二):
本地执行环境创建方式,当程序在IDE中运行时候,可以通过createLocalEnvironment创建基于本地的执行环境,可以指定并行度
StreamExecutionEnvironment env = StreamExecutionEnvironment.createLocalEnvironment(2);
获取ExecutionEnvironment方式(三):
创建远程执行环境。远程环境将程序发送到集群执行。适用于本地直接发送程序到集群上执行测试。
StreamExecutionEnvironment env = StreamExecutionEnvironment .createRemoteEnvironment("bigdata-pro-m07", 8081,"WordCountJava.jar");
(3.2)初始化数据
-
readTextFile
-
socketTextStream
通过读取文件并转化为DataStream[String]数据集,这样就完成了从本地文件到分布式数据集的转换,同时在Flink中提供了多种从外部读取数据的连接器,包括批量和实时的数据连接器,能够将Flink系统和其他第三方系统连接,直接获取外部数据。
(3.3)执行转换操作
Flink中的Transformation操作都是通过不同的Operator来实现的,每个Operator内部通过实现Function接口完成数据处理逻辑的定义。在DataStream和DataSet中提供了大量的算子。如Map、FlatMap、Filter、KeyBy等。
Flink中定义Function的计算逻辑可以通过三种方式完成:
方法一:通过创建Class实现Function接口
方法二:通过创建匿名内部类实现Function接口
方法三:通过实现RichFunction
(3.4)分区key指定
分区的目的是将相同key的value放在同一个partition中 -
根据字段位置指定(Flink1.12不推荐)
官方1.12版本中使用的这种方式:
-
根据字段名称指定(Flink1.12不推荐)
使用字段名称需要DataStream中的数据结构类型必须是Tuple类或者P0J0类 -
通过key选择器指定
基于POJO类型通过key选择器指定key分区代码示例:
package com.aikfk.flink;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.ReduceFunction;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;
/**
* @author :caizhengjie
* @description:TODO
* @date :2021/3/5 3:07 下午
*/
public class WordCountJava3 {
public static void main(String[] args) throws Exception {
// 准备环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<WordCount> dataStream = env.socketTextStream("bigdata-pro-m07",9999)
.flatMap(new FlatMapFunction<String, WordCount>() {
@Override
public void flatMap(String line, Collector<WordCount> collector) throws Exception {
String[] words = line.split(" ");
for (String word : words){
collector.collect(new WordCount(word,1));
}
}
})
// 将相同key的value放在同一个partition(按照key选择器指定)
.keyBy(new KeySelector<WordCount, Object>() {
@Override
public Object getKey(WordCount wordCount) throws Exception {
return wordCount.word;
}
})
.reduce(new ReduceFunction<WordCount>() {
@Override
public WordCount reduce(WordCount t1, WordCount t2) throws Exception {
return new WordCount(t1.word , t1.count + t2.count);
}
});
dataStream.print();
env.execute("Window WordCount");
}
/**
* POJO类
*/
public static class WordCount{
public String word;
public int count;
public WordCount() {
}
public WordCount(String word, int count) {
this.word = word;
this.count = count;
}
@Override
public String toString() {
return "WordCount{" +
"word='" + word + '\'' +
", count=" + count +
'}';
}
}
}
运行结果:
2> WordCount{word='hive', count=1}
3> WordCount{word='java', count=1}
2> WordCount{word='hive', count=2}
2> WordCount{word='hive', count=3}
3> WordCount{word='java', count=2}
2> WordCount{word='hive', count=4}
15> WordCount{word='hadoop', count=1}
(3.5)输出结果
- 输出到控制台
- 输出到文件
- 输出到外部存储
(3.6)程序触发
应用的执行,需要调用ExecutionEnvironment的Execute()方法来触发应用程序的执行,DataStream流式应用需要显性的指定execute()方法来运行程序,如果不调用程序则不会执行;对于DataSet API输出算子中已经包含了对execute()方法的调用,则不需要显性调用execute()方法;
Flink和Spark的区别
1、设计理念不同
flink:Flink是基于事件驱动的,是面向流的处理框架, Flink基于每个事件一行一行地流式处理,是真正的流式计算. 另外他也可以基于流来模拟批进行计算实现批处理。
spark:Spark的技术理念是使用微批来模拟流的计算,基于Micro-batch,数据流以时间为单位被切分为一个个批次,通过分布式数据集RDD进行批量处理,是一种伪实时。
2、架构不同
flink:Flink 在运行时主要包含:Jobmanager、Taskmanager和Slot。
spark:Spark在运行时的主要角色包括:Master、Worker、Driver、Executor。
3、任务调度不同
flink:Flink 根据用户提交的代码生成 StreamGraph,经过优化生成 JobGraph,然后提交给 JobManager进行处理,JobManager 会根据 JobGraph 生成 ExecutionGraph,ExecutionGraph 是 Flink 调度最核心的数据结构,JobManager 根据 ExecutionGraph 对 Job 进行调度。
spark:Spark Streaming 连续不断的生成微小的数据批次,构建有向无环图DAG,根据DAG中的action操作形成job,每个job有根据窄宽依赖生成多个stage。
4、时间机制不同
flink:flink支持三种时间机制:事件时间,注入时间,处理时间,同时支持 watermark 机制处理迟到的数据,说明Flink在处理乱序大实时数据的时候,更有优势。
spark:Spark Streaming 支持的时间机制有限,只支持处理时间。使用processing time模拟event time必然会有误差, 如果产生数据堆积的话,误差则更明显。
5、容错机制不同
flink:Flink 则使用两阶段提交协议来保证exactly once。
spark:Spark Streaming的容错机制是基于RDD的容错机制,会将经常用的RDD或者对宽依赖加Checkpoint。利用SparkStreaming的direct方式与Kafka可以保证数据输入源的,处理过程,输出过程符合exactly once。
6、吞吐量与延迟不同
flink:Flink是基于事件的,消息逐条处理,而且他的容错机制很轻量级,所以他能在兼顾高吞吐量的同时又有很低的延迟,它的延迟能够达到毫秒级;
spark:spark是基于微批的,而且流水线优化做的很好,所以说他的吞入量是最大的,但是付出了延迟的代价,它的延迟是秒级;
7、状态不同
flink:flink是事件驱动型应用是一类具有状态的应用,我们要把它看成一个个event记录去处理,当遇到窗口时会进行阻塞等待,窗口的聚合操作是无状态的。过了窗口后DataStream的算子聚合操作就是有状态的操作了,所以flink要把聚合操作都放到窗口操作之前,才能进行无状态的聚合操作。而spark全程都是无状态的,所以在哪聚合都可以。
spark:spark本身是无状态的,所以我们可以把它看成一个rdd一个算子一个rdd的去处理,就是说可以看成分段处理。
8、数据不同
flink:在flink的世界观中,一切都是由流组成的,离线数据是有界限的流,实时数据是一个没有界限的流,这就是所谓的有界流和无界流。流处理的特点是无界、实时, 无需针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作,一般用于实时统计。
spark:在spark的世界观中,一切都是由批次组成的,离线数据是一个大批次,而实时数据是由一个一个无限的小批次组成的。批处理的特点是有界、持久、大量,非常适合需要访问全套记录才能完成的计算工作,一般用于离线统计。
对于数仓的理解
随着互联网及物联网等技术发展,越来越多的数据被生成,如何有效利用这些数据就成为了企业决胜的法宝了。大型公司会基于数据做出BI、推荐系统、决策支持、统计分析、报表等业务。
其中数据存储涉及众多知识点,本文目的就是对这些名词术语及内涵进行解析,便于读者对数据平台相关的概念有全面的认识。
1 OLTP VS OLAP
1970年随着关系数据库理论的提出,诞生了一系列经典的RDBMS,如MySQL、Oracle、SQL Server、DB2等。这些RDBMS为社会信息化的发展做出的重大贡献。然而随着数据库使用范围的不断扩大,它被逐步划分为操作型数据库OLTP跟分析型数据库OLAP。
1.1 OLTP
操作型数据库OLTP(On-Line Transaction Processing 联机事务处理)也可以称面向交易的处理系统,它是针对具体业务在数据库联机的日常操作,通常对记录进行CRUD。
OLTP模式下用户较为关心操作的响应时间、数据的安全性、完整性和并发支持的用户数等问题。传统的数据库系统作为数据管理的主要手段,主要用于操作型处理。
1.2 OLAP
分析型数据库OLAP(On-Line Analytical Processing)叫联机分析处理,主要用于历史数据分析。这类数据库作为公司的单独数据存储,负责利用历史数据对公司各主题域进行统计分析。为啥要分成操作型跟分析型呢?原因是他们有太多不同了!
对比
1.3 操作型OLTP VS 分析型OLAP
之所以区分为操作型跟分析型,那是因为这俩的核心功能不同!前者主要是面向操作,后者主要是面向分析,在细节上存在众多差异。
1.3.1 数据组成差别
数据时间范围不同:一般操作型数据库只存放90天内数据,分析型数据存放数年内数据,所以这俩要进行物理分离。
数据细节差异不同:操作型数据库主要存放细节数据,汇总数据是动态技术而成的。分析型数据库中既存放细节数据又存放用户关系的汇总数据。
数据时间表示不同:操作型数据库反应的是当前状态,分析师数据库中既又当前状态又有过去各时刻的快照数据。
1.3.2 技术差别
查询数量跟频率不同:操作型数据库查询频率但量小,分析型数据库查询量大但频率小。
数据更新不同:操作型数据库设计到用户CRUD。分析型数据库属于归档性质存储,只提供查询。
数据冗余性不同:操作型数据库在设计表的时候就会减少数据冗余避免更新复杂。分析型数据库中则只有查询功能,因此数据冗余性一般都存在。
1.3.3 功能差别
数据读者不同:操作型数据的使用者是业务环节下的各个角色,比如用户、商家等。分析型数据库一般只有研发跟数据分析人员专门使用。
定位不同:操作型数据库主要是面向应用层的数据库,是为了支持具体业务而存在的。分析型数据库是针对特定业务主体域的分析人物而创建的,是面向主体型数据库。
2 数仓
2.1 数仓简介
数仓发展
随着人类IT发展,数据越来越多被产生,并且这些数据还可能跨部门,跨业务。如何把数据集成起来进行OLAP是个巨大挑战。
数据仓库(Data Warehouse)应运而生,数据仓库是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理中的决策制定。
数据仓库是伴随着企业信息化发展起来的,在企业信息化的过程中,随着信息化工具的升级和新工具的应用,数据量变的越来越大,数据格式越来越多,决策要求越来越苛刻,数据仓库技术也在不停的发展。数据仓库的趋势:
- 实时数据仓库以满足实时化&自动化决策需求。
- 大数据&数据湖以支持大量&复杂数据类型(文本、图像、视频、音频)。
数仓发展
对于数仓可以理解为原来各个数据孤岛中的数据可能存储位置、存储格式、编程语言等各个方面不同。数仓要做的就是把数据按照所需格式提取出来,进行转换、过滤、清洗。最终装载到数据仓库,整个过程也叫ETL。
提取 Extraction:表示从操作型数据库搜集指定数据。
转换 Transformation:表示将数据转化为指定格式,并进行数据清洗保证数据质量。
加载 Load:加载过程表示将转换过后满足指定格式的数据加载进数据仓库。
随着数仓的不断普及跟使用,信息产业就开始从以关系型数据库为基础的运营式系统慢慢向决策支持系统发展。这个决策支持系统,其实就是我们现在说的商务智能(Business Intelligence)即BI。
可以这么说,数据仓库为OLAP解决了数据来源问题,数据仓库和OLAP互相促进发展,进一步驱动了商务智能的成熟,但真正将商务智能赋予智能的,其实是数据挖掘。
2.2 数仓特征
2.2.1 面向主题
面向主题特性是数据仓库和操作型数据库的根本区别。
操作型数据库是为了支撑各种业务而建立,是按照业务功能进行组织的。
分析型数据库则是为了对从各种繁杂业务中抽象出来的分析主题进行分析而建立。
所谓主题是指用户使用数据仓库进行决策时所关心的重点方面,如:收入、客户、销售渠道等。所谓面向主题,是指数据仓库内的信息是按主题进行组织的。
2.2.2 集成性
集成性指数据仓库中的信息不是从各个业务系统中简单抽取出来的,而是经过一系列加工、整理和汇总的过程,因此数据仓库中的信息是关于整个企业的一致的全局信息。
2.2.3 企业范围
数据仓库内的数据是面向公司全局的。比如某个主题域为成本,则全公司和成本有关的信息都会被汇集进来。
2.2.4 历史性
较之操作型数据库,数据仓库的时间跨度通常比较长。前者通常保存几个月,后者可能几年甚至几十年。
2.2.5 时变性
时变性是指数据仓库包含来自其时间范围不同时间段的数据快照。有了这些数据快照以后,用户便可将其汇总,通过这些信息,可以对企业的发展历程和未来趋势做出定量分析和预测。
2.3 数仓架构
2.3.1 架构
数据仓库标准上可以分为四层:ODS(临时存储层)、PDW(数据仓库层)、DM(数据集市层)、APP(应用层)。
DWBI
各个系统的数据通过ETL同步到操作性数据仓库ODS中,对ODS数据进行面向主题域建模形成DW(数据仓库),DM是针对某一个业务领域建立模型,具体用户(决策层)查看DM生成的报表。
临时存储数据运营层:ODS(Operational Data Store):
ODS层将来自不同数据源的数据通过ETL(Extract-Transform-Load)过程汇聚整合成面向主题的、集成的、企业全局的、一致的数据集合。现在可选择的大数据同步技术也比较多,如datax,canal,kafka等。这一层的主要目的是把源系统的数据基本原样(有些数据敏感等级高不同步)的同步到大数据平台,因此比较容易进行方案的统一。
仓库层:DW(Data Warehouse):
DW为数据仓库层,DW层的数据应该是一致的、准确的、干净的数据。主要有清洗,拆分,整合,标准化,备份,隔离几个任务。即对源系统数据进行了清洗后的数据。这一层的数据一般是遵循数据库第三范式的,在DW层会保存BI系统中所有的历史数据,例如保存10年的数据。
DW : Data Warehouse 翻译成数据仓库,DW由下到上分为 DWD、DWB、DWS。
DWD:Warehouse Detail 细节数据层,有的也称为 ODS层,是业务层与数据仓库的隔离层
DWB:Data Warehouse Base 基础数据层,存储的是客观数据,一般用作中间层,可以认为是大量指标的数据层。
DWS:Data Warehouse Service 服务数据层,基于DWB上的基础数据,整合汇总成分析某一个主题域的服务数据,一般是宽表。
集市层:DM(Data Mart):
这一层有一个更直观的叫法是宽表层,前面提到这一层主要是为了解决某一类的分析问题,也就是面向分析,既然是面向分析,那么一般来讲是多个业务过程,而将多个业务过程融合成一个分析主题,势必会关联很多数据。宽表就是这样来的。在OLAP分析工具还不是很成熟的时候,仍然建议构建多维宽表,这样可以避免过多的模型间的关联操作。一般用于机器学习的特征宽表存在于这一层。集市层构建的好坏有一个比较好的衡量标准就是是否可以满足超过80%的应用层数据需要,剩下的20%来源于数仓层。
应用层:Application层:
该层数据完全是为了满足具体的分析需求而构建的数据,从数据的广度来说,则并不一定会覆盖所有业务数据,而是DM层数据的一个真子集,从某种意义上来说是DM层数据的一个重复。面向应用的特点一般有以下几个特征,灵活多变,简单。灵活多变是说业务需要各种形式或者各种自定义口径的数据,如KV结构的,各种条件来计算的。简单指的是数据一般是高度汇总的,如报表或者核心KPI指标。
2.3.2 数仓分层原因
用空间换时间:通过大量的预处理来提升应用系统的效率,因此数据仓库会存在大量冗余的数据。
解耦:不分层的话如果源业务系统的业务规则发生变化将会影响整个数据清洗过程,工作量巨大。
简化:通过数据分层管理可以简化数据清洗的过程,因为把原来一步的工作分到了多个步骤去完成,当数据发生错误的时,往往只需要局部调整某个步骤即可。
2.4 元数据介绍
2.4.1 元数据定义
数仓的元数据Metadata是关于数据仓库中数据的数据。它的作用类似于数据库管理系统的数据字典,可以简答理解为一本书的目录,保存了逻辑数据结构、文件、地址和索引等信息。广义上讲,元数据描述了数据仓库内数据的结构和建立方法的数据,一般我们会用关系型数据库来存储这些数据,比如MySQL。
元数据是数据仓库管理系统的重要组成部分,元数据管理器是企业级数据仓库中的关键组件,贯穿数据仓库构建的整个过程,直接影响着数据仓库的构建、使用和维护。
构建数据仓库的主要步骤之一是ETL。这时元数据将发挥重要的作用,它定义了源数据系统到数据仓库的映射、数据转换的规则、数据仓库的逻辑结构、数据更新的规则、数据导入历史记录以及装载周期等相关内容。数据抽取和转换的专家以及数据仓库管理员正是通过元数据高效地构建数据仓库。
用户在使用数据仓库时,通过元数据访问数据,明确数据项的含义以及定制报表。
数据仓库的规模及其复杂性离不开正确的元数据管理,包括增加或移除外部数据源,改变数据清洗方法,控制出错的查询以及安排备份等。
元数据可分为技术元数据和业务元数据。
技术元数据为开发和管理数据仓库的IT人员使用,它描述了与数据仓库开发、管理和维护相关的数据,包括数据源信息、数据转换描述、数据仓库模型、数据清洗与更新规则、数据映射和访问权限等。
业务元数据为管理层和业务分析人员服务,从业务角度描述数据,包括商务术语、数据仓库中有什么数据、数据的位置和数据的可用性等,帮助业务人员更好地理解数据仓库中哪些数据是可用的以及如何使用。
由上可见,元数据不仅定义了数据仓库中数据的模式、来源、抽取和转换规则等,而且是整个数据仓库系统运行的基础,元数据把数据仓库系统中各个松散的组件联系起来,组成了一个有机的整体,如图所示
在这里插入图片描述
2.4.2 元数据作用
在数仓中元数据的主要作用如下:
描述哪些数据在数据仓库中,帮助决策分析者对数据仓库的内容定位。
定义数据进入数据仓库的方式,作为数据汇总、映射和清洗的指南。
记录业务事件发生而随之进行的数据抽取工作时间安排。
记录并检测系统数据一致性的要求和执行情况。
评估数据质量。
相当于写了一部数据用户指南手册
2.5 数据治理
如果你做过推荐系统跟BI报表等基于数据的系统,你就会知道数据治理的重要性!如果做过机器学习就会知道数据远远比算法更重要。通常我们对数据质量的判断来自准确性、完整性和一致性三方面,然而这三点原始数据通常并不具备,原始数据一般有如下留个特点。
数据重复
字段名跟结构前后不一致
某些记录存在字段缺失
原始数据来源跟格式各不相同
重点数据存在异常值
在做数据清洗时,一般有如下几点规则可寻:
确保原始数据的准确输入
小心处理NA值跟字符串为空的字段
检查字符型变量仅包含有效值
检查数值型变量在预定范围内
检查是否存在缺失数据
检查并删除重复数据
检查特殊值是否唯一
检查是否存在无效数据
数仓如何选型
这道题没明白面试官具体想要问什么,假如要问数仓平台各组件选型,实在太宽泛了,待补充。
如何搭建大数据平台
太宽泛了,待补充。
Flink的算子
算子:
在 Flink 代码中,我们定义的每一个处理转换操作都叫作“算子”(Operator),所以我们的程序可以看作是一串算子构成的管道,而数据则像水流一样有序地流过。
按照功能不同可以大致分为三类,如下:
Source 表示“源算子”,负责读取数据源。
Transformation 表示“转换算子”,利用各种算子进行处理加工。
Sink 表示“下沉算子”或“接收算子”,负责数据的输出。
按照批、流可以分为两类:DataSet和DataStream。
DataStream
- Source算子
1、基于文件
env.readTextFile(...);
env.readFile(...);
2、基于Socket
env.socketTextStream(...);
3、基于集合
env.fromCollection(...);
env.fromElements(...);
env.generateSequence(...);
4、自定义数据源
env.addSource(...); - Transform算子
1、Map
DataStream -> DataStream
1对1的映射,用于解析元素,转换数据类型等。
2、FlatMap
DataStream -> DataStream
1对0,1对1,1对多的映射,多用于拆分不需要的列表和数组。
3、Filter
DataStream -> DataStream
多用于数据去重。
4、KeyBy
DataStream -> KeyedStream
分流处理,将一个数据流分成不相关的多个流分区。
5、Reduce
KeyedStream -> DataStream
合流处理,将KeyedStream中有相同Key的元素合并为单个值,并且总是将两个元素合并为一个元素,将上一个合并过的值和当前的元素结合,产生新的值并发出,直到仅剩一个值为止。
6、Aggregations
KeyedStream -> DataStream
内置聚合逻辑,可以对KeyedStream中具有相同Key的元素进行求和、求最大值或最小值等。keyedStream.sum(...);
keyedStream.min(...);
keyedStream.max(...);
keyedStream.minBy(...);
keyedStream.maxBy(...);
min/max为返回同一个Key分组下指定字段的最小/最大值,minBy/maxBy为返回同一个Key分组下指定字段有最小/最大值的元素。简单理解就是min/max返回最小/最大值,minBy/maxBy返回最小/最大值那一行数据。
7、Split和Select
Split:DataStream -> SplitStream
Select:SplitStream -> DataStream
Split和Select是组合使用的,Split根据用户定义标准将数据流拆分为两个或更多的数据流,Select根据用户定义的标准获取对应的数据流,以便在获取的数据流中执行后续的转换操作。
8、Project
DataStream -> DataStream
用在元素的数据类型是元组(Tuple)的数据流中,它根据指定的索引从元组中选择对应的字段组成一个自己返回。
9、Union
DataStream* -> DataStream
负责将两个或多个相同类型的数据流进行合并来创建一个包含数据流中所有元素的新数据流。
10、Connect和CoMap、CoFlatMap
Connect:DataStream + DataStream -> ConnectedStreams
将连接两个保留其类型的数据流来创建新的连接流,从而允许这两个数据流共享状态。
CoMap:ConnectedStreams -> DataStream
对输入的每个ConnectedStreams元素进行转换并产生1个结果元素输出到新的数据流中,实现的是一个1对1的关系。
CoFlatMap:ConnectedStreams -> DataStream
对输入的每个ConnectedStreams元素进行转换并产生0个、1个或多个结果元素输出到新的数据流中,实现的是一个1对0、1对1或1对多的关系。
11、Iterate
DataStream -> IterativeStream -> DataStream
迭代操作。 - Sink算子
1、基于文件
env.writeAsCsv(...);
env.writeAsText(...);
2、基于标准输出流
DataStream.print();
DataStream.printToErr();
3、基于Socket
env.writeToSocket(...);
4、自定义数据接收器
env.addSink(...);
DataSet
- Source算子
1、基于文件
env.readTextFile(...);
env.readTextFileWithValue(...);
env.readCsvFile(...);
env.readFileOfPrimitives(...);
2、基于集合
env.fromCollection(...);
env.fromElements(...);
env.fromParallelCollection(...);
env.generateSequence(...);
3、配置CSV解析选项
4、递归遍历输入路径的目录 - Transformation算子
1、Map
1对1映射。
2、FlatMap
1对0,1对1,1对多映射。
3、MapPartition
没太看懂怎么用的,待补充。
4、Filter
过滤数据,多用于数据去重。
5、Project
用在元素的数据类型是元组(Tuple)的数据流中,它根据指定的索引从元组中选择对应的字段组成一个自己返回。
6、Union
负责将两个相同类型的数据流进行合并来创建一个包含数据流中所有元素的新数据流,两个以上,可以使用多个级联调用实现。
7、Distinct
根据指定的Key对数据记得元素进行去重得到一个新的数据集。
8、GroupBy
将一个数据集分成不相交的分区,所有具有相同Key的元素都被分配到相同的分区。
9、Reduce
合流处理,将数据集中有相同Key的元素合并为单个值,并且总是将两个元素合并为一个元素,直到仅剩一个值为止。
10、ReduceGroup
待补充。
11、Aggregate
sum(...);
min(...);
max(...);
minBy(...);
maxBy(...);
12、Join
可以将两个数据集合并为一个数据集,将两个数据集中具有相同键的元素连接到一起,并提供了多种方式将复合连接条件的元素组合到一个数据集中。
13、OuterJoin
左外连接、右外连接或全外连接。
14、Cross
笛卡尔积。
注意:非常消耗计算量的操作,甚至会消耗大量计算集群资源。
15、CoGroup
待补充。 - Sink算子
1、基于文件
env.writeAsCsv(...);
env.writeAsText(...);
2、基于数据流
DataSet.print();
DataSet.printToErr();
如何删除数据库中的重复数据,仅保留1条
DELETE
FROM table
WHERE id IN ( SELECT * FROM ( SELECT id FROM table GROUP BY id HAVING count( id ) > 1 ) a ) AND deptno NOT IN ( SELECT * FROM ( SELECT min( deptno ) AS deptno FROM dept GROUP BY dname HAVING count( dname ) > 1 ) b )
Union和Union All的区别
区别1:取结果的并集
1、union: 对两个结果集进行并集操作, 不包括重复行,相当于distinct, 同时进行默认规则的排序;
2、union all: 对两个结果集进行并集操作, 包括重复行, 即所有的结果全部显示, 不管是不是重复;
区别2:获取结果后的操作
1、union: 会对获取的结果进行排序操作;
2、union all: 不会对获取的结果进行排序操作;
区别3:
1、union看到结果中ID=3的只有一条
select * from student2 where id < 4
union
select * from student2 where id > 2 and id < 6
2、union all 结果中ID=3的结果有两个
select * from student2 where id < 4
union all
select * from student2 where id > 2 and id < 6
总结
union all只是合并查询结果,并不会进行去重和排序操作,在没有去重的前提下,使用union all的执行效率要比union高
Hive和Clickhouse的区别
一、Hive的数据文件
和ClickHouse不同,由于Hive本身并不存储数据,而是为HDFS上的文件赋予数据库表、列的语义,保存对应的元数据供查询时使用,因此Hive的数据文件存在多种类型
1、textfile
textfile(文本文件)是Hive中默认的数据文件,是一类基于纯文本的数据文件格式。在大数据时代之前的CSV、TSV都属于该类文件。这类文件的特点如下。
按行存储,文件内的一个物理行对应数据表中的一行数据。
行内以特殊的符号分列。
纯文本保存,不需要特殊解编码器即可识别。
受限于纯文本表现力的限制,复杂类型可能需要额外的信息才能正确解析(即单独的数据文件不足以保存所有信息),例如日期等。
默认情况下无压缩。
文本文件由于其按行存储的特性,导致其在Spark中是性能最差的一种数据文件格式。文本文件通常由业务侧的程序直接生成,且在业务侧被大量使用。因此Hive默认情况下使用文本文件作为数据文件的存储格式,保证这些文本文件在导入大数据系统后可以不用转换而直接被Hive识别和处理。
2、Apache ORC
Apache ORC(Optimized Row Columnar,优化行列式)是Hive中一种列式存储的数据文件格式,ORC在textfile的基础上进行了大量的修改以优化大数据场景下的查询性能,ORC的主要特点如下。
按列存储。
二进制存储,自描述。
包含稀疏索引。
支持数据压缩。
支持ACID事务。
3、Parquet
Hadoop Parquet是Hadoop生态中的一种语言无关的,不与任何数据计算框架绑定的新型列式存储格式。Parquet可以兼容多种计算框架和计算引擎,由于其优秀的兼容性,在生产中被大量使用。其主要特点如下。
按列存储。
二进制存储,自描述。
包含稀疏索引。
支持数据压缩。
语言独立、平台独立、计算框架独立。
4、Parquet与ORC
Parquet和ORC格式有着很多的相同点,那么在使用时应当如何选择呢?
(1) 原则一:希望平台独立,更好的兼容性,选择Parquet
Parquet在设计时考虑了通用性,如果希望进行联邦查询或为了将数据文件交给其他计算引擎使用,那么应该选择Parquet。
(2) 原则二:数据量庞大,希望获得最强的查询性能,选择ORC
ORC针对HDFS进行了针对性的优化,当数据非常庞大且需对查询性能有要求时,务必选择ORC格式。ORC在大数据量下的性能一定强于Parquet,大量的实验证明了这一点。因此本书后续的性能比较都是基于ORC格式的Hive。
ORC的设计原则和ClickHouse类似,都是存储服务于计算的典范。这也提现了性能和通用性不可兼得。再次强调,架构设计没有银弹,有得必有失。不要试图设计各方面都优秀的架构,即使是Parquet,也为了通用性放弃了性能。
二、Hive的存储系统
Hive本身不提供存储,其数据都存储于HDFS(Hadoop Distribution File System,Hadoop分布式文件系统)上。HDFS是大数据中专用的分布式文件系统,专为大数据处理而设计。
三、Hive计算引擎与ClickHouse计算引擎的差异
Hive本身并不提供计算引擎,而是使用Hadoop生态的MapReduce或Spark实现计算。由于Spark更高层次的抽象,使得Spark的计算引擎的性能远高于MapReduce。两者之间的区别如下:
1、运行模式不同
ClickHouse是MPP架构,强调充分发挥单机性能,没有真正的分布式表,ClickHouse的分布式表只是本地表的代理,对分布式表的查询都会被转换为对本地表的查询。这导致ClickHouse在执行部分大表join时可能出现资源不足的情况。
Hive的数据存储于分布式文件系统,因此Hive的计算引擎Spark在执行计算任务时,需要依据数据分布进行调度。在必要时,Spark可以通过CBO将数据重新排序后再分散到多台机器执行,以实现复杂的查询。
ClickHouse适合简单的DW之上的即席查询。而Spark由于其分布式特性,导致其任务启动时间很长,因此不适合实现即席查询,但是对于大数据量的join等复杂查询时具备非常大的优势。
2、优化重点不同
ClickHouse的优化重点在如何提高单机的处理能力,而Spark的优化重点在于如何提高分布式的协作效率。
四、ClickHouse比Hive快的原因
需要再次强调的是,ClickHouse只是在DW即席查询场景下比Hive快,并没有在所有场景都比Spark快,详细的分析请参考第5章。本节对比的是,当ClickHouse和Hive都进行即席查询,ClickHouse比Hive快的原因。
1、严格数据组织更适合做分析
ClickHouse的数据组织相对于Hive更严格,需要用户在建表时制定排序键进行预排序。虽然Hive的ORC格式和ClickHouse的数据文件其实一定程度上是等价的,但是Hive的ORC格式并不要求数据存储前进行预排序。
在预排序的情况下,数据在写入物理存储时已经按照一定的规律进行了聚集,在理想条件下可以大幅度降低I/O时间,避免数据的遍历。Hive的ORC格式在这一块并没有严格要求,因此ORC的存储就已经比ClickHouse消耗更多的I/O来遍历数据了。而ClickHouse却可以通过实现预排序好的数据和良好的索引,直接定位到对应的数据,节省了大量的I/O时间。
2、更简单的调度
ClickHouse目的在于压榨单机性能,并没有真正的分布式表,数据都在本地,这也使得ClickHouse不需要复杂的调度,直接在本机执行SQL即可。而Hive的数据都在HDFS上,在真正任务前需要依据数据分布确定更复杂的物理计划,然后将Spark程序调度到对应的Data Node上,调度的过程非常消耗时间。
Spark中group by是宽依赖还是窄依赖
宽依赖:聚合类操作会产生shuffle,所以为宽依赖;
会产生宽依赖的其他算子操作:
1.去重操作:
Distinct等。
2.聚合,byKey类操作
reduceByKey、groupByKey、sortByKey等。
byKey类的操作要对一个key,进行聚合操作,那么肯定要保证集群中,所有节点上的相同的key,移动到同一个节点上进行处理。
3.排序操作:
sortByKey等。
4.重分区操作:
repartition、repartitionAndSortWithinPartitions、coalesce(shuffle=true)等。
重分区一般会shuffle,因为需要在整个集群中,对之前所有的分区的数据进行随机,均匀的打乱,然后把数据放入下游新的指定数量的分区内。
5.集合或者表操作:
join、cogroup等。
两个rdd进行join,就必须将相同join key的数据,shuffle到同一个节点上,然后进行相同key的两个rdd数据的笛卡尔乘积。
Flink如何做到精确一次性的端到端数据传输
Source:保证数据仅消费一次
Prossess:打开checkpoint,设置为exactly-once
Sink:数据接收端需要支持事务方式写入
两段式提交:
pre-commit:创建快照作为checkpoint的一部分
commit:使用事务方式写入
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫