大数据初级汇总

文章介绍了Linux系统中监控内存使用的方法,如free、top、vmstat和ps命令。接着讨论了Hadoop生态中的Spark、HDFS、HBase和Hive的相关概念,包括Spark的内存管理、分区策略、数据本地化以及容错机制。此外,还涵盖了MapReduce的排序过程、分区和分桶的概念,以及YARN的提交模式和Hadoop的优化策略。
摘要由CSDN通过智能技术生成

limit查看内存

在Linux中,你可以使用多个命令来查看系统的内存使用情况。以下是几个常用的命令:

  1. free命令:用于显示系统的内存和交换空间(swap)使用情况。
    free -h :以人类可读的格式显示内存使用情况。
    free -m :以MB为单位显示内存使用情况。
    free -g :以GB为单位显示内存使用情况。
  2. top命令:用于实时监视系统的资源使用情况,包括内存。
    在top命令中,按下Shift + m 可以按照内存使用情况对进程进行排序,显示最耗费内存的
    进程在最上面。
  3. vmstat命令:用于显示系统的虚拟内存统计信息,包括内存使用、缓冲区和交换空间等。
    vmstat :显示虚拟内存统计信息。
    vmstat -s :显示详细的虚拟内存统计信息。
  4. ps命令:用于显示当前运行进程的信息,包括进程的内存占用情况。
    ps aux :显示所有进程的详细信息,包括内存使用情况。
  5. htop命令:类似于top命令,但提供了更直观和交互式的界面,可以查看内存使用情况以及其他系
    统资源。
    htop :打开htop界面,显示系统的资源使用情况。
    这些命令可以帮助你实时监视和了解Linux系统的内存使用情况。选择合适的命令可以根据你对内存信
    息的需求和个人喜好。

HDFS中小文件怎么解决?

  1. 合并文件:将多个小文件合并为一个大文件。可以使用Hadoop中MR作业来实现文件合并操作,或者使用hdfs dfs -getmerge命令将多个小文件合并为本地文件,然后再将合并后的文件上传到HDFS
  2. 序列文件:这是一种二进制文件格式,可以容纳键值对或记录数据结构。可以将小文件转化为序列文件,减少存储空间的占用,并提高读取效率
  3. 归档文件:把小文件打包为一个归档文件,比如TAR或者ZIP,然后上传到HDFS
  4. HBase:如果小文件需要进行频繁的随机访问,可以将小文件存储在HBase上
  5. 写入HDFS之前,对数据进行预处理和合并
  6. 调整分片策略

MapReduce排序

  1. 在MapReduce的shuffle过程中通常会执行三次排序,分别是:

    Map输出阶段(溢写阶段):根据分区以及key进行快速排序

    Map的合并溢写文件:将同一个分区的多个溢写文件进行归并排序,合成大的溢写文件

    Reduce输入阶段:将同一分区,来自不同Map task的数据文件进行归并排序

    最后阶段:使用了堆排作最后的合并过程。

key排序、二次排序、全排序

key排序:按照键对数据进行排序

二次排序:在键排序的基础上,对于相同的键,再根据其他字段进行排序

全排序:对整个数据集进行排序,不仅仅是在单个reduce节点上

快排和归并

快排和归并都是采用分治的思想

快排:

    • 选择一个基准元素(一般都是第一个或最后一个)
    • 将数组分为两个子数组,小于基准元素放左边,大于基准元素放右边
    • 对左右子数组分别递归地应用快速排序算法
    • 合并左右子数组和基准元素,得到排序后的数组

归并:

    • 将数组分为两个相等大小的子数组
    • 递归地对两个子数组应用归并排序算法
    • 合并两个有序子数组,得到一个有序的大数组

动态分区、静态分区

总的来说,静态分区是预先定义好分区规则和值的分区方式,适用于已知的、固定的分区情况。而动态
分区是根据实际数据的分布情况动态生成分区,适用于数据量不确定、分区规则经常变化的情况。选择
静态分区还是动态分区取决于具体的业务需求和数据特点。

动态分区:通过MR任务对数据进行指定字段进行分组

    • 不用手动指定分区目录
    • SQK执行时候确定的
    • 有结果集才创建分区
    • 方便快捷,但是可能会占用大量资源
    • 通过普通表选出的字段包含分区字段,分区字段放在最后,多个分区字段按照分区顺序放置

静态分区:指定分区,直接插入,不用执行计算任务,直接拉取

    • 需要手动指定具体的分区目录
    • 列是在编译时期,通过用户传递列名来决定的
    • 静态分区不管有没有数据都会创建该分区
    • 用于分区少,分区名可以明确的数据

