【大数据面试题大全】大数据真实面试题(持续更新)
1)Flink
1.1.Flink 的简单介绍
Flink 是一个分布式的流式数据的处理引擎,对于有界和无界数据进行状态计算,提供了很多便于用户编写分布式任务的 API,有 DataSetAPI,但是新版本中已经被舍弃了,即将淘汰了,现在用的是 DataStreamAPI,还有一些 TbaleAPI,但是做的并不是十分完善,比起 SqarkSQL 还是有很大的差距,Flink 里面还提供了容错机制,FlinkCEP实时预警等功能。
1.2.Flink 和 SparkStreaming 有什么区别
1)从架构角度上:SparkStreaming 的 Task 的运行依赖于 Driver,Executor,Worker,Flink 运行主要依赖于JobManager,TaskManager。
2)从数据处理的角度:SparkStreaming 是微批处理,需要指定微批处理的时间间隔,而 Flink 是通过事件时间作为驱动的,是真正意义上的流处理。
3)从时间机制上:Flink 提供了事件时间,注入时间,处理时间,最主要的就是事件时间。同时 Flink 支持 WaterMark 水位线机制,支持数据的延迟处理,这方面 SaprkStreaming 只有处理时间、StructStreaming 支持事件时间和 WaterMark,但是并没有 Flink 做的好,Flink 做的更加完善。
4)checkpoint方面,Flink 的 checkpoint 有 exactly-once,保证数据刚好被处理一次,spark 可能会处理多次。
1.3.Flink 是怎么保证数据不丢失的
1、checkpoint
- 这点是最重要的,并且会延伸出很多其他的问题,首先搞清楚什么是 checkpoint:数据在处理的过程中,保存了处理的状态还有处理的位置等,保存的方式和拍快照差不多,如果系统出现故障了,重新启动之后,就会从 checkpoint 记录的位置或者状态继续进行计算,这样数据就能保证不丢失了。
- 说到 checkpoint 就要说到栅栏机制:JobManager 启动一个 checkpoint 的协调器线程(如果记不住名字,可以直接说启动一个线程就行了),然后这个线程会定时的发送 barrier(栅栏),栅栏会按照顺序,依次经过各个 operator,比如 Source、Transfomation、Sink 这个顺序,经过 Source 的时候,Source 就会进行一个短暂的暂停(极其短暂,并不影响数据的运行,因为 Flink 是分布式的),然后将当前 Source 的状态拍快照,暂时存储在 HDFS 中,然后栅栏通过,进行下一个 Transfomation 的状态存储,然后重复上面的步骤,然后栅栏通过,进行 Sink,也是重复上面的步骤,最后栅栏返回到 checkpoint 的协调器线程中,checkpoint 的协调器线程判断上面所有的步骤都 OK 的时候,才算是 checkpoint 成功的执行了一次,中间有一个 operator 失败了,都算做 checkpoint 失败。
2、checkpoint 的执行模式(一致性):
- at-most-once:至多一次。故障发生之后,计算结果可能丢失;
- at-least-once:至少一次。就算故障发生了,也保证每个至少处理一次数据,所以可能会出现重复处理的情况;
- exactly-once:精确一次。不管系统是否发生故障,结果只会精确的出现一次,也成为恰好一次;(大多数 checkpoint 执行模式都是选用 exactly-once 进行一致性处理)
3、State(状态):
把状态存储到每个 taskManager(就是节点,如 node1,node2,node3 等)的内存中,说到内存肯定是不如磁盘安全的
注意:checkpoint就是对每个 operator 的 State 做了持久化存储(持久化就是保存在磁盘中,如HDFS)
1.4.Flink 代码编写好了,也设置了 checkpoint,但是有人改动了 Flink 代码,会对checkpoint 的结果产生影响吗
代码更改后只要 checkpoint 中的数据结构不发生变化,是不影响数据恢复的。
1.5.Flink中 exactly-once 是如何保证的
1、开始事务创建一个临时文件夹,把数据写入到这个文件夹里面。
2、预提交将内存中缓存的数据写入文件并关闭。
3、正式提交将之前写完的临时文件放入目标目录下。这代表这最终的数据。
4、丢失执行成功的时候会吧临时文件都干掉。
5、若失败发生在预提交之后,正式提交前,可以根据状态来提交预提交的数据,也可以删除预提交的数据。
1.6.Flink 数据量过大怎么办
1、考虑使用处理时间。
2、加机器。
3、使用滚动事件减少数据的重复。
4、kafka缓存。
1.7.Flink 的 slot 和并行度有什么关系
solt 就是 TaskManager 上面的槽,属于提供方;
并行度是在 slot 上执行的,属于使用方。
1.8.Flink 的重启策略
是基于 Flink 的 checkpoint 才可以启动的,默认就是固定间隔重启,比如重启几次、不重启等,不设置 checkpoint 就是没有重启策略,还有 FallBack 重启策略,还有故障率重启策略。
1.9.Flink 的广播变量
因为 Flink 中的任务是在 slot 中并行执行的,如果一旦多个 slot 都需要一份变量数据的时候,那么我们可以用到广播变量,将这个变量分别发送到各个 TaskManager(节点)上,这样每个 slot 就可以直接到自己的 TaskManager 节点和上获取变量数据了,减少了远程传输带来的性能的损耗,但是每个 TaskManager 上只能出现同一个广播变量一份。
1.10.Flink 窗口中的 session
没有固定的时间间隔,就是当用户退出了这个会话,就对会话阶段内的窗口进行数据统计。
1.11.Flink 的状态存储
三个:MemoryStateBackend,FSStateBackend,RocksDBstateBackend
1.12.Flink 在windows中出现了数据倾斜怎么解决
1、在windows之前进行预聚合。
2、重新对key进行设置或者修改。
1.13.Flink 是如何处理反压的
其实flink是自带反压策略的,jobManager 和 taskManager 是有通讯的,一旦出现下游处理时间较长,那么 source 阶段就会调整自己拉取的数据量大小,如果自动处理的策略还是没有减少压力的效果,那么可以通过设置 parrilizims 通过提高并行度来解决,还可以通过设置 slot 的数量来提高数据处理的速率来解决。
1.14.Flink 中的 operatorChain
能减少线程之间的切换,减少消息的序列化还有反序列化,减少延迟的同时提高了吞吐量,至于什么情况下才会出现 operatorChain 呢,当连续的 task 之间出现 OneToOne 模式就会自动将这几个多个 task 连接,形成一条算子链,那么什么是 OneToOne 呢,OneToOne 就是上下游的并行度相同,也没有发生数据的排序变化,此时就认为是 OneToOne 模式,一般在代码调试阶段会将operatorChain关闭,这样方便在 Flink-dashboard 中观察数据流转信息。
1.15.Flink 中做聚合的时候 groupby,keyby 中出现热点问题怎么解决
1、首先在业务上避免这种问题,比如上海北京的订单比较多,其他的少,那我们可以对上海北京的数据做单独处理。
2、在key上进行处理。
3。参数设置,缓存一定的数据后再进行触发,以减少对state的访问,从而减少数据短时间的传输,减少数据倾斜。
1.16.Flink 中 Taskslot 的概念
Flink 中的 TaskManager 是执行任务的真正的 worker,每个 TaskManager 都会创建一个独立的线程来进行 task 任务的执行,所以设置了 slot 就是将 TaskManager 的资源平均分配出来,这样可以让多个 Task 同时执行,这样就避免了多个 task 之间导致的资源的竞争问题,但是注意 solt 只会对内存进行隔离,CPU 是不会进行隔离的。
1.17.
1.18.
1.19.
1.20.
1.21.
1.22.
1.23.
1.24.
1.25.
2)Spark
3)Java
作为目前最火爆的开发语言,使用Java已经是大数据开发者的基本技能,很多大数据组件也适用于Java开发,如:Flink
3.1.Java 中的集合
【Java-Java集合】Java集合详解与区别
3.2.Java 中的多线程如何实现
1、继承Thread类。
2、实现Runnable接口。
3、实现Callable接口。
4、线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度。
详细:
https://www.cnblogs.com/big-keyboard/p/16813151.html
3.3.Java 中的 JavaBean 怎么进行去重
1、利用 HashSet,泛型指定我们创建好的 JavaBean,通过 hashSet 中的 add() 方法,进行去重。
publicstaticvoidmain(String[] args){Date date=newDate();//获取创建好的javaBean对象并进行赋值JavaBean t1 =newJavaBean();
t1.setLat("121");
t1.setLon("30");
t1.setMmsi("11");
t1.setUpdateTime(date);//再创建一个javaBean对象,赋同样的值 JavaBean t2=newJavaBean();
t2.setLat("121");
t2.setLon("30");
t2.setMmsi("11");
t2.setUpdateTime(date);//用HashSetHashSet<JavaBean> hashSet =newHashSet<JavaBean>();
hashSet.add(t1);
hashSet.add(t2);System.out.println(hashSet);System.out.println();for(JavaBean t:hashSet){//只会出现一个值System.out.println(t);}
2、利用 ArrayList,泛型指定我们创建好的 javaBean,通过 ArrayList 中的 contain() 方法进行判断后去重。
//用ListList<TestMain18> lists =newArrayList<TestMain18>();if(!lists.contains(t1)){
lists.add(0, t1);}if(!lists.contains(t2)){//重写equals
lists.add(0, t2);}System.out.println("长度:"+lists.size());
3.4.Java 中 == 和 equals 有什么区别
==
用来判断对象在内存中的地址是否相等,
equals
用来判断对象中的内容是否相等。
3.5.Java 中的任务定时调度器
1、Timer timer = new Timer() timer.schedule(重写 new TimerTask 方法)
//方式1:Timer timer =newTimer();//TimerTask task, 要定时执行的任务//long delay,延迟多久开始执行//long period,每隔多久执行延迟
timer.schedule(newTimerTask(){@Overridepublicvoidrun(){System.out.println("每隔1s执行一次");}}, 5000,1000);*/
2、Executors.newScheduleThreadPool(线程池数量)返回的对象 scheduleAtFixeRate,重写 run 方法。
//方式2:ScheduledExecutorService executorService =Executors.newScheduledThreadPool(3);
executorService.scheduleAtFixedRate(newRunnable(){@Overridepublicvoidrun(){System.out.println("每隔1s执行一次");}},5,1, TimeUnit.SECONDS);
3、SprintBoot 中提供了定时任务的相关注解,使用起来特别方便,利用corn定义触发的规则。
@Component//表示该类是Spring的组件,会由Spring创建并管理@EnableScheduling//表示开启定时任务扫描publicclassTestTimedTask2{//https://cron.qqe2.com/@Scheduled(cron ="0/3 * * * * ? ")publicvoidtask(){System.out.println("每隔3s执行一次");}}
4)SQL
SQL 作为计算机行业最基本的语言之一,也是必须要了解的。
4.1.SQL 中的聚合函数
avg(),max(),min(),sum(),count()
等
注意:
聚合函数不会自己使用,也不会和 where 一起使用,一般使用的时候都是和 group by 一起使用(分组必聚合),还有就是在 having 语句后面进行使用。
4.2.SQL 中的各种 join 与区别
inner join
(内连接):就是找到两个表中的交集。
left join
(左外连接):以左边的表为主,如果没有与右边的表相对应的用 null 补充在表中。
right join
(右外连接):以右边的表为主,同上。
full join
(满外连接):Hive 中特有的,MySQL 中没有,保留两边的表的所有内容,没有对应的互相都用 null 补充在表中。
4.3.简单说一下 MySQL 中的数据结构
MySQL的数据结构为 B + 树
【计算机基本原理-数据结构】八大数据结构分类
【计算机基本原理-数据结构】数据结构中树的详解
4.4.关系型数据库和大数据组件中的 nosql 数据库有什么区别
1、关系型数据库的特点:
- 结构化的存储
- 采用结构化的查询语言sql
- 操作数据要具有一致性,比如事务操作
- 可以进行join等复杂查询
- 无法进行大量数据的高并发读写
2、nosql数据库的特点:
- 非结构化的数据库
- 高并发大数据下读写能力强
- 事务性差
- join 的复杂操作能力弱
5)Linux
在大数据环境安装部署、提交 jar 包的时候,都会应用到 Linux 操作系统,所以了解需要了解 Linux 常用命令。
【Linux-Linux常用命令】Linux常用命令总结
6)Hadoop
6.1.Yarn
6.1.1.Yarn 提交作业流程
1、由客户端向 RM 提交任务(MR,Spark…)
2、RM 接收任务,并根据任务随机找一台NM,启动 AppMaster,通知以 container 方式。
container:资源信息容器(节点信息,内存信息,CPU信息),运行:AppMaster
3、指定 NM 启动 AppMaster,启动后和 RM 保持心跳机制,用于报告当前已经启动了,并且通过心跳来传递相关信息。
4、根据 RM 给定任务信息,根据任务信息,对任务进行分配,主要会分配出要启动多少个 map 和多少个 reduce,以及每个 map 和每个 reduce 需要使用多大资源空间,然后将资源申请相关信息发送给 RM(心跳发送)
5、RM 接收到资源申请信息后,将申请信息交给内部资源调度器,由资源调度器,根据相关的资源调度方案,进行资源分配即可,如果当下没有资源,在此处等待。
注意:
资源并不是一次性全部给到 AppMaster,一般会采用极可能满足方案,如果满足不了,会先给与一定资源进行运行,如果空闲资源连一个 container 都不足,就会将这些资源挂起,等待资源充足。
6、AppMaster 基于心跳机制,不断询问RM是否已经准备好了资源了,如果发现已经准备好了,然后直接将资源信息获取。
7、根据资源信息说明,到指定的 NM 上启动 container 资源容器,开始运行相关任务。
8、NM 接收启动的信息后,开始启动执行,此时会和 AppMaster 以及 RM 保持心跳连接。
RM 将任务的相关信息根据心跳通知 AppMaster
AppMaster 将资源的使用信息根据心跳通知 RM
9、当 NM 运行完成后,会通知 AppMaster 并将资源使用完成情况通知给 RM。
10、AppMaster 告知给 RM 任务已经运行完成了, RM 回收资源,通知AppMaster进行自毁即可。
注意:
当 NM 在运行过程中,如果发生错误了,此时 RM 会立即将资源回收,此时 AppMaster 就需要重新和 RM 申请资源。
详情:【Hadoop-Yarn】Yarn 的运行流程
6.1.2.Yarn 的资源调度
1、
FIFO scheduler
:
先进先出调度方案
当一个调度任务进入到调度器之后,那么调度器会优先满足第一个MR任务全部资源,此时就有可能将资源全部都获取到了,导致后续的任务本身的运行时间很短,但是由于第一个MR将资源全部抢走了, 导致后续任务全部等待。
此种调度器在生产中 一般不会使用,因为生产中yarn平台不是你自己的。
2、
Fair scheduler
:
公平调度器
可以预先分配出多个队列, 相当于对资源进行预先的划分。
3、
capacity scheduler
:
容量调度器
此种调度器是有 Yahoo 提供一种调度方案,同时也是当下Apache版本的hadoop默认调度方案。每个队列,可以指定占用多少的百分比的资源,从而保证,大的任务可以有单独的队列来运行,并且小的任务,也可以正常的运行。
6.1.3.Yarn 成员
clustermanager、nodemanager、applicationmaster。
6.2.HDFS
6.2.1.HDFS 读写流程
【Hadoop-HDFS】HDFS的读写流程 & SNN的数据写入流程
6.2.2.HDFS 中小文件过多会有什么影响
HDFS 擅长存储大文件,我们知道,HDFS 中每个文件都有各自的元数据信息,如果 HDFS 中有大量的小文件,就会导致元数据爆炸,集群管理的元数据的内存压力会非常大(namenode 节点)
6.2.3.HDFS 中小文件过多怎么处理
1、使用官方工具 parquet-tools 合并指定的 parquet 文件。
# 合并 HDFS 上的 parquet 文件
hadoop jar parquet-tools-1.9.0.jar merge /tmp/a.parquet /tmp/b.parquet
# 合并本地的 parquet 文件
java -jar parquet-tools-1.9.0.jar merge /tmp/a.parquet /tmp/b.parquet
2、合并本地的小文件,上传到 HDFS(通过 HDFS 客户端的 appendToFile 命令对小文件进行合并上传)
hdfs dfs -appendToFile user1.txt user2.txt /test/upload/merged_user.txt
3、合并 HDFS 的小文件,下载到本地,可以通过 HDFS 客户端的 getmerge 命令,将很多小文件合并成一个大文件,然后下载到本地,最后重新上传至 HDFS。
hdfs dfs -getmerge /test/upload/user*.txt ./merged_user.txt
4、Hadoop Archives (HAR files)是在 0.18.0 版本中引入到 HDFS 中的,它的出现就是为了缓解大量小文件消耗 NameNode 内存的问题。
HAR 文件是通过在 HDFS 上构建一个分层文件系统来工作。HAR 文件通过 hadoop archive 命令来创建,而这个命令实际上是运行 MapReduce 作业来将小文件打包成少量的 HDFS 文件(将小文件进行合并成几个大文件)
# Usage: hadoop archive -archiveName name -p <parent> <src> <dest># har命令说明# 参数 “-p” 为 src path 的前缀,src 可以写多个 path# 归档文件:
hadoop archive -archiveName m3_monitor.har -p /tmp/test/archive_test/m3_monitor/20220809 /tmp/test/archive
# 删除数据源目录:
hdfs dfs -rm -r /tmp/test/archive_test/m3_monitor/20220809
# 查看归档文件:
hdfs dfs -ls -R har:///tmp/test/archive/m3_monitor.har
# 解归档:将归档文件内容拷贝到另一个目录
hdfs dfs -cp har:///tmp/test/archive/m3_monitor.har/part-1-7.gz /tmp/test/
6.2.4.HDFS 成员
namenode、datanode、secondarynamenode;namenode 有 active 和 standby。
6.2.5.NameNode 和 SecondaryNameNode 的区别与联系
SecondaryNameNode 并不是 NameNode 的备份节点,主要是将内存中的 Fsimage 和磁盘上的 Fsimage 文件进行合并。
6.2.6.HDFS 中 Fsimage 与 Edits 详解
【Hadoop-HDFS】HDFS中Fsimage与Edits详解
6.3.MapReduce
6.3.1.map 阶段的工作机制
【Hadoop-MapReduce】MapReduce编程步骤及工作原理(详见标题4:map 阶段的工作机制)
6.3.2.reduce 阶段的工作机制
【Hadoop-MapReduce】MapReduce编程步骤及工作原理(详见标题5:reduce 阶段的工作机制)
6.3.3.MR 的优劣
不管是 map 阶段还是 reduce 阶段,大量进行磁盘到内存,内存到磁盘相关的 IO 操作,主要目的能够解决处理海量数据计算问题。
- 带来好处:能够处理海量的数据。
- 带来的弊端:造成大量的磁盘 IO 工作导致效率比较低。
6.3.4.MR 的相关配置
配置默认值释义mapreduce.task.io.sort.mb100设置环型缓冲区的内存值大小mapreduce.map.sort.spill.percent0.8设置溢写的比例mapreduce.cluster.local.dir${hadoop.tmp.dir}/mapred/local溢写数据目录mapreduce.task.io.sort.factor10设置一次合并多少个溢写文件
7)Hive
7.1.Hive 相关数据的存储位置
Hive 的元数据存储在mysql中(默认derby,不支持多客户端访问),数据存储在 HDFS,执行引擎为 MR。
7.2.Hive 内外表的区别
1、建表时用 external 区分。
2、删除外表时删除元数据,删除内表是删除的是元数据和存储数据。
3、外表存储位置自己定,内表存储位置在 /uer/hive/warehouse 中。
7.3.Hive 如何实现分区
1、创建表时指定字段进行分区。
2、使用 alter table 对已经创建完成的表进行分区的增加和删除操作。
# 建表:createtable tablename(col1 string) partitioned by(col2 string);# 添加分区:altertable tablename addpartition(col2=’202101’);# 删除分区:altertable tablename droppartition(col2=’202101’);
3、修改分区。
altertable db.tablename
set location '/warehouse/tablespace/external/hive/test.db/tablename'
7.4.Hive 装载数据
altertable db.tablename addifnotexistspartition(sample_date='20220102',partition_name='r') location '/tmp/db/tablename/sample_date=20220102/partition_name=r';
7.5.Hive 修复分区数据
msck repair table test;
7.6.Hive 中的排序方式及对比
1、Hive 中的排序方式有:
order by,sort by,distribute by,cluster by
2、四种排序方式的区别:
order by
: 对数据进行全局排序,只有一个 reduce 工作sort by
: 一般和 distribute by 一起使用,当 task 为 1 时效果和 order by 一样distribute by
: 对 key 进行分区,和 sort by 一起实现对分区内数据的排序工作cluster by
: 当 order by 和 distribute by 的字段相同时可以用 cluster by 代替,但是只能升序
注意:
生产环境中使用 sort by 比较少,容易造成 oom,使用 sort by 和 distribute by 较多。
7.7.row_number()、rank()、dense_rank() 的区别:
三者都是对数据进行标号排序
row_number()
:不会出现序号的增加或减少,当数值相同时也会有排名先后之分rank()
:当排序相同时序号重复,总序不会变化dense_rank()
:当排序相同时序号重复,总序会减少
7.8.Hive 如何实现数据的导入和导出
- 导入数据:① load data 的方式可以对本地或HDFS上的数据进行导入② Location方式
create external ifnotexists stu2 like student location '/user/hive/warehouse/student/student.txt';
③ sqoop方式 - 导出数据:一般用sqoop方式
7.9.Hive 中 over() 的使用
8)Sqoop
8.1.Sqoop 常用命令
【Sqoop-命令】Sqoop相关了解及命令
8.2.Sqoop 如何进行空值处理
导出数据时采用
--input-null-string
和
--input-null-non-string
两个参数。
导入数据时采用
--null-string
和
--null-non-string
。
8.3.Sqoop 如何处理特殊字符
Sqoop 中遇到特殊字符可以使用
hive-drop-import-delims
丢弃,也可以使用
--hive-delims-replacement
,它会将特殊字符替换为我们设定的字符。
8.4.Sqoop 任务有 reduce 阶段吗
只有 map 阶段,没有 reduce 阶段的任务。默认是 4 个 MapTask。
9)Oozie
1、Oozie 一般不单独使用,因为需要配置 xml 文件很麻烦。
2、Oozie 一般与 Hue 一起使用,可以调度各种任务比如 Shell,MR,Hive等。
3、无论是单独使用还是与 Hue 集成,Oozie中最重要的点都在于 workflow 的配置。
4、与 Hue 整合时在 Schedule 中配置定时任务的时间,在 workflow 中配置任务的相关位置信息。
10)Azkaban
1、元数据存储在 Mysql 中。
2、有三种部署模式: solo-server(所有服务在一台服务器上), tow-server(web,executor在不同服务器上),multiple-executor-server(一般不常用)。
3、azkaban的任务调度:
- Hive脚本: test.sql
use default;drop table aztest;create table aztest(id int,name string) row format delimited fields terminated by ',';load data inpath '/aztest/hiveinput' into table aztest;create table azres as select * from aztest;insert overwrite directory '/aztest/hiveoutput'select count(1) from aztest;
- hive.job(名称.job)
type=command #固定dependencies=xx #有依赖的任务的时候添加这个command=/home/hadoop/apps/hive/bin/hive -f 'test.sql'
- 将所有文件打包成 zip 包上传到 Azkaban 上,然后点击 summary,然后选择 schedule 进行时间的配置。
11)Flume
Flume 是一个用来实时采集流数据的分布式数据采集系统,容错性强,可靠性高。
11.1.Flume 的架构组件
(source,channel,sink)
1、Flume 中的 agent:包含 source,channel,sink 的统称。
2、source:是用来采集数据的组件,可以监控一个文件的变化,可以监控一个目录下新文件的变化,可以监控一个目录下所有文件的内容变化,也可以自定义数据源,在配置的时候要配置 source 的名称。
3、channnel:可以配置两种方式进行数据的缓存,一种是内存,另一种是以生成文件的方式。
4、sink:支持 HDFS,Kafka,自定义目标源等,还可以支持下一个 agent。
5、event:Flume 将采集到的数据封装到 event 中进行传输,本质上是一个字节数组。
11.2.Flume 的多种架构
1、Flume 可以以 agent 的方式进行串联。
2、Flume 可以并联,将多个 agent 的 sink 传输到新的 agent 的 source 中。
3、Flume 可以 串联+并联+多sink 等。
11.3.Flume 的相关配置
1、source,channel,sink 的名称。
2、channel 是基于内存还是基于文件。
3、sink 对应的 channel。
4、sink 到 kafka 的话要配置 kafka 的 topic,端口号,ack 等。
12)Kafka
12.1.Kafka为什么这么快
1、查询速度快
- 分区,文件分段。
- 二分查找法定位消息在哪个段(文件)中。
2、写入速度快
- 顺序写入。
- 零拷贝:数据直接从磁盘文件复制到网卡设备中,不需要经过应用程序之手。零拷贝技术通过 DMA 技术,将文件内容复制到内核模式下的 ReadBuffer,直接将数据内核的数据传递到网卡设备中,所以零拷贝是针对于内核,数据再内核模式下实现了零拷贝。
- 批量发送:通过 batch.size 参数来设置批量提交数据的大小,默认是16K,当数据积压到这一值时就会统一发送,数据会发送到一个分区中。
- 数据压缩:Producer 端压缩,Broker 端保持,Consumer 端解压缩。
12.2.Kafka 怎么避免重复消费
可以利用两阶段事务提交(Flink)或者容器去重(HashSet,Redis,布隆过滤器)
12.3.Kafka 怎么保证顺序消费
Kafka 是全局无序但是局部有序,只要我们在推送消息的时候都推送到同一个分区,消费时也指定一个分区消费即可。
12.4.Kafka 分区有什么作用
提升读写效率 + 方便集群扩容 + 消费者负载均衡
12.5.Kafka 如何保证数据不丢失
1、生产者端,设置 ack(0、1、-1 / all)
0
:生产者端不会等到 Broker 端返回 ack,继续生产数据。
1
:当 Broker 中的 Leader 端收到数据就返回 ack。
-1 / all
:当 Broker 中的 Leader 和 所有的Follower 都接收到数据才返回 ack。
2、消费者端,采用先消费后提交的方式,宁愿重复消费也不能让数据丢失。
3、Broker 端:有副本机制保证数据安全性。
12.6.消费者与消费者组之间的关系
同一时间一条消息,只能被同一个消费者组的一个消费者消费,不能被同一个消费者组的其他消费者消费。但是可以被不同消费者的消费者组所消费。
12.7.Kafka 架构及基本原理
【Kafka-架构及基本原理】Kafka生产者、消费者、Broker原理解析 & Kafka原理流程图
13)HBase
13.1.HBase 的架构组成
- HMaster
- HRegionServer
- Region
- zookeeper
HBase:Client -> Zookeeper -> HRegionServer -> HLog -> Region -> store -> memorystore -> storeFile -> HFile
13.2.HBase 的读写流程
【HBase-读写流程】HBase的读写流程与内部执行机制
13.3.HBase 中 rowkey 的设计
- Hash
- 时间戳倒转
13.4.Region 的分区和预分区
- HBase 在创建表的时候可以指定预分区规则。
- HBase 建表后和可以通过 split 命令进行分区的更改。
- HBase 也可以再建表的时候通过 split.txt 文件中的信息通过 SPLIT_FILE 命令进行预分区。
13.5.HBase 优缺点
- 优点:- 支持非结构化数据的存储- 相对于关系型数据库HBase采用列式存储,写入的效率很快- HBase中的null值不会被记录在内,节省空间并提高了读写性能- 支持高并发的读写- 支持大量数据的存储工作
- 缺点:- 本身并不支持sql查询- 不适合大范围的扫描查询
14)ClickHouse
14.1.ClickHouse 建表时要注意什么
CH 建表时要指定引擎。
14.2.ClickHouse 进行表数据更新或删除操作时候的 SQL 语句
更新:
Alter table update (xx="xx") where 主键 = ?
删除:
Alter table delete where 主键= ?
写入:
insert into table() values()
14.3.ClickHouse 引擎分类及特点
- MergeTree:- MergeTree引擎共同特点:用插入来表示数据的更新。因为在 CH 中,主键列不是唯一的,仅仅是为了创建索引,提高我们的查询效率,再次插入数据,数据重复。在 MergeTree 引擎中,后台会有一个进程,在定期执行数据合并操作,但是什么时候不知道。- 注意:如果在插入了一条数据之后,马上使用
select * from tablename
,这个操作不会读取到最新的数据,要等后台合并之后查询到的数据才是最新的,因此为了确保每次查询都是最新的数据有两种解决办法:1、手动触发后台进程合并操作:optimize table 表名 final
手动合并,但是如果大量数据进行合并会变慢,而且合并过程中表不可以(不推荐)2、每次查询的时候对数据进行分组聚合
操作,已达到去重的目的。 - 日志引擎:- TinyLog:TinyLog 最小最轻量级的引擎,当我们需要快速写入小表(100w 行以内),以后整体读取它们这个引擎是最高效的,追加的方式。- TinyLog缺点:没有并发控制,同时读取和写入的时候,读取操作报异常,同时写入多个表,数据会被破坏,不支持索引。
- 集成引擎:Kafka,MySQL,HDFS,ODBC,JDBC,与其他存储数据库或者存储介质进行整合时使用。- 项目没使用集成MySQL的引擎原因:因为 CH 是映射 MySQL 的表,本质上还是在 MySQL 中做 select 查询,对数据库造成访问压力。- 注意:使用了 MySQL 引擎关联 MySQL 中指定的库,那么在 CH 中就会出现一个库,这个库中是用 MySQL 的 sql 语法来进行操作的。
- 其他特定功能引擎(用的比较少)
14.4.MergerTree 引擎分类
- MergeTree:1、orderby 一般用于排序主键,使用了 orderby 就不用 primary by 了。2、建表后,在指定的目录下,会按照分区进行分文件夹,分区中每个列都是一个 .bin 文件,是一个列被压缩的表现,.idx 文件代表主键索引,.mrk 保存块偏移量。
- ReplacingMergeTree:1、如果表会进行进行修改使用此引擎,但是此引擎只保证数据最终被修改,无法保证查询过程中主键重复 。2、
ENGINE=ReplacingMergeTree([ver])
,ver 为版本,如果 ver 没有指定,那么会保留最后一次修改的内容,如果 ver 指定,保留第一次的内容。 - SummingMergeTree:1、聚合功能,只能进行sum聚合。2、
SummingMergeTree([columns])
,如果指定了 columns,那么所选列不能是主键和非数值类型,如果没有选,会自动把非主键列中的数值列进行聚合。3、如果不手动刷新,就要等待后台自动进行聚合,或者使用分组聚合的 sql 查询可以得到刷新后的结果。 - AggregatingMergeTree:1、聚合功能,功能更加全面,除了 sum 外还有别的聚合功能。2、一般和 MergeTree 一起使用,把明细数据存放到 MergeTree 中,然后 insert into 插入到 AggregatingMergeTree 表中,然后再使用分组聚合查询就能得到聚合后的结果。
- CollapsinMergeTree:CH 中不支持 update 和 delete 操作(不能使用标准的更新和删除语法操作 CH),因此 CH 推荐的方式使用 CollapsinMergeTree 进行删除,在表中增加一个字段 sign,1 表示状态行,-1 表示取消行,用取消行来表示状态行的数据被干掉了,当触发合并操作之后,会对 1 和 -1 进行折叠操作,也就是同时删除了这两条数据。状态行和取消行不折叠的两种情况:1、由于合并机制是后台发生的,具体的执行时间无法预测,所以可能会出现数据冗余的情况。2、如果是先出现的取消行,然后出现的状态行,也无法进行折叠。3、CH不能保证数据插入的时候相同主键落到同一个节点上,不同节点上的数据是无法进行折叠的。解决方式:在查询数据的时候,使用 sum 将 sign 字段求和,having 出大于 0 的数据即可。注意:取消行的特点是除了 sign 列其他的数据都是状态行的拷贝,状态行的数据可以来自于 ogg 和 canal,但是取消行的数据我们难道要通过根据主键查询 CH 表的数据,然后复制拼接取消行数据的 sql 语句吗?答案:不需要,ogg 中的删除操作有 before 字段可以直接作为取消行插入到 CH 表中,canal 中的删除操作有 data 字段可以直接作为取消行插入到 CH 表中。
- VersionCollapsinMergeTree:相对于 CollapsinMergeTree 来说对状态行和取消行插入的顺序没有严格的要求了,但是不仅要添加 sign 列还要增加一个 version 列,用上一条数据的 update 时间来作为 version 的值。1、查询依旧使用分组聚合的方式。2、或者使用
select * from tablename final
,此操作并没有真正触发合并,而是后台将数据计算好了呈现出来的效果(这是一个非常低效的方式来选择数据,尽量不要用来查询数据量较大的表)
14.5.ClickHouse 表的分类
本地表:部署在单机环境下
集群表:部署在集群环境下
14.6.ClickHouse 中的 Update、Delete 操作
在 CH 中不能使用常规的 sql 语句进行 update 和 delete 操作,而是要使用 alter table 进行操作。
- 如何查看操作的数据:在CH的system库mutations表中,记录着CH修改操作的记录
- mutation 具体过程:首先用 where 条件找到具体的分区,重建每个分区,用新的分区覆盖老的分区,分区一旦被替换,不可退回(即使修改一条数据,也会覆盖,所以效率上来说比较慢)
14.7.OLAP 组件分类
- ROLAP:(对明细层的数据进行实时聚合计算查询)impala、presto
- MOLAP:(对数据进行多维预聚合加工,然后对预聚合数据进行实时计算查询)Druid、Kylin
- HyBirdOLAP:(ROLAP+MOLAP)TiDB
14.8.ClickHouse 属于 OLAP 还是 OLTP
ClickHouse 属于 ROLAP,但是也可以做 MOLAP(通过物化视图的方式进行预聚合)
CH 与其他 OLAP 的区别:
Druid
:
实时查询,但是不支持复杂sql查询,不支持数据更新操作。
Kylin
:
亚秒级查询,支持复杂sql查询,但是会构建 cube,容易出现维度爆炸,维度控制在10个左右,不支持数据更新操作。
ClickHouse
:
1、即可以对明细数据进行实时OLAP分析,也可以对数据进行预聚合计算。
2、单表查询优势巨大。
3、支持数据更新操作。
4、支持sql查询,多表联查等操作(不支持窗口函数以及相关子查询)
15)Kudu
15.1.Kudu 的建表
Kudu 的建表必须要有主键。
15.2.Kudu 依赖 Hadoop 吗
Kudu 不需要依赖 Hadoop 集群,Kudu 有自己的存储机制。
15.3.Kudu 的分区方式一共有几种
hash、range、hash&range(混合分区)三种方式,项目中使用hash方式进行分区。
15.4.Kudu 的存储依赖 HDFS 吗
Kudu 不依赖 HDFS。
15.5.Kudu 的架构体系(角色)
- master:负责管理从节点,并且存储数据在从节点中的位置,也就是元数据。
- catelog:元数据的存储位置,无法直接访问,只能通过 API 查询,记录着表的结构,表的位置,状态,以及各个 tablet 开始和结束的 key(分区)- 作用:管理元数据,负载均衡,监听 tablet-server 状态。
- tablet-server:只负责存储数据,类似于 datanode。
15.6.Kudu 的架构体系(特点)
1、Kudu 的存储是以表的形式,有分区,有列名,列的类型,列值,类似于一个关系型数据库,但是还不是关系型数据库。
2、Kudu 是主从结构,有 master 和 tablet-server,主节点又分为 action 和 wait 两个。
3、Kudu 的表分区,分区的副本存在于各个节点上,类似于 Kafka。
4、Kudu 的分区类似于 HBase 的 Region,一张表按照一定间隔规则分成若干个分区。
5、Kudu 的主从节点分工类似于 HDFS 中的 datanode 和 namenode。
6、Kudu 表(tablet-server)中的一个分区会被拆分成多个 tablet,每一个分区对应一个 tablet,分区有三种方式:Hash、Range、Hash+Range。
15.7.项目中如何创建 Kudu 表(Spark)
根据DataFrame建表:
- 创建KuduContext对象(DataFrame,SparkConf)
- kuduContext.tableExists(tableName)- dataFream.schema(),返回变结构 StructType。- StructType.fields.map(field=>{StructField(field.name, field.dataType, true/false[判断字段是否为主键])})- 将更改好的 StructField 创建成新的表结构。- newCreateTableOption(),指定表的分区方式根据主键字段进行分区,设置副本数。
- kuduContext.createTable(tableName, kuduStructType, List(primaryFieldName), options)
Kudu 创建表需要 new 一个 createOptions 对象,通过这个对象指定副本数和分区方式,指定分区方式时要指定主键字段。
16)Ogg
16.1.OGG 简介
OGG 是一种基于日志的结构化数据复制软件,通过解析源数据库在线日志或归档日志获得数据的增删改变化。
OGG 能够实现大量交易数据的获取,转换,发送。
16.2.OGG 实现 Oracle 的实时同步大致过程
- 首先 Oracle 要开启 archivelog(归档日志)和辅助日志功能。
- ogg源端:(开启管理进程 mgr,extract 进程和 pump 进程)1、mgr 进程是负责管理两个子进程的。2、extract 进程是到 oracle 中拉取增删改等日志的作用,然后将日志转换成一个中间文件(LocalTrail)3、pump 进程是请求目标端的 mgr 进程开启 collect 进程,然后压缩中间文件传送到 connect 进程。
- ogg目标端:(开启管理进程 mgr,connect 进程和 replicat 进程)1、mgr 进程是负责管理两个子进程,并完成与远端 pump 进程的通信。2、connect 进程是接收 pump 进程传输的中间文件的,connect 进程可以没有,没有的时候 replicat 会代替 connect 接收文件。3、replicat 进程是用来接收文件,并将文件转换成目标端对应的 SQL 或者对应的插入语句,在目标端执行即可实现数据同步。
17)Canal
17.1.Canal实现原理
- Canal 是模仿 MySQL 的主从架构,主备原理:在 MySQL 主从关系中,salve 会向 master 发送 dump 命令,master 会根据配置情况判断是否是自己的从节点,如果是自身的从节点,那么 MySQL 每更新一条数据,salve 也会随之变更。
- Canal 实现原理:Canal 像是一个伪装者一样,装成 MySQL的从节点,也想 MySQL 的 master 发送 dump 命令,从而达到 MySQL 与 Canal 的数据同步。
17.2.Canal 实现 MySQL 的实时同步大致过程
- 首先 MySQL 要开启 bin-log 日志(binary-log)功能,顾名思义,这个日志中记录的都是二进制的数据(canal是一个cs架构,分别有canal-server和canal-client)
- canal-server:canal-server 有 1~n 个 instance,每个 instance 下有四个进程来协作同步数据,通常一个 instance 对应一个数据库,方便对数据的不同目标端发送。- EventParse:从 bin-log 日志中拉取数据。- MetaManager:记录读取 bin-log 日志的位置,也就是 offset,同时记录 client 端在 EventStore 拉取数据的 offset。- EventSink:从 EventParse 中获取数据,进行解析转换,然后将数据写到 EventSotre。- EventStore:client 从此处拉取数据(是一个内存环形缓冲区)
- canal-client:- canal-client 从 server 端拉取数据,每次拉取多少,拉取到了哪里,由 canal-server 中的 MetaManager 所管理。- 拉取到的数据经过数据处理,最终将数据写到 Kafka 集群。
18)Druid
18.1.Druid 有哪些特点(项目中为什么使用 Druid)
Druid 支持海量数据的实时毫秒级查询,适合我们的行情分时数据业务(指数项目中应用)
18.2.为什么 Druid 支持实时毫秒级查询,底层怎么做到的
1、优秀的分布式架构设计,各个角色各司其职分工协作,提供了整体的效率。
2、底层存储支持 Chunk 分文件夹,Segment/Partition 分文件。
3、预聚合,加快查询效率。
4、位图索引(了解即可,只需要知道是用空间换时间,用二进制位运算避免了表扫描即可)
19)Kylin
19.1.Kylin 有哪些特点
1、Kylin 支持 sql,但是不支持数据更新。
2、Kylin 会对数据进行预计算,也就是构建 cube。
3、Kylin 在预计算的时候比较耗费时间和空间,但是构建完 cube 后面查询效率就提升了。
19.2.Kylin 的 cube
1、存储在 HBase 中。
2、一个 cube 由多个 cuboid 组成,cuboid 的计算方式为 2 的(维度 -1)次方。
19.3.Kylin 的膨胀率
构建完 cube 后的数据量大小 ÷ 原始数据量大小,膨胀率小于 1000% 都是正常。
19.4.cube 如何进行优化(剪枝优化)
1、使用衍生维度,会将表的非主键维度排除掉。
2、指定字段不进行 cube 的构建。
3、指定多维度的组合同时出现时才会进行 cube 的构建,单独出现时不会构建 cube。
19.5.Kylin 的应用场景
一张大表,并发访问量不是很高的情况下,想要实现亚秒级查询,可以使用 Kylin。
20)Doris
20.1.Doris 的架构
FE、BE
- FE 中有三个进程:leader、follower、observer,leader 和follower 是主从节点的概念,防止单点故障,observer 是当查询压力过大时的拓展查询功能,并且完成元数据的备份工作,所以 observer 只读不写。
- BE 作为数据存储的节点,是分布式的,多借点并行进行数据查询,同时 BE 还会将数据存储多个副本中,可按照数据配置。
- Broker 是一个无状态进程,可以帮助 Doris 访问外部数据源,通常在每台节点上部署一个 Broker 实例。
20.2.Doris 端口号
主要用到的端口号:
- 8030:FEHttpServer
- 8040:BEHttpServer
- 9030:FEMysqlServer
20.3.Doris 的特点
1、Doris 对于数据查询可以做到毫秒级别的响应速度,但是对于高并发写入不太友好,如 streamload 写入的时候最好是每 1s 或者多秒执行一次 streamload。
2、Doris 支持 jdbc 协议。
3、Doris 的 FE,BE 节点都可以进行扩容和缩容。
20.4.Doris 使用过程中的问题
1、Doris 安装后会用自身拥有的 jdk,如果我们自行安装就会和 Doris 进行冲突导致 Doris 的宕机。
2、使用 Mysql 客户端登录,查看 FE 的状态:
mysql-hip-P9030-uroot-pxxxxx
。
3、Mysql 中的 varchar 到 Doris 中转变成的字符类型要×3。
4、Doris 中的文本类型为 String。
版权归原作者 bmyyyyyy 所有, 如有侵权,请联系我们删除。