spark任务提交参数

  1. class:指定要运行的主类。
  2. –master:指定 Spark 应用程序运行的集群管理器的 URL
  3. –deploy-mode:指定 Spark 应用程序的部署模式,可以是 client 或 cluster。
  4. –executor-memory:设置每个 Executor 的内存大小。例如,1g 表示 1GB,500m 表示 500MB。
  5. –driver-memory:设置 Driver 程序的内存大小。
  6. –num-executors:设置 Executor 的数量。
  7. –executor-cores:设置每个 Executor 的 CPU 核心数。

Spark 为什么比 MapReduce 快

Spark基于内存:Spark是基于内存进行数据处理操作的,而MapReduce则是基于磁盘进行数据处理

DAG有向无环图:Spark中具有DAG有向无环图,在这个过程中减少了shuffle以及落盘的次数

粗颗粒度资源申请:Spark分配资源是静态的,在application启动前已经为其分配好了所有的 资源,后
续不需要在分配,执行较快,但对资源的利用率相对较差。

vim查找某个字符

可以使用 / 或 ? 命令来查找特定字符或字符串

  1. 普通模式下查找:
    按下/ 键,然后输入要查找的字符,按下回车。Vim将会定位到第一个匹配的字符位置。
    按下n 键可以查找下一个匹配的字符。
    按下N 键可以查找上一个匹配的字符。
  2. 命令模式下查找:
    按下: 键,然后输入/ 加上要查找的字符,按下回车。例如: :/字符。
    按下回车后,Vim会定位到第一个匹配的字符位置。
    按下n 键可以查找下一个匹配的字符。
    按下N 键可以查找上一个匹配的字符。
    另外,Vim还提供了其他一些高级的查找命令和选项,例如正则表达式匹配、查找替换等。可以通过
    Vim的帮助文档( :help )或在线资源查找更多关于Vim查找功能的详细信息。

脑裂

原因:

    • 网络问题:网络故障、断开或拥塞可能使节点无法相互通信,导致脑裂。
    • 节点故障:当某个节点无法正常工作时,可能会导致与该节点通信的一组节点被分离,从而引发脑裂。
    • 通信延迟:节点之间的通信不是实时的,可能受到网络延迟、负载等因素的影响。如果在信息交换过程中出现较大的通信延迟,可能会引起超时或其他问题,从而导致脑裂。
    • 逻辑分区:某些情况下,分布式系统可能会被设计为逻辑分区。如果这些逻辑分区之间无法相互通信,就会产生脑裂现象。
    • 不一致的配置或策略:果分布式系统中的不同节点使用了不一致的配置或策略,可能会导致节点在某些情况下被划分到不同的子集中,从而引发脑裂

解决方法:

      • 使用一致性算法
      • 冗余备份
      • 心跳检测与故障恢复
      • 分区感知路由策略:通过将请求路由到同一分区的节点,可以减少脑裂对系统的影响。这样,在发生脑裂时,只有同一分区的节点受影响,而其他分区的节点可以继续提供服务。
      • 容错与退化设计:容错设计包括使用多个独立的子系统,以确保系统的一部分仍然可用。退化策略则是在脑裂发生时暂时禁用某些功能或服务,以保证系统的核心功能仍然可用。

分区/分桶

分区和分桶在Hive中都可以用于优化查询性能和数据管理,但其使用场景略有不同。分区适用于根据某
个特征对数据进行划分和过滤,而分桶适用于将数据均匀地分散到多个桶中,提高查询性能和数据的均
匀性。
分区的选择可以根据查询需求和数据特征进行,例如按照日期、地区等进行分区。而分桶的选择可以根
据数据的大小和查询需求进行,桶的数量应根据数据量和查询频率合理选择,以保持数据的均匀性和查
询性能。

分区:分区是将系统的数据和功能划分为多个独立的子集或区域的过程。

  1. 哈希分区:根据数据的特征或键进行哈希计算,并将相同哈希值的数据分配到同一个分区中
  2. 范围分区:根据数据的取值范围进行划分,将数据按照一定的范围划分到不同的分区中
  3. 地理分区:将系统按照地理位置进行划分,将相邻或附近的节点组成一个分区。这样可以减少网络传输延迟,并提高系统的响应速度。
  4. 功能分区:将系统按照不同的功能或服务进行划分

分桶:是将数据分散到多个桶中,以实现负载均衡、提高查询性能和减少存储空间的消耗。

  1. 哈希分桶:使用哈希算法来将数据项映射到不同的桶中
  2. 范围分桶:按照数据项在一个特定范围内的取值将其分配到不同的桶中
  3. 频率分桶:根据数据项出现的频率将其分配到不同的桶中

HBase rowkey设计原则

唯一性

散列性

顺序性

简洁性

避免频繁更新

怎么实现散列

  1. 加盐
  2. 哈希前缀:在设计 RowKey 时,将一部分常用的前缀信息进行哈希处理,并将哈希结果作为 RowKey 的一部分。这样可以将具有相同前缀信息的数据行散列到不同的 Region Server 上
  3. 基于时间戳:如果需要按照时间范围查询数据,可以将时间戳作为 RowKey 的一部分。并且,在时间戳的基础上添加一些随机数或其他信息,以增加散列性和顺序性。

RDD五大特性

  1. 弹性(Resilient)容错性:RDD具有容错性,即当RDD的某个分区数据丢失时,它可以通过RDD的血统
    (Lineage)重新计算丢失的数据,从而实现数据的容错和恢复。
  2. 分区(Partitioning):RDD将数据划分为多个逻辑上的分区,每个分区都可以在集群中的不同节
    点上进行并行处理。分区的划分可以根据数据的特点和需求进行灵活配置。
  3. 依赖(Dependency):RDD通过血统(Lineage)来记录其来源和转换操作的依赖关系,从而实
    现数据的容错性和恢复性。RDD的每个转换操作都会生成一个新的RDD,并建立与父RDD的依赖
    关系。
  4. 不可变性(Immutability):RDD的数据是不可变的,一旦创建就不能修改。这种不可变性使得
    RDD可以进行容错和恢复,并支持数据共享和并行处理。
  5. 惰性计算(Lazy Evaluation):RDD具有惰性计算的特性,即在遇到Action操作之前,RDD的转
    换操作不会立即执行,而是记录下转换操作的计划(DAG图),并在Action操作触发时按需计算。
    这种惰性计算可以优化执行计划,减少不必要的计算开销。

spark持久化

临时保存:

RDD可以使用persist()指定持久化级别

内存放不下就放磁盘

DataFrame或Dataset可以使用cache()缓存

内存

持久保存:

checkpoint 检查点

会从头执行(出现故障从头计算)

Linux查看当前目录

pwd:显示完整路径

ls:显示当前目录下的文件和子目录

ls-l:以长格式显示当前目录下的文件和子目录,包括权限、所有者、文件大小等详细信息

zookeeper paxos算法,最终模型

有主模型:

数据一致性

leader发起提议,询问跟随着

各个跟随者响应,半数通过,提议生效

leader通知各个跟随者同步提议事务

所有提议必须由总统提出

选主

加入投票机制(过半原则)

看PID最大的,无脑投最大(快速选主)

加入朝代标记(解决脑裂问题)

议员PID必须与公共PID相同(保证数据完整性)

其他议员宕机重启直接找总统同步数据即可

参与投票节点过多,加入观察者(节省投票时间)

count,distinct数据倾斜

count数据倾斜:对数据集进行计数操作时,数据分布不平衡

解决:

基于哈希分片

基于范围分片

distinct数据倾斜:对数据集进行去重操作时,数据的分布不平衡

解决:

采用

分桶

spark宽窄依赖,stage怎么划分

宽窄依赖:

窄依赖是指一个父 RDD 的每个分区只被子 RDD 的一个分区所使用

宽依赖是指一个父 RDD 的某个分区可能会被多个子 RDD 的分区所使用

窄依赖只需要简单地将数据传递给下游的子 RDD 分区,而宽依赖涉及到数据的重新分区和重组,需要进行 Shuffle 操作。

stage:

每个 Job 会被拆分成多个 Task,作为一个 TaskSet 任务集,其名称为 Stage

Stage 的切割规则为:从后往前,遇到宽依赖就切割 Stage 。

spark减少分区

spark分区:

哈希分区

范围分区

自定义分区

减少分区:

    1. coalesce方法可以将RDD或DataFrame的分区数量减小到指定的值
    2. repartition 方法会根据指定的分区数量对 RDD 或 DataFrame 进行重新分区
    3. 可以使用适当的分区器来控制分区的数量

Spark 数据本地化级别与区别

Spark数据本地化级别是指Spark作业在执行时数据存放在哪个位置以提高计算性能和效率。Spark提供
了以下几种数据本地化级别:

  1. PROCESS_LOCAL(进程级本地化):
    数据本地化在同一个进程内完成。即将需要计算的数据存放在同一个Executor进程的内存中,
    避免网络传输开销。
    这是最高级别的本地化级别,适用于数据量较小,不需要跨节点传输的情况。
  2. NODE_LOCAL(节点级本地化):
    数据本地化在同一个节点内完成。即将需要计算的数据存放在同一个节点的内存中,减少跨节
    点的数据传输。
    适用于数据量较大,但仍可以容纳在一个节点的内存中的情况。
  3. RACK_LOCAL(机架级本地化):
    数据本地化在同一个机架内完成。即将需要计算的数据存放在同一个机架的节点内存中,减少
    跨机架的数据传输。
    适用于数据量很大,无法完全存放在一个节点内存中的情况。
  4. ANY(任意位置本地化):
    数据可以存放在任意节点的内存中。这是最低级别的本地化级别,不要求数据在特定位置本地
    化。
    适用于数据量非常大,无法在一个节点或机架内存放的情况。
    通过设置不同的数据本地化级别,Spark可以根据数据的位置和调度策略来选择最适合的数据本地化方
    式,减少数据传输开销,提高计算性能和效率。在实际使用中,可以根据集群的网络拓扑和数据分布情
    况来选择合适的数据本地化级别,以达到最佳的性能优化效果。

看到一个陌生的算子,在不运行代码的情况下,怎么区分它是转换算子和还是行动算子

  1. 在Spark中,通常可以通过查看算子的返回类型来区分转换算子和行动算子。Spark中的转换算子返回的
    是一个新的RDD或DataFrame,而行动算子返回的是具体的结果或触发作业执行的动作。
    例如,假设有一个名为 data 的RDD,你看到了以下代码:
    val result = data.filter(_ > 0).map(_ * 2).collect()
    通过观察代码可以发现, filter 和 map 是连续调用的转换算子,它们返回一个新的RDD,并没有立即
    执行计算。而最后的 collect 是一个行动算子,它触发了实际的计算并返回最终的结果。
    另外,一些常见的行动算子还有 count 、 first 、 take 等,它们都会触发作业的执行并返回相应的结
    果。
    因此,当你遇到一个陌生的算子时,可以查看其返回类型来判断它是转换算子还是行动算子。转换算子
    返回的是新的RDD或DataFrame,行动算子返回的是具体的结果或触发作业执行的动作。

血缘关系

Spark 根据用户 Application 中的 RDD 的转换算子和行动算子,会生成 RDD 之间的依赖关系,多个
RDD 之间的关系又 形成一条关系链叫做 RDD 的血统(Lineage)。如下图,图中每个猿人都可以看做
是一个 RDD 。同时也生成了逻辑上的 DAG(有向无环图)。每一个 RDD 都可以根据其依赖关系一级
一级向前回溯重新计算,这便是 Spark 实现容错的一种手段 (因为 RDD 不会保存数据),如果某个
RDD 丢失了,则可以根据血缘关系,从父 RDD 计算得来。

    1. 血缘关系有两种类型:宽依赖和窄依赖
    2. spark可以根据血统/依赖关系来重新计算丢失的分区的数据,而不是从新计算
    3. 血缘关系也带来了一定的开销。在宽依赖的情况下,需要进行数据的 shuffle 操作,这可能会导致数据的重组和网络传输,增加计算的开销
    4. 血缘关系是惰性求值的,在Spark中执行一个转换操作时,只会记录转换操作而不会立即执行。只有当遇到一个行动算子(例如 count、collect)时,Spark 才会根据血缘关系来计算结果。

CAP原则

CAP原则是分布式系统设计中的一个基本原则,无法同时满足一致性,可用性和分区容错性.

一致性:

分布式系统中所有的数据副本在任何时刻都保持一致

可用性:

分布式系统能够提供可靠性和持续的响应

分区容错性:

分布式系统在面对网络分区故障的情况下继续正常运行

YARN模式 client和cluster的区别

Client提交模式适用于交互式和即时响应的场景,应用程序的生命周期与客户端程序相关联。在 YARN Client 模式下,Driver 在应用提交的本地机器上运行,ApplicationMaster 该模式下没有作业调度的功能

Cluster提交模式适用于长期运行的、不需要与客户端交互的应用程序,应用程序的生命周期与YARN集群的生命周期相互独立。在 YARN Cluster 模式下,Driver 运行在ApplicationMaster 中

MR任务跑不完的原因

  1. 数据量过大:如果输入的数据量太大了,而集群的计算资源能力有限,可能导致任务无法及时完成
  2. 数据倾斜:输入数据分布不均匀或者某些数据的键值对过于频繁,可能导致某些Reduce节点负载过重,导致任务执行时间过长甚至任务失败
  3. 内存溢出:如果MR任务要求使用较大的内存,但是集群的节点内存配置不够,就有可能发生内存溢出错误,导致任务失败或者无法完成
  4. 网络故障:由于MR涉及大量的数据传输和节点的通信,所以集群中的网络出现故障,就可能导致任务无法完成
  5. 运行时错误:MR任务在运行时可能会遇到运行时错误,比如数据格式不匹配,权限问题等,也会导致任务无法完成
  6. 配置错误:MR任务的配置可能存在问题,从而导致任务无法完成

spark中shuffle是什么?

shuffle是在执行数据转换操作时,根据数据重新分区.重新组合,和排序的过程

spark中shuffle用于在不同的计算节点之间重新分发和重新排序数据

spark中的shuffle通常发生在聚合操作(reduce,groupByKey)和连接操作(join操作)

RDD中reduceByKey,groupByKey那个性能好

reduceByKey比groupByKey性能好

groupByKey是将相同的键所有数据都集中到一个计算节点上,然后进行分组

reduceByKey操作在每个分区上先进行本地聚合,将相同键的数据聚合成单个键值对,然后再进行全局的聚合操作

HIve 开窗函数 工作流程

SUM()

AVG()

COUNT()

MIN()

MAX()

RANK():为每一行分配一个唯一的数字

工作流程

    1. 数据导入
    2. 元数据管理:用元数据来描述和管理数据
    3. 查询编写
    4. 查询优化和执行
    5. 数据处理
    6. 查询结果处理

Hive与Hadoop工作流程

  1. 输入HQL,将查询语句发送到Driver执行
  2. Driver通过编译器解析HQL
  3. 编译器将元数据请求发送到MetaStore
  4. MetaStore将元数据响应给编译器
  5. 编译器检查要求,重新发送计划给Driver
  6. Driver将执行计划发送给执行引擎
  7. 执行引擎发送任务,同时对元数据进行DDL操作
  8. 执行引擎将任务发送到ResourceManage,RM把任务分给NodeManager,由Node Manager分布式执行MR任务
  9. 任务执行结束,将结果返回给执行引擎,同时执行引擎找NameNode获取数据
  10. 执行引擎接收DataDode发送的结果
  11. 执行引擎将结果发送到Driver
  12. Driver将结果发送到Hive接口

HBase三级缓存

HBase是一个分布式、面向列的NoSQL数据库系统,其中有三级缓存用于提高数据读取性能。这三级缓
存分别是:

  1. BlockCache(块缓存):
    BlockCache是HBase的第一级缓存,它位于RegionServer内存中,用于缓存HFile的数据
    块。
    HFile是HBase中存储数据的文件格式,BlockCache会缓存HFile中的数据块,以便快速响应
    读取请求。
    BlockCache的数据是被压缩和序列化的,它可以减少磁盘IO,提高数据读取的性能。
  2. MemStore(内存存储):
    MemStore是HBase的第二级缓存,它也位于RegionServer内存中,用于缓存写入数据。
    当客户端向HBase写入数据时,数据首先会被写入MemStore,然后在后台周期性地刷写到
    HFile中。
    由于数据在MemStore中是有序存储的,写入速度非常快,从而提高了写入性能。
  3. BlockCache(文件系统缓存):
    文件系统缓存是HBase的第三级缓存,它位于HBase集群节点的操作系统缓存中。
    HBase利用Hadoop的HDFS进行数据存储,文件系统缓存可以将部分HFile的数据块缓存在操
    作系统缓存中。
    当RegionServer在BlockCache中没有找到需要的数据块时,它会从操作系统缓存中读取,以
    加快数据的读取速度。
    这三级缓存的存在可以大幅提升HBase的读取性能。首先,BlockCache可以减少磁盘IO,将频繁访问
    的数据块缓存在内存中,加快数据的读取。其次,MemStore可以将写入数据暂时缓存,使得写入速度
    更快。最后,文件系统缓存可以在BlockCache未命中时提供备用数据,进一步提高读取性能。这些缓
    存机制的结合使得HBase具备高吞吐量和低延迟的特性,适用于大规模数据存储和实时访问的场景。

spark算子产生shuffle的算子

  1. groupByKey算子:按照键值对数据进行分组,将具有相同键的数据聚合在一起
  2. reduceByKey算子:按照键值对数据进行分组,并对每组数据进行聚合操作
  3. aggregateByKey算子:按照键值对数据进行分组,并对每组数据进行聚合操作,与reduceByKey不同,aggregateByKey返回不同类型的结果
  4. sortByKey算子:根据键值对对数据进行排序
  5. join:将两个RDD按照键进行连接操作

spark提交模式

本地模式

Standalone模式

YARN模式

Hadoop优化 spark优化

Hadoop作为一个大数据处理框架,优化是提高其性能和效率的重要手段。以下是一些常见的Hadoop
优化策略:

  1. 数据本地化:尽量将数据存储在离计算节点近的位置,减少数据的网络传输和读取时间。
  2. 合理设置块大小:合理设置HDFS块大小,通常是128MB或256MB,以减少小文件和碎片化。
  3. 压缩数据:对HDFS上的数据进行压缩,可以减少磁盘IO和网络传输开销。
  4. 使用合适的存储格式:选择合适的数据存储格式,如Parquet、ORC等,可以提高数据读取性能。
  5. 数据分区:在MapReduce程序中,合理进行数据分区,避免数据倾斜和不均匀的情况。
  6. 调整任务数:根据集群资源和数据规模,适当调整任务数和分区数,以充分利用资源。
  7. Combiner函数:使用Combiner函数来进行局部聚合,减少Shuffle的数据量。
  8. 增量式输出:使用增量式输出来减少HDFS的写入次数,提高写入性能。
  9. 任务重用:启用任务重用,减少任务启动的开销。
  10. 内存管理:调整任务的内存配置,合理分配内存资源。
  11. 数据缓存:使用数据缓存技术,如Memcached或Redis,来加速数据读取。
  12. 采用更高版本:使用较新的Hadoop版本,以获得更多性能优化和新功能。
    以上是一些常见的Hadoop优化策略,根据具体场景和需求,可以选择合适的优化措施来提高Hadoop
    集群的性能和效率。

spark资源充足 这个任务怎么变快

在Spark中,当资源充足时,可以通过以下方式来使任务变得更快:

  1. 增加并行度:通过增加并行度,即增加并发执行的任务数,可以更充分地利用资源。可以通过调
    整spark.default.parallelism 参数或使用repartition 等算子来增加并行度。
  2. 使用更快的算子:在Spark中,有一些算子比其他算子更快,比如使用reduceByKey 替代
    groupByKey 、使用map 替代flatMap 等。选择性地使用性能更好的算子可以加快任务的执行速
    度。
  3. 内存存储和缓存:将常用的数据集缓存在内存中,可以减少数据的重复计算,从而提高任务的执行
    速度。可以使用cache 或persist 方法来缓存数据集。
  4. 数据本地化:尽量将数据存储在计算节点的本地磁盘上,减少数据的网络传输和读取时间。
  5. 数据分区和倾斜处理:合理进行数据分区,避免数据倾斜和不均匀的情况,以充分利用资源。
  6. 使用高性能文件格式:选择合适的数据存储格式,如Parquet、ORC等,可以提高数据读取性能。
  7. 合理设置资源参数:根据集群资源和数据规模,适当调整任务的资源配置,如内存、CPU核数等,
    以充分利用资源。
  8. 使用数据预聚合:对数据进行预聚合,减少Shuffle的数据量,从而加快任务的执行速度。
  9. 并行计算:对于可以并行计算的任务,可以将其并行执行,从而缩短任务的执行时间。
    总的来说,在资源充足的情况下,通过合理地调整并行度、选择更快的算子、缓存数据、数据本地化等
    方法,可以使Spark任务变得更快。同时,也需要根据具体场景和数据特点,综合考虑各种优化策略,
    以获得更好的性能。

spark YARN提交流程

YARN和Spark是两个分布式计算框架,它们的任务提交流程有所不同:
YARN提交流程:

  1. 用户通过命令行或Web界面向YARN集群提交一个应用程序,例如MapReduce作业。
  2. ResourceManager接收到应用程序的提交请求,并为应用程序分配一个
    ApplicationMaster(AM)。
  3. ResourceManager通知NodeManager在集群中的某些节点上启动AM。
  4. AM在分配的节点上启动后,负责协调和管理应用程序的执行。
  5. AM向ResourceManager申请容器资源,以便启动应用程序的任务(例如Map或Reduce任务)。
  6. ResourceManager根据可用资源情况,将容器资源分配给AM。
  7. AM通过心跳机制与ResourceManager保持通信,报告任务的执行状态。
  8. 当应用程序执行完毕或失败时,AM通知ResourceManager释放已占用的资源,并结束应用程序。

Spark提交流程:

  1. 用户通过spark-submit 命令或其他方式将Spark应用程序提交给Spark集群。
  2. 在应用程序的Driver程序中,SparkContext被创建并连接到集群的ResourceManager(通常是
    YARN的ResourceManager)。
  3. ResourceManager为应用程序分配一个Executor,用于在集群中的某个节点上执行任务。
  4. Driver程序将应用程序的任务划分为不同的阶段(Stages),并将任务发送给Executor。
  5. Executor在节点上启动后,根据Driver程序发送的任务,在本地执行任务并进行计算。
  6. Executor将计算结果返回给Driver程序。
  7. Driver程序根据任务的执行情况,决定是否需要继续执行更多的任务或结束应用程序。
    总结起来,YARN和Spark的提交流程都是从用户提交应用程序开始,通过ResourceManager或
    SparkContext将应用程序的任务分配给集群中的节点执行,然后汇总计算结果并通知用户任务的执行状
    态。不同之处在于YARN是通用的资源管理框架,而Spark是基于YARN或其他资源管理框架的分布式计
    算框架。

snappy数据压缩 数据存储

snappy提供了各种编程语言的库和接口

spark数据存储:

分布式文件系统

列式存储格式

关系型数据库

NoSQL数据库

内存存储

hive内部表,外部表

内部表:连带删除HDFS上的数据

管理起来方便

通常用来测试使用

用完就删除,防止资源浪费

外部表:更安全

误删也只是目录,重新建就好

总结: 内部表是Hive默认的表类型,数据和元数据由Hive管理,删除表时数据也会被删除。而外部表
的数据由外部存储系统管理,Hive仅维护表的元数据信息,删除表时只删除元数据而不删除数据。外部
表通常用于与其他系统共享数据,以便在Hive中进行查询和分析。

列式存储和行式存储的异同

行式存储:

磁盘读取开销大

行式存储写入一次完成,保证了数据的完整性

行存储在要修改数据的指定位置写入一次就行

列式存储:

需要将行数据块缓存起来,更占内存

列存储要把一行记录拆成单列保存,写入次数比行存储多

列存储将磁盘定位到多个列上分别写入

转换算子

  1. reduceByKey:对包含键值对的RDD进行聚合,根据相同的键的值进行聚合操作
  2. groupByKey:相同的键所有数据都集中到一个计算节点上,然后进行分组
  3. map:对RDD中的每一个元素应用一个函数,返回一个新的RDD,新的RDD中的元素类型可能与原RDD中元素类型不同
  4. sortBy:对包含键值对的RDD进行排序,根据键进行排序
  5. filter:对RDD中的每个元素应用一个谓词函数,返回一个新的RDD,新的RDD中只包含满足谓词函数条件的元素

MapReduce的计算流程

MR的计算流程分为Map阶段和Reduce阶段 Map和Reduce中间还有一个shuffle阶段

Map阶段:

切片

根据hash算法算出K-V值

shuffle阶段:

map阶段生成的键值对根据键分组,相同的键的键值对会被发送到同一个reduce

Reduce阶段:

reduce阶段会进行最终的排序、聚合并输出最终的结果

Hadoop MR的shuffle和Spark shuffle的区别

  1. Hadoop是做完一个数据拉一个放内存里,等全部完成在聚合;Spark是在拉取的时候就开始聚合,不用等全部完成
  2. Hadoop shuffle数据通过磁盘写入;Spark shuffle 数据写入内存,内存不够时写入磁盘
  3. Hadoop shuffle通过HTTP协议传输数据;Spark shuffle通过NIO传输协议
  4. Hadoop shuffle使用分区器进行分区;Spark shuffle默认使用哈希分区
  5. 在处理大规模数据时,Hadoop shuffle比Spark shuffle相对稳定,因为Spark shuffle内存使用比较多,可能会导致内存不足的问题

为什么HBase可以做到百亿数据秒级查询

基于HDFS的存储,可以将数据分块存储到不同的节点上

基于分布式框架,可以将数据分散存储到多个节点上,可以在多台机器上同时处理请求

列族存储,将相同属性的列存储在一起,可以减少I/O次数

预分区,可以将数据在多个节点上分区存储,可以有效地避免数据倾斜等问题,提高查询效率

基于索引查找,支持基于行键和列族的索引查找

1.求部门前三薪资 SQL 实现思路

要实现查询部门前三薪资的 SQL,可以按照以下思路进行实现:

  1. 使用 GROUP BY 子句按照部门进行分组,计算每个部门的平均薪资。
  2. 使用子查询或公用表表达式 (CTE) 获取每个部门的平均薪资,并按照平均薪资进行降序排序。
  3. 使用窗口函数或子查询为每个部门的薪资排名。
  4. 使用条件筛选保留排名前三的记录。

下面是一个示例 SQL 查询语句的实现:

WITH department_avg_salary AS (
  SELECT
    deptno,
    AVG(sal) AS avg_salary
  FROM
    emp
  GROUP BY
    deptno
)
SELECT
  empno,
  ename,
  sal,
  deptno
FROM
  (
    SELECT
      emp.*,
      ROW_NUMBER() OVER (PARTITION BY emp.deptno ORDER BY emp.sal DESC) AS rank
    FROM
      emp
      JOIN department_avg_salary ON emp.deptno = department_avg_salary.deptno
  ) ranked_employees
WHERE
  rank <= 3;

在这个示例中,首先使用 WITH 子句定义了一个名为 department_avg_salary 的公用表表达式,计算每个部门的平均薪资。然后,使用子查询将每个员工与其所属部门的平均薪资进行连接,并使用窗口函数 ROW_NUMBER() 计算每个部门内员工的薪资排名。最后,在外层查询中筛选出排名前三的员工记录。

2.连续 7 天登录 SQL 实现过程

  1. 首先,假设有一个名为 user_login 的表,其中包含了用户的登录记录,包括用户ID(user_id)和登录日期(login_date)字段。
  2. 使用子查询或公用表表达式 (CTE) 来获取每个用户连续登录的天数。在子查询中,使用窗口函数和日期函数来计算每个登录日期与前一天日期的差值(间隔天数),并将结果作为新的列。
  3. 使用外层查询来筛选出连续登录天数达到7天的用户记录。

以下是一个示例 SQL 查询语句的实现:

WITH consecutive_logins AS (
  SELECT
    user_id,
    login_date,
    login_date - LAG(login_date) OVER (PARTITION BY user_id ORDER BY login_date) AS day_diff
  FROM
    user_login
)
SELECT
  user_id,
  MIN(login_date) AS start_date,
  MAX(login_date) AS end_date,
  COUNT(*) AS consecutive_days
FROM
  consecutive_logins
WHERE
  day_diff = 1
GROUP BY
  user_id
HAVING
  COUNT(*) >= 7;

在这个示例中,使用 WITH 子句定义了一个名为 consecutive_logins 的公用表表达式,计算了每个用户的连续登录天数。窗口函数 LAG() 用于获取前一天的登录日期,从而计算出当前登录日期与前一天的差值(间隔天数)。然后,在外层查询中筛选出连续登录天数为1的记录,并使用 GROUP BY 子句按用户ID进行分组。最后,使用 HAVING 子句筛选出连续登录天数达到7天及以上的用户记录。

3.统计每个员工前三个月的薪水,每月统计一次

  1. 确定数据表结构:首先,确定包含员工薪水信息的数据表,表中应至少包含员工编号、薪水日期和薪水金额等字段。
  2. 确定统计时间范围:确定需要统计的时间范围,即前三个月的时间段。
  3. 筛选数据:使用SQL的WHERE子句筛选出在统计时间范围内的薪水记录。可以使用日期函数和比较操作符来筛选出符合条件的记录。
  4. 分组和聚合:使用SQL的GROUP BY子句按照员工编号进行分组,并使用聚合函数(如AVG)计算每个员工在每个月的平均薪水。
  5. 排序:根据需要,可以使用ORDER BY子句对结果进行排序,例如按照员工编号和月份进行排序。
SELECT
  empno,
  YEAR(payment_date) AS year,
  MONTH(payment_date) AS month,
  AVG(amount) AS avg_salary
FROM
  salary
WHERE
  payment_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 3 MONTH)
GROUP BY
  empno, YEAR(payment_date), MONTH(payment_date)
HAVING
  YEAR(payment_date) = YEAR(CURRENT_DATE()) AND MONTH(payment_date) <= MONTH(CURRENT_DATE())
ORDER BY
  empno, YEAR(payment_date), MONTH(payment_date)

在这个查询中,假设存在名为 salary 的表,包含员工的薪水信息,包括员工编号(empno),薪水支付日期(payment_date)和薪水金额(amount)等字段。

查询逻辑如下:

  1. 使用 WHERE 子句筛选出支付日期在过去三个月内的薪水记录。
  2. 使用 GROUP BY 子句按照员工编号、年份和月份进行分组。
  3. 使用 HAVING 子句限制结果只包含当前年份以及当前月份或之前的记录,确保只统计前三个月的数据。
  4. 使用 ORDER BY 子句按照员工编号、年份和月份排序结果。

这样可以得到每个员工在前三个月内每个月的平均薪水数据。

请注意,上述查询中使用的表名和字段名是根据你之前提供的表结构假设的,你需要根据实际情况进行相应的调整。另外,该查询假设薪水支付日期是以日期格式存储的,如果实际情况不同,你可能需要调整日期函数的使用方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值