Advertisement

大数据笔记(学习归纳)

阅读量:
  • 本文初衷是为了学习归纳,若有错误,请指出。

修改记录

时间 内容
2020年4月10日 第一次发布
2020年4月16日 添加MaxCompute SQL部分
2020年9月14日 新增数仓部分笔记

大数据架构

基础知识题

大数据组件概念

集群 :多个人做同样的事

分布式 :多个人协作,干不同的事情。

Hadoop 是一种基于分布式存储与计算架构的开源项目(The open-source project),其核心组件包含HDFS分布式文件系统用于数据存储以及MapReduce技术实现分布式计算,并提供资源调度与管理功能(如Yarn)。该框架支持高可靠性、可扩展性和容错能力(通过数据副本和集群实现)。

Yarn 是为了解决资源管理和计算组件之间的分离问题而在Hadoop 2.0中引入的一种技术,在Hadoop 2.0中出现的原因是为了应对存储在HDFS中的数据需要更为复杂的交互模式的需求,并通过提供更丰富的处理框架来提升系统的灵活性和扩展性。

ZooKeeper 是一个分布式、开源的应用程序协调器(service),基于观察者模式被设计为协调分布式应用程序。它通过注册观测者来接收数据变化。

该方案基于Facebook开源的一个数据分析平台,其核心功能专为应对海量结构化日志的数据统计需求而设计,能够将复杂的存储文件转换为便于操作的表格形式,并采用与传统SQL相似的查询方式对大量数据进行采集与分析,其主要特点是实现离线环境下的高效处理能力,本质上实现了将关系型数据库的技术架构与分而治之的计算范式相结合

在这里插入图片描述

参考文献:《hadoop之hadoop用途方向》书名信息:

参考文献:《大数据基本概念》书名信息:https://www.sohu.com/a/259640251_741445

大数据环境搭建

1.介绍一下集群搭建的过程?
  • 获取Hadoop 2.X源码包及 JDK1.8官方版本包,并从官方HDFS项目网站下载官方认证版HDFS组件,默认安装 CentOS7虚拟镜像,在我的测试环境中使用虚拟机搭建三台集群环境。

  • 设置Linux操作系统并关闭网络防火墙服务以阻止不必要的流量泄漏;禁用SeLinux以避免潜在的安全漏洞;配置集群系统的时间同步机制以确保数据一致性。

  • 使用虚拟机复制另外两台服务器的完整操作系统环境,并正确设置其IP地址;通过ping命令验证各节点之间的通信连接;确保所有节点能够正常访问彼此的数据存储空间。

  • 创建专门用于运行Hadoop服务的用户 account hadoopUser,默认赋予root和hadoopUser权限;为两个主要用户账号配置SSH免秘钥访问权限:

    • 修改etc/hosts文件,在每台服务器上生成公钥对并将公钥信息备份至其他节点;
    • 在集群间进行密钥交换验证;
    • 添加本地公钥文件至用户的 authorized_keys目录中(建议创建该目录),否则可能导致后续Hadoop组件格式化时出现错误;
    • 最终完成所有安全与访问权限配置后重启相关服务以保证新设置生效。
  • 最终要求每台机器都部署Hadoop和JDK软件,并补充相应的环境变量设置。随后需要详细设置hadoop的四大核心配置文件(core-site.xml, hdfs-site.xml, mapred-site.xml, yarn-site.xml)。

  • 随后选择一台机器作为 namenode节点,并进行Hadoop分区格式化操作。完成这些步骤后需启动Hadoop验证集群以确认搭建是否成功。

简述的过程是

部署CentOS7虚拟机环境 -> 配置IP地址以及hosts文件设置并完成时间同步 -> 启用无需密钥的登录机制 -> 部署Hadoop分布式计算框架 -> 配置Hadoop的存储系统参数 -> 启动Hadoop服务并执行MapReduce程序处理任务

2.说一两个搭建过程遇到的坑?

hdfs namenode -format 在进行格式化操作时曾出现过问题。最初遇到的问题是无法通过SSH进行免密钥登录,后来发现配置文件的格式存在异常。建议在粘贴其他地方的配置代码时先用工具进行格式化处理,并检查其中是否存在 中文符号

这个问题需要注意的是虚拟机之间的互联问题。这里采用自定义网络配置VMware hypervisor 8实例,在集群部署时必须确保所有节点处于同一网络范围内,并且确保网络设备与物理服务器上的VMware hypervisor 8实例IP地址之间存在关联关系。

HDFS

1.请介绍一下HDFS?

​ Hadoop由三部分组成:HDFS 、分布式计算MapReduce 和资源调度引擎Yarn

HDFS是一种基于分布式架构的文件存储系统。它采用层级化目录结构,并且其功能模块与常见的操作系统如Linux相似。该系统的根目录通常位于/位置,并且能够跨越多台服务器实现数据存储。在功能上支持基本操作如创建、删除、更新以及文件移动等操作,并且允许用户在使用时感受到数据以虚拟方式存存在单一服务器上的体验。

​ HDFS具有高可用容错率高可扩展 的特点。

​ 在HDFS中有一个核心概念-block 块。

HDFS上的文件遵循128M为单位进行划分,并分别分布在集群的不同数据节点上。需要注意的是,128M是最大值,在实际应用中块文件的大小通常不会达到这个数值。

以确保数据可用性和容错能力得以实现

HDFS系统的结构体系采用了经典的主从型架构Master/Slave模式进行组织设计,在实际运行过程中主要由客户端与服务端构成。其中客户端通过NameNode作为 primary master node 来完成对存储于各个DataNode中的文件信息的访问与管理操作。在这种架构下,NameNode不仅负责协调管理各子节点的工作状态,并且还配置了备用名称节点(secondaryNameNode)作为主要备用 master node 来保证系统的高可用性与稳定性。

在NameNode对每个DataNode进行管理时会采用心跳检测机制以便持续收集节点心跳信息以及各节点块的状态报告这有助于判断集群中的各个节点是否正常运行当Hadoop集群启动初期系统会进入一个切换至安全模式该模式要求99.9%以上的节点均处于正常运行状态只有确认所有关键节点均正常后NameNode才会切换回主工作模式以确保HDFS系统的可用性

HDFS具有其核心优势,在保证系统可靠性的前提下实现了高效的文件管理和数据存储功能。要确保系统高可用性的关键在于消除关键节点故障,在这种情况下,HDFS主要依赖于体系架构中的SecondaryNamenode组件来进行冗余设计。具体来说,在NameNode处于活跃状态时出现问题时,zookeeper负责发送命令使活跃状态下原有的NameNode切换至备用模式,同时将任务转移给处于正常运作中的SecondaryNamenode来进行处理。在这一过程中,zookeeper不仅负责监控和协调NameNode的状态管理,还负责发送命令使活跃状态下原有的NameNode切换至备用模式,同时将任务转移给处于正常运作中的SecondaryNamenode来进行处理

HDFS的分布式架构体现了其高度可扩展性。该系统能够有效缓解内存限制问题,并通过O(1)一致性机制提升吞吐量性能以及对不同应用类型的有效隔离。然而,在实际应用中,只有在集群规模达到数千节点以上时才会采用这种设计模式(其中联邦架构通过支持多个NameNode主节点实现资源分配与数据冗余管理)。

​ 至此HDFS概括性介绍完毕,对于HDFS的读写流程请翻看其它回答。

2.HDFS的机制是指什么,它有什么作用?

HDFS的核心特征体现在其独特的heartbeat mechanism上。众所周知,HDFS采用经典的Master/Slave架构模式,具体而言,每个NameNode负责管理一组DataNodes,该系统利用其独特的heartbeat mechanism进行协调,工作原理如下:

  • 当 master 节点开始运行时, 立即开启并管理一个 ICP 服务;
  • 当各个 slave 节点启动后, 与主节点建立连接, 并每隔三秒钟向主节点发送一次 ICP 服务的心跳数据, 包含当前运行状态信息;
  • 主节点接收到心跳数据后, 根据接收到的主节点状态反馈信息, 将相关操作指令发送至被从的各 slave 节点。

心跳机制的作用有三点

NameNode通过心跳机制全面负责管理数据,并定期从集群中的每个NameNode处接收心跳信息与块状状态更新请求。存在心跳表明该NameNode运行正常,在其块状状态报告中也会包含该DataNode上所有数据的完整列表。

(2)Datanode启动后开始运行并完成对Namenode的注册流程,在此过程中持续通过心跳机制上报数据块信息;系统会每隔3秒发送一次心跳报文;当该Datanode返回响应并执行相应的Namenode指令时;若在10分钟内未能发送任何心跳报文,则表明该Datanode出现故障无法正常工作

(3)当Hadoop集群开始运行时会切换到一个安全模式,在该安全模式下会依赖于心跳机制进行管理操作。仅当NameNode成功收到至少99.9% DataNode的状态反馈时才会解除此安全状态。

3.请简述下HDFS文件的读写流程

HDFS读流程

在获取文件名称之后,在JVM虚拟机环境中运行HDFS客户端软件,在其文件系统功能中远程调用NameNode服务方法以获取关于块的位置信息返回结果。
随后通过FSDataInputStream工具找到各个DataNode节点,并建立相应的连接来接收数据流。
持续不断地将数据发送给客户端;一旦第一个块完成传输,则关闭与该DataNode相关的连接,并立即处理下一个块的数据传输工作。
每个datanode存储的block都有一个crc32位作为校验码,在传输到客户端后重新计算crc值并与原值进行比较;如果两者一致,则证明传输的数据与本地存储的一致。

img

HDFS写流程

在向HDFS发送数据时, 首先需要与namenode进行通信以确认是否可以上传文件, 并获取接收到的块所属的datanode. 随后会依次将每个块发送至对应的节点, 并由接收该块节点负责将该副本发送给其他所有节点.

在数据读取过程中,默认配置了两个专用队列:一个是用于处理完成的数据的主队列(记为DataQueue),另一个用于处理返回确认的数据的ack队列。每次读取单个字符会被逐个字节传输至临时缓冲区,并将其存储于独立的小块中(每个小块带有4-byte校验码)。所有生成的小包最终都会被整合进主数据队列中。

在data queue中存放的每一个包件会依次分批地发送到各自对应的datanode及其副本上,并会在ack queue队列中备份一份新的校验值信息。当一个包件完成写入操作后系统会立即生成新的校验码并将其与ack queue中该包件的校验码进行逐一核对对比;如果对比结果为成功则系统将直接删除相应的包件;但如果对比结果不一致则系统会将该包件重新送回data queue供其再次进行数据重传操作

HDFS写流程

img
4.HDFS存储大量的小文件会发生什么问题?

其中Namenode负责存储文件系统的元数据 ,这些元数据用于记录文件、块和目录,并占用大约150字节的空间。当系统出现较多的小文件时,在hdfs中存在过多的小文件会导致在元数据中消耗内存空间来记录它们的存在。这可能导致Namenode的工作负载增加,并可能降低系统性能。

​ 通常可以通过两种方法处理:

启动mr程序流程:运行mr程序并配置参数后,在Hadoop的archive命令下执行操作序列(例如:hdfs dfs - put $file .jar),以完成单个小文件的压缩至一个HAR格式化 archives存储方案)。该方法特别适合用于单个小块数据的集中存储管理与长期数据备份需求场景下的解决方案

Sequence Files 方案:还不太会用,暂不说明。

5.block块为什么设置比较大?是不是越大越好?

block的大小取决于磁盘传输速度。例如,在磁盘传输速度为200MB/S的情况下,则通常将block大小设置为256MB。

当block过大时, 从磁盘读取数据的时间会明显延长, 同样地, map函数通常每次处理单个block, 因此当block规模过大时, mr的整体运行效率也会受到影响。

当block设置过小时(即其大小小于某个合理阈值),系统会面临与hdfs处理海量小型文件时遇到的相似问题——这会导致 namenode 负担过重而产生内存压力

MapReduce分布式计算

1.MapReduce的shuffle过程是怎么样的?

MapReduce的shuffle流程实际上属于其运行过程中两个关键阶段的一部分,并具体来说即为在这些阶段中执行的关键操作即为:将数据按照键进行分组并重新排列这一操作被称为 Map Shuffle,在完成此操作后随后进行 Reduce Shuffle 这一操作以进一步整理数据准备进入最终的 Reduce 阶段

  • 该过程将map的结果按分区排序后将结果按分区合并后写入磁盘最终生成一个按分区排列好的文件。
  • map task产生的kv对数据先存放在一个循环缓冲区其容量限制在100MB当缓冲区已填至80%时就会开始溢出至磁盘。
  • 在将数据转移至磁盘的过程中系统会对kv对执行哈希分划并排序mr程序默认采用哈希分划方法即通过计算kv对键值的哈希值来确定分划然后根据分划后的余数值决定具体分配给各个reduce任务。
  • 接下来系统会评估是否有相同键的数据需要执行压缩操作。
  • 最终处理完成后将结果传递给reduce任务使用。

在Reduce Shuffle过程中中,在初始阶段从reduce端通过网络传输到磁盘获取map输出数据阶段开始执行操作;在此期间,在reduce shuffle阶段中,则会将键相同的键值对数据进行合并;随后进行排序合并处理;整个过程持续到调用reduce方法之前结束

2.Combiner的作用

Combiner 是一种用于解决 map 和 reduce 任务之间数据传输压力的技术实现。该系统通过定义一个聚合函数来实现相同键值对的缩减。具体而言,该系统允许用户根据 map 任务输出的结果自定义一个合并函数,该函数能够将具有相同 key 值的所有键值对缩减成较少数量的数据,从而有效降低传输至 reduce 任务的数据量,并减少网络带宽消耗以及 reduce 任务的工作负载。

实际上组合器充当可选项,在 shuffle 过程中无论是否设置了该参数以及设置的次数如何都不会影响最终结果。

3.如何诊断是否有数据倾斜存在并处理?

数据倾斜有以下两种常见原因:其一,在某个特定字段(即key)所关联的数据量显著高于其他字段的数据量;其二,则存在某些极端或异常的数据记录其规模明显高于平均水平。

可对MR程序的reduce方法中的每个键的最大值进行监控,并预先设定一个阈值。当当前记录的该键数值超过该阈值时即可判断数据出现失衡现象,并将相关信息记录至日志文件中进行分析。

第二种是对编写MR程序时,在业务层面考虑自定义的分区键 是否合理。类似于,在 ADS 库建表时,默认指定某个字段作为分区键。

在MR程序中采用TotalOrderPartitioner取代HashPartitioner,在该方案中通过从原始数据中随机抽取一定比例的数据样本来确定分区边界。从而能够识别出会导致数据分布失衡的关键键值,并将其分散处理。

MR程序中使用Combiner。

4.简述一下MapReduce的过程

MapReduce是一种基于divide and conquer策略构建而成的分布式计算系统,在算法设计上体现了经典的分治思想。该系统由两大核心环节组成:map环节和reduce环节。

​ 在map阶段 中:

  • 首先从HDFS中读取文件, 每个文件都被划分为一个个block, 每个block内的数据会被解析为多个key-value (kv) 对, 然后调用map taskmap方法 ;
    • 通过分片处理接收到的每一个key-value (kv) 对, 并生成新的key-value (kv) 对;
    • 随后会对这些key-value (kv) 对执行分区、排序并压缩处理, 其中涉及到了Map阶段的数据shuffle过程;
    • 最后将处理后的结果存储到本地磁盘上, 供后续Reduce任务使用

​ 在reduce阶段中:

该系统负责处理多个map任务的输出,并按照不同的分区将数据传输到相应的reduce节点上进行合并排序(其中shuffle过程类似于洗扑克牌的方式重新排列数据)。
随后该系统会汇总所有输入键值对的数据,并计算出最终结果。
最后会将该系统的reduce阶段计算所得的结果存储到HDFS文件中。

Yarn资源调度框架

1.介绍下Yarn的框架?(重要)

Yarn的架构遵循经典的主-从模式,并与HDFS具有类似的架构设计。基本上来说,yarn由一个ResourceManager 和多个NodeManager 构成。其中RM作为主要节点负责资源管理功能,NM作为辅助节点提供服务支持。

ResourceManager 是一个全局性的资源管理系统,在系统中扮演核心管理角色。它全面负责系统级的资源调度与分配任务,并承担着整个系统资源调度与分配的主要职责。该系统不仅能够处理客户端请求,并且负责启动及监控ApplicationMaster 的运行过程;同时还会监管NodeManager的工作流程;最后并进行资源的分配与调度安排。

在ResourceManager中主要包含两个关键组件:Schedule调度器 和 **ApplicationManager应用程序管理器

  • 该调度器 会根据系统中的资源限制条件(如内存、CPU负载等),将程序的资源需求与可用资源进行匹配。(主要有三种类型:先进先出(FIFO)调度算法、基于容量限制的调度算法以及平均分配型调度算法)
  • 该应用管理系统 则主要负责管理整个系统的应用运行状态。它会接收提交的应用任务请求,并从资源池中获取容器来运行 ApplicationMaster 并进行任务处理工作,并统一协调整个系统的运行状态。
  • 与之相对的是 ApplicationMaster 负责协调节点上的任务执行。
  • 它是一个由 ResourceManager 管理的应用服务协调层组件。

ApplicationMaster 负责处理 yarn 内部运行的应用程序各个实例,并整合来自 ResourceManager 的资源;同时通过 NodeManager 来监控容器的行为以及资源使用状况。

在集群中存在多个NodeManager实例,在每个节点上都承担着资源使用的管理职责。这些实例不仅会接收并处理ApplicationManager发出的相关请求,在接收来自Resource Manager的相关指令时也会主动进行响应。此外,在完成必要的资源分配后还会将有关容器使用的状态反馈给Resource Manager以供参考。

这里的Container 实际上是一个资源抽象概念,在系统资源分配中所涉及的具体资源类型包括内存、磁盘存储空间以及输入输出功能等。

具体过程如下:

当客户端应用程序向Resource Manager发起资源请求时, Resource Manager接收该请求后, 提供相应的Container给Node Manager, I通知Node Manager启动Application Master instance.

当 Application Master 启动后向 ResourceManager 注册时

当程序运行时,在线客户与ApplicationMaster持续保持交互关系,并可实时追踪系统的运行状态。在NodeManager的职责下会定期向ResourceManager提交关于自身状态及Container资源使用情况的信息;完成任务后,在NodeManager的协调下(ApplicationMaster负责关闭系统并归还所有容器到资源池中),确保系统资源得到合理分配。

概括来说其过程如下

用户向系统提交请求以获取资源,并随后启动ApplicationMaster程序以开始运行任务所需的资源分配。系统会将容器分配给当前执行的任务,并在完成该任务后回收容器以释放资源。

除此之外,
除了现有的服务之外,
还有JobHistoryServer(作业历史服务,
用于记录并跟踪Yarn中调度执行的任务历史信息)
以及TimelineServer(用于记录应用程序运行过程中的关键事件信息),
这些服务器也需要手动启用以确保正常运行。

2.Yarn的动态性是指什么?

是指多个应用程序的ApplicationMaster 实时地 与ResourceManager 进行通信 , 持续不断地 获取并 释放 资源 ,然后再获取并 释放 资源 的过程 。

3.Yarn的调度器有哪三种?他们的区别是什么?(重要)

在yarn中提供了三种调度器选项:采用先进先出机制基于队列实现的FIFO Scheduler ,基于资源容量分配的Capacity Scheduler ,以及采用公平分配机制的Fair Scheduler

  • 三类调度器间的差异主要体现在其作业调度机制上
  • 在Hadoop 1.x版本中,默认采用FIFO调度器。该调度器基于队列模型处理每一个任务作业,在时间序列上依次执行作业操作
  • 当作业到达时会立即被加入到相应的队列中,在容量限制下按照预先设定的优先级执行
  • Fair Scheduler会动态地重新分配系统资源给所有job任务,并采用平均分配策略以确保每个任务都能公平地分享集群资源

Zookeeper分布式协调框架

1.请简单介绍下Zookeeper?(重要)

ZooKeeper是一个由分布式开发的开源代码组成的、专门负责为分布式应用程序提供协调服务的工具。

Zookeeper具有对外维护秩序和安全的特点,并非仅仅指它整体内部环境和谐统一、内部管理有序、协调一致;它还意味着对外服务态度一致、对外形象良好。

拆开来看是指Zookeeper服务端有两种运行模式:一种是单机环境下的独立运行模式;另一种是基于集群环境下的仲裁决策模式。所谓的仲裁是指只要多数派节点同意就可以按照该事件进行处理,并无需等待集群中所有节点都确认完毕后才能采取行动。而Zookeeper作为一种遵循主从架构的应用,在仲裁决策模式下通常会指定一个主要负责处理事务的核心节点担任领导角色(Leader),其余从属节点则作为参与者(Follower)。当处理某一事件时,领导角色都会首先征询各个从属节点的意见后再作出决策;如果获得多数参与方的认可,则领导角色将命令下发给所有从属节点去完成相应的事务处理工作。

安其内属于Zookeeper中的领导机制,在集群启动阶段以及运行过程中都会进行 leader选举。当一个 leader失效后,概述选举过程具体说明如何通过少数服从多数的原则选出新的 leader。

在Zookeeper系统中所涉及的数据结构构成核心知识领域,由于其提供的服务主要由以下几个方面构成:

该系统由三部分构成:数据节点(作为简化的文件系统)+ 基础命令集(类似于Zookeeper的核心功能)+ 用于触发变化通知(类似于监听器的作用)。

Znode可划分为持久性组件非持久性组件 ,其中当使用Zookeeper的命令create执行文件操作时,默认会选择后者作为操作对象;这些临时组件会在对话框关闭后被删除掉。此外还可以选择将其设为有序模式,在这种模式下,默认会附加一个自增数字作为标识符来区分不同的组件。

该系统采用了一种类似于监听器机制的通知系统流程:首先需完成注册步骤;接着持续监控指定事件;最后触发相应的响应动作。具体而言,在该系统架构中:客户端通过在znode节点上创建一个Watchman实例来进行监控配置;每当znode节点上的数据发生变化时;watchman组件会自动检测到数据变化并执行相应的处理流程以向客户端发送通知信息。值得注意的是;这一设计模式不仅适用于本地部署;也同样被应用到了分布式文件存储框架中的高可用性扩展方案中。

2.Zookeeper的工作原理?
3.Zookeeper读写流程:
  • 由Client向Follwer发起一个读写请求
  • 由Follwr将请求发送至Leader, Leader接收到该请求后启动投票机制,并指示所有参与方完成投票程序
  • 由Followr传递其收集到的投票信息至Leader
  • 当Leader汇总所有票数后发现有必要进行数据读取或更新时,则指示所有参与方执行相应的操作,并提交到数据库
  • 由 Follower 处理完毕后返回处理结果至 Client
4.加入Zookeeper中某个Follower出故障了怎么办?(重要)

​ 这会启动Zookeeper的状态同步 过程。具体来说如下:

在完成leader选举后, 每个Follower与对应的leader之间建立通信连接, 在每次事务执行期间, 每个Follower都会将自己的最大事务ID 发送给相应的leader. 当某个Follower出现故障时, leader会根据该Follower之前发送的原有的 zxid 值来确定同步基准点, 并将其与该节点后续的所有 zxid 信息进行同步更新.

一旦达到同步状态时,系统会告知Follower已处于更新阶段。Follower接收到update消息后,则能够及时响应客户端发出的新请求并持续运行。

Hive

1.概括性地介绍一下Hive及其用法?(重要)

Hive主要用于处理海量结构化的日志数据进行统计分析。它是一种基于Hadoop的数据仓库解决方案,在实际应用中能够将结构化的数据文件映射为一张数据库表,并提供与SQL类似的查询功能。其本质在于将其转化为MapReduce程序逻辑。

Hive与其它数据库的区别:

Hive数据库的数据存储于HDFS文件系统中,在实际应用中需要将其转码为MapReduce(mr)程序来进行执行。由于这种模式下任务运行涉及复杂的资源分配与任务调度机制,在实际使用中可能会导致查询效率较低的问题;此外需要注意的是,在HDFS的操作中支持覆盖式追加操作(即所谓"append"操作),但并不支持传统的更新操作(update)以及事务管理;同时该系统具备良好的扩展性特点,在多节点环境下运行良好;另一个重要特性是其读取性能较为突出,在读取数据前无需验证,在读取时才会进行数据校验;最后需要注意的是该系统适用于处理大规模数据查询场景

Hive的优缺点:

  • 优点:该系统采用类似于SQL的语法结构设计操作界面;为用户提供无需编写MapReduce程序即可完成计算任务的能力;允许用户提供自定义的函数模块以满足个性化需求。
  • 缺点:该系统目前不具备对更新操作的支持以及完整的事务管理功能;在查询响应时间上表现出明显延迟现象。

Hive的架构原理

复制代码
* Hive首先是一个客户端工具,它提供了一些用户可操作的**接口** ,可以通过交互shell,JDBC和web UI方式连接Hive,在Hive的内部有个**Driver驱动器** ,驱动器里面实现了**解析器,编译器,优化器和执行器** 的功能,在用Hsql查询表时,sql语句在驱动器中会先做语法和语义解析,解析之后再进行相应的语法编译,然后在通过优化器时产生逻辑计划和物理计划,并进行优化,最后在执行器中转换成对应的mr jar包,打包给hadoop集群运行获得结果.
* 其中,在用SQL查询语句之前,Hive会将存放在hdfs的数据和对应的表建立映射关系,而记录这些映射信息和表结构信息的**元数据** ,会存放在Hive指定的数据库中,比如mysql或者它自身warehourse目录下。
* 大体流程如下:


​ 用户接口(shell、JDBC、Web UI) --> Driver(解析、编译、优化、执行)–> MR程序 --> hadoop集群

Hive的交互方式有三种:Hive交互Shell,Hive JDBC服务和Hive的命令 *

Hive交互Shell:直接输入在hive中/bin目录下的hive命令,进行sql查询

JDBC服务:

启动hiveServer2服务:bin/hive --service hiveserver2

然后 beeline命令连接hiveserver2:

复制代码
        bin/beeline

        beeline> !connect jdbc:hive2://node1:10000
        
            
                    
                    
    ```
* 

Hive命令:在hive命令后面加 -e 选项后,接sql查询语句即可。
复制代码
bin/hive -e "show databases;"
复制代码
* 

Hive的数据类型和mysql的类似,常用的int、bigint、double、string、date、boolean,还有smallint、tinyint、float、varchar、timestamp,另外还有三种复合数据类型:array(数组),map(键值对),struct(一组命名的字段),复合类型在建表时需要特别指定。

Hive的建表操作

    * Hive的表可以分为**外部表** 和**内部表** ,外部表创建时需要执行**EXTERNAL** 关键字,它仅记录数据所在的存储路径,删除数据时外部表只是删除表的元数据,在重新建表后能直接关联上原来的数据,通常用作**底层表** ;而内部表不需要指定EXTERNAL关键字,在删除数据后会把表的元数据和真实数据一起删除,通常用作**中间表** 。
    * 建表时建议指定分区,**partitioned by** ,分区是把表的数据分目录存储在不同文件夹中,后期查询时可以避免全量扫描提升查询效率,可以指定一级分区,二级分区等;分区有动态和静态之分,在插入数据时可以给定具体的分区值做静态分区的方式插入,也可以只写明分区键做动态分区的方式插入,动态分区的方式会根据插入数据的值自动划分分区,但可能产生较多的小文件,浪费系统内存和IO。
    * 还可以指定分桶,**Clustered by** ,分桶类似于将**文件切分** ,它是将整个数据内容按照分桶键的值做hash算法,得出的结果再和分桶数做模运算来进行切分,指定了分桶表之后,后续select查询条件要加**tablesample(bucket x out of y)** ,适用于需要**抽样调查** 的情况。
    * 最后建表时可以指定每一行中字段的分隔符,用”**row format delimited fields terminated by** “指定;可以指定文件存储类型,stored as 二进制文件,文本文件、或列式存储文件。以及指定表在hdfs上的存储位置location。

Hive数据的导入和导出

Hive数据导入:

**第一种** ,用**load data** 导入数据:

导入数据[local]从路径'dataPath'覆盖到表student并按指定的分区值;

复制代码
```

第二种方法

hdfs fs -put /opt/bigdata/student.txt /user/hive/warehouse/student1

第三种操作可以在建表过程中使用SELECT * FROM 某张表来实现,在覆盖表中插入数据时同样适用。

最后一个方案是无需额外步骤地导入表格文件进行操作;但需确保该数据文件已预先准备好以供后续使用。

Hive数据导出

此方法采用插入操作进行文件输出

复制代码
        #加local导出到本地路径,默认文件分隔符时“\001”,之后本地会生成一个日志型的文件。

        insert override local directory '/opt/bigdata/student';
        #格式化导出文件
        insert override local directory '/opt/bigdata/student' row format delimited fields terminated by ',';
        #这里没有local
        insert override directory '/export/student' row format delimited fields terminated by ',';
        
            
                    
                    
                    
                    
                    
                    
    ```
* 

**第二种是Hadoop命令** 直接下载,由于表和数据有映射关系,每张表在hdfs上都能找到对应数据存储位置,所以我们可以直接下载下来的,后期要检查下数据和分隔符是否有问题。
复制代码
    hdfs fs -get /usr/hive/warehouse/student/student.txt /opt/bigdata/data

```

第三种方式使用Hive shell进行命令导出

复制代码
        #1.hive -e  “sql语句”  >> file; 这种是直接执行sql语句,把结果导出到文件中。

        #2.hive  -f  "sql文件"  > file; 这种是执行完sql文件后,将查询结果写入到file中
        
        bin/hive -e 'select * from default.student;' >> /opt/bigdata/student.txt
        
            
                    
                    
                    
                    
    ```
* 

**最后一种是export导出** 到hdfs
复制代码
    hive>export table student to '/usr/hive/warehouse/student';

```

Hive的文件存储格式和压缩机制:此处不做详细说明,因为缺乏深入理解。已知Hive的压缩操作主要分为两个阶段:一是Map Shuffle阶段的数据写入到磁盘时执行;二是Reduce阶段输出结果时进行。常用方法是将数据以ORC格式存储并结合Snappy进行压缩以提高效率。

Hive中的SerDe功能实现了序列化与反序列化的核心逻辑设计。该技术基于Serde库完成对行对象的数据编码与解码操作,在实际应用中使得数据能够轻松地被导入到数据库表中,并最终完成文件内容与Hive表格之间的映射关系建立。

HDFS file -> InputFileFormat -> key,value -> Deserializer (反序列化) -> Row object

Row object -> Serializer (序列化) -> key,value -> OutputFileFormat -> HDFS file

在建表过程中可以通过设置row格式参数来使用SerDe方法;这种方法常用于企业中处理多字符分隔问题的情景。

核心一点是Hive的优化 ,参考下面另一个问题的答案:**8. 数据倾斜现象和解决办法?(重要)

2. 将数据直接传到HDFS分区目录上,怎么让分区表和数据产生关联?

由于将文件上传至HDFS后,hive系统缺乏相应的元数据信息,因而无法检索到对应的原始数据。建议在上传文件至数据库之后,为每个目录创建相应的分区表

复制代码
    dfs -mkdir -p 分区目录
    dfs -put 分区数据
    hive>alter table 表明 add partition(分区);
3. 桶表是否可以直接通过load将数据导入?

无法进行, 因为在hdfs中加载数据时只会存在一个文件无法完成分桶操作的结果, 必须借助中间表来进行数据导入操作

4. hive的分区可以提高效率,那么分区是否越多越好?为什么?

不是越多越好

  • Hive 的基础层确实建立在 HDFS 上,并且 HDFS 主要用于存储大数据而非小规模数据。随着分区数量的增多,在这种情况下会导致 namenode 的负担加重。
  • Hive 会被转换为 MapReduce 程序, MapReduce 作业会被拆分成多个 task 任务, 其中每个 small file 被分配一个单独的任务. 每个 task 需要启动一个独立的 JVM 实例, 这些 JVM 实例启动和停止的过程会对系统的性能产生一定的影响.

所以分区数要合理设计,一般在3个以内。

5. 什么情况下Hive可以避免进行mapreduce?
  • 当执行无需进行COUNT或SUM等聚合操作的简单SELECT语句时,默认情况下不会经过MapReduce流程,并可以直接从HDFS目录中获取相关数据。(fetch抓取)
    • 此外,在过滤条件仅涉及分区字段时,默认情况下同样不会经过MapReduce流程,并且可以通过FETCH机制完成数据获取。
复制代码
    select * from order_partition where month = '2019-03';

另外一种方法是可以允许用户自行配置Hive使其采用本地模式运行。但需要注意的是,在这种情况下必须满足以下条件:查询的数据总量不得超过256MB或数据件数不得超过4件;如果不满足上述条件,则系统会默认采用MapReduce模式处理。

复制代码
    set hive.exec.mode.local.auto = true;
6. order by ,sort by , distribute by , cluster by 的区别?

Order by 会对所给的全部数据进行全局排序 ,只启动一个reduce来处理。

Sort by 作为局部排序 使用,在排序过程中根据数据规模大小自动启动一个或多个reducer。这些reducer会分别对每个reduce执行内部排序。

对应于mr中的partition
利用hash算法,在map阶段将查询结果的相同hash值分配至相应的reduce节点上
配合排序操作一起执行

Cluster By 本质上相当于将数据先按分布分组再排序。当两种操作作用于相同的字段时其效果与仅使用 cluster 时一致但 Cluster By 的一个显著特点是其结果始终采用降序排列而无法指定升序或降序的操作

7. 如何将数据以动态分区的方式插入分区表中?

1.首先创建对应分区表和一张普通表

2.然后将数据加载到普通表

复制代码
    load data local inpath '/opt/bigdata/order_partition' into table tt_order;
  • 3.最后利用普通表来将数据加载到动态分区表中
复制代码
    #先设置使用动态分区的参数和使用非严格模式
    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict; 
    
    #然后通过普通表导入分区表
    insert into table order_partition partition(year,month) select order_number,order_price,substring(order_time,0,4) as year,substring(order_time,6,12) as month from tt_order;
    #注意导入的字段顺序,分区键一定要放在最后,否则会报错。
8. 数据倾斜现象和解决办法?(重要)

1.什么是数据倾斜?

在同一个reduce操作中出现大量具有相同特征的键值对时, 或者某个键对应的数值远远多于其他键对应的数值, 这种数据分布不均匀的现象即被称为数据倾斜

2.数据倾斜的现象

当执行某个具体的任务时

在现实工作中常见到的情况较多:例如,在这种情况下常用的方法是使用大表与小表进行连接(join),其中小表特定的键值较为集中。这会导致在特定的一个reducer节点上接收的数据量显著高于平均数值;另一种常见的情况是两个大型表格之间的连接操作(join)中,在判断条件字段为空或为零的情况下出现较多的数据项。这些项目都会被分配到同一个reducer节点上进行处理工作;此外,在执行group by操作后对某个字段进行去重计数(count distinct)的操作时,在某些关键字段具有大量数据的情况下也会导致reducer节点的工作负担过重

3.数据倾斜的原因

  • key值分布不均衡, 如空值、零值等
  • 业务数据的固有属性
  • 在建表过程中考虑不够全面, 可能导致后续的 join 操作出现数据偏倚问题
  • 某些 SQL 查询语句本身就存在偏倚性问题, 例如使用 COUNT(DISTINCT) 通常会单独使用 reduce 操作来统计唯一值数量, 当处理的数据量非常大时, 这种情况会导致整个任务难以高效完成
  • 这种情况下建议先根据需要统计的字段进行 group by 分组处理后再进行 sum 或者 count 操作

4.数据倾斜的解决方案,有三个层面可以思考处理:

第一,SQL语句调优 *

查询语句将包含具体所需的列和分区键。某些复杂表中的字段会设有json格式的文本。这些字段不一定都需要用于过滤即可减少reduce阶段的工作量。

较大的数据集连接较小的数据源时,请先将较小的数据集首先加载到内存中,并在映射(map)阶段进行数据整合以减少后续归并阶段的工作量。

在两个大的表格之间进行 join 操作时,在第一张大表中将包含空值的 key 转换为字符串,并在此基础上附加 rand() 生成随机数;随后,在 MR 过程中的数据分区会将倾斜度较高的数据重新分配至不同的 reduce 节点上以减少数据倾斜问题。另一种方法是在 join 操作的 on 条件中暂时排除所有 key 为空的记录,在完成这些非空 key 数据之间的相互连接并汇总后才进行 union_all 操作以恢复包含 key 为空的数据集

复制代码
        select * from a left outer join b

        on case where id is null then concat('任意字符串',rand()) else id end = b.id;
        
        select * from log a join users b on a.id is not null and a.id = b.id
        union all
        selct * from log a where a.id is null;
        
            
                    
                    
                    
                    
                    
                    
    ```
* 

查询语句中count(distinct) **改成group by + sum()** ,比如

select count(distinct id) from test; ==> select sum(id) from (select id from test group by id); 这种可能会多开一个reduce来完成group by的操作,但会明显提高查询速度。

针对不同数据类型产生的数据倾斜,存在这样的情况,A表中的id字段的数据类型是int,但join的B表中id字段存在脏数据,有一些是int类型但也有string类型的,那么再join操作时,默认的hash操作就会对int类型的key进行分配,而对于string类型的key会被统一分配到一个reduce中,这种情况就需要先进行**类型转换** ,如 a join b on a.id = **cast**(b.id as int);

还有一些时候可以把数据倾斜的数据单独拿出来处理,然后再**union all** 回去。

**第二,通过设置hive参数配置解决** ,这种主要是优化计算速度,避免数据倾斜发生

开启**map端聚合**

并不是所有的聚合操作都需要在reducec端完成,很多聚合操作都可以现在map端先进行**部分聚合** ,最后在reduce端得出最终结果(类似于mr过程中的combiner,预先合并压缩数据,再提供给reduce统计计算)

再hive开启map端聚合后,一旦发现数据倾斜,系统就能自动负载均衡,把相同特征的key分发到不同的reduce中,主要通过hive.groupby.skewindata参数完成。
复制代码
    #开启map端聚合的设置

映射阶段是否执行聚合操作,默认启用
设置hive.map.aggr为true
指定在map阶段执行聚合操作时所需的数据条目数量
配置hive.groupby.mapaggr.checkinterval参数为10万
当数据存在倾斜时会自动实施负载均衡策略,并将具有相同特征的关键字分配至不同的reducer中(默认关闭)

复制代码
```

设置并行执行

和ORACLE类似的方式下都可以通过并行执行来提升查询效率;而在于HIVE则依赖于通过参数控制空值

复制代码
        #开启并行执行

        set hive.exec.parallel = true;
        #设置同一个sql允许的最大并行度,默认是8
        set hive.exec.parallel.thread.number = 16;
        
            
                    
                    
                    
                    
    ```
* 

设置**压缩**

压缩可以在map端要进行shuffle时压缩和在完成reduce输出时压缩

    * Hive表中间数据压缩
复制代码
    #设置为true为激活中间数据压缩功能,默认是false,没有开启

指定中间数据压缩的操作采用布尔值true;注:通过将MapReduce任务的输出压缩编码器配置为SnappyCodec实现;

复制代码
```
  • Hive表最终输出结果压缩
复制代码
        set hive.exec.compress.output = true;

        set mapred map.output.compression = codec = org.apache.hadoop.io.compress.SnappyCodec;
        
            
                    
                    
    ```
* 

**推测执行**

说简单点就是Hadoop用了一个备份任务来同时执行,跟原来的任务相比较,谁先执行完成就用谁的计算结果作为最终的计算结果。具体定义如下:

​ Hadoop采用了推测执行机制,它根据一定的法则推测出”拖后腿“的任务,并为这样的任务启动一个**备份任务** ,让备份任务和原始任务同时处理一份数据,并最后选择优先执行完成的任务计算结果作为最终结果。
复制代码
    #开启推测执行机制

    set hive.mapred.reduce.tasks.speculative.exection = true;

```

JVM重用

JVM实例可以在同一作业中被共享多次以减少启动及销毁的时间

复制代码
        #设置jvm重用个数

        set mapred.job.reuse.jvm.num.tasks = 5;
        
            
                    
                    
    ```
* 

合理设置**map数** 和**reduce数** * 在map执行之前将**小文件合并** 可以减少map数
复制代码
    #系统默认的格式,可以不用设置。

将 hive.input.format 赋值给 org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

复制代码
```
  • 复杂文件 可以增加map数
复制代码
        增加map方法有一个公式:

        compute(SliteSize(Math.max(minSize,Math.min(maxSize,blocksizs))))公式
        - 调整maxSize最大值,让maxSize小于blocksize就可以增加map数
        - minSize默认等于1,maxSize默认等于blockSize大小。
        
        #比如这样设置就可以达到增加map数的效果
        #设置每个map处理的文件maxSize大小为10M,这样小于一个block128M的话,系统就会分配更多10M的map来处理复杂任务。
        set mapreduce.input.fileinputformat.split.maxsize = 10485760;
        
            
                    
                    
                    
                    
                    
                    
                    
                    
    ```
* 合理设置Reduce数,比如设置每个job中reduce的个数为3个
复制代码
    set mapreduce.job.reduces = 3;

```

第三,修改MR程序 去避免数据倾斜

在MR程序的reduce阶段可对每个键的最大数值进行记录,并设定一个数值基准。一旦达到或超越该数值基准,则判断为数据分布失衡,并将相关信息记录至日志文件以便后续分析。

第二种是在构建MR程序的过程中,在业务逻辑的角度分析自定义的分区键 的合理性如何?类似于在ADS库建表时通常情况下会默认设置哪个字段作为分区键。

在MR程序中采用TotalOrderPartitioner替代HashPartitioner,在此基础上基于对原始数据的抽样结果来设定分区边界,并能够识别出可能导致数据分布不均的关键键值。

MR程序中使用Combiner

数据仓库

1.介绍一下对数据仓库的理解?

​ 数据仓库是面向业务主题,为分析数据而设计的。

类似于现实生活中的普通仓库, 数据仓库能够实现物资的集中管理和分类存放, 并便于随时调取所需物资. 其主要目的是为了更加便捷地获取所需数据信息, 并为业务决策提供可靠的数据支撑.

多种来源的数据在进行元数据处理时类似于给物品贴上标签。ETL提取过程与层次化建模过程如同将物品分类放置在货架上,在这个过程中有一些样本适合进行抽样分析作为数据挖掘与机器学习的基础材料。高频使用的样本则专门用于实时查询操作。不常用的历史样本则被按主题筛选后另作详细分析以备查询需求。像阿里云这样的平台工具就像是存储了大量商品的货架一样。

​ 总结来说,它的特点有:

首先关注主题:指数仓中的数据依据特定的业务领域进行分类整理,并且能够帮助用户进行决策支持与深入分析。

第二点, 整合能力: 数仓中的数据来自多个来源系统, 并支持多种数据抽取, 转换与加载(ETL)工具进行无缝整合至数仓

在第三部分稳定性问题主要体现在以下几个方面:在数据仓库中进行决策分析是一项重要功能,在大数据环境下能够支持大量历史数据的查询和检索;通常仅支持一次性插入新数据而不进行实时更新操作;

第四部分:时变性。时变性的核心特征在于其与时间相关联的能力,在此过程中持续生成与主题相关的最新数据。例如,在该系统中会按照年度、月份、日期等的时间序列数据进行更新和分析。

2.什么是维度、事实表、维度表、数据集市、粒度?
  • 粒度:粒度反映了数据仓库按照不同的层次组织数据信息的方式,并根据不同的查询需求存储不同级别的细节与非细节信息。粒度过细则可能导致数据过于繁琐且难以管理;而粒度过粗则可能无法满足特定业务场景下的详细分析需求。
  • 维度:维度是衡量事物多维特性的基础框架,在数据分析过程中帮助我们从不同角度深入理解数据的本质特征与内在联系。
  • 维度表:维度表通常是对现实世界中具体对象或概念的事实性描述信息库,在实际应用中可视为用户的观察窗口或分析视图。它通过整合相关属性信息构建了一个关于现实世界的多维视角模型。
  • 事实表:事实表主要用于存储经过计算得出的综合业务统计指标和关键绩效指标(KPI),这些指标能够全面反映企业的经营状况和发展趋势。
  • 指标:“指标”特指那些能够量化评估某类事物或现象运行状态的具体数值指标。“销售总额”就是一个典型的业务统计指标。
  • 度量值域范围限制问题?
3.数据仓库系统的数据质量如何保证?
4.描述一下OLTP和OLAP的区别
  • OLAP 联机分析处理

    • 构成数据仓库系统的核心功能
    • 该系统的数据规模庞大,在处理大规模数据查询方面表现出色。
    • 尽管对实时响应的要求不高,并且DML(数据 Manipulation Language)操作频率有限。
    • 具备处理复杂业务分析任务的能力。
    • 特别关注于辅助决策者进行科学决策。
    • 同时能够以直观简洁的方式呈现查询结果。
  • 在线事务处理(OLTP)

  • 主要应用于传统关系型数据库的核心功能

  • 数据规模较小

  • 需要支持实时操作和密集的数据更新(DML)操作

  • 具备高并发的事务处理能力,并突出提高数据处理效率的能力

5.数据仓库常用的两种模型及其特点?
  • 基于星型架构的数据模型:基本事实表与多维数据源通过外键字段实现关联关系。需要注意的是,在这种设计中不允许嵌套使用多维数据源。

  • 优势:该模型结构清晰且易于理解,在执行查询操作时能够显著提升性能。

  • 局限性:每个维度字段都可能占用大量存储空间;这可能导致冗余数据积累的问题,在扩展系统时需特别注意;另一个挑战是在实施过程中需要进行大量的数据清洗和预处理工作以确保业务流程的有效运行。

  • 雪花模型:基于星型模型的架构中,在原有维度表的基础上允许向外扩展并形成新的维度表。

  • 优势:该方案的优势在于其数据冗余度较低且具备良好的扩展性。

  • 缺点:当维度表的层次变多时(即随着业务规模扩大后端维护变得更加复杂),其可读性会有所下降;并且在发展至业务后期阶段后端维护变得更加复杂;此外,在关联多个维度表时(即join操作涉及多个表格时)查询效率有所下降。

6.构建数仓应该有哪些过程?
  • (1) 明确业务目标,并深入探究业务需求背景;
    • (2) 研究数据架构特点并实施元数据规范化处理。
    • (3) 规划层次化架构框架,在确保完整性的同时完成以下工作:
      • 确定核心主题模型
      • 设计层次化维度体系
      • 实施粒度划分与维度表设计
    • (4) 建立标准化操作流程(包括但不限于命名规范制定、字段命名规则确立及数据库编码标准制定),确保操作的一致性和可追溯性。
    • (5) 开发并完善ETL工程(包含但不限于开发模块化ETL组件及编写自动化测试用例),同时建立质量控制流程对输出结果进行严格把控。
    • (6) 实施数据库维护方案并推进智能优化策略设计。
7.ETL流程应该有哪些?

优化相关

1.MaxCompute SQL中用到哪些优化?

通过优化SQL过程来实现

  • 建分区表 ,但建议分区层数不超过3层,后续查询时为了避免全表扫描需要分区裁剪,分区值尽量常量化,避免不可确定值;插入数据时尽量采用写入静态分区 的方式,优化数据存储,如果用动态分区,会生成较多的小文件,增加系统负担。
  • 只select有效列,并用limit 限制返回的条数。
  • 读取相同源表时可以合并成一条sql ,系统会优化只读取一次。
  • mapjoin优化
  • 将full outer join 改为left outer join + union all 并对小表使用上mapjoin
  • 尽可能保证表达式两边的数据类型一致,如果发生隐式转换容易造成精度问题,比如string和bigint都转成double来相等比较,悲观情况下,可能触发数据倾斜。这时要cast显式转换 一下
  • 少用distinct ,容易触发数据倾斜,count(distinct)处理的时间会很长可以转换成count()+ group by
  • 多个表join时,join顺序很重要 ,优先选择join结果输出小的表先关联,能有效减少中间数据量,节省IO和计算资源。
  • 尽量使用内置的UDF函数和窗口函数 ,内置UDF在实现做了很多优化,运行块,省资源,窗口函数本身能处理很多复杂问题。
  • 尽量避免Order by,order by会触发全局排序,只能单点运行,效率低,如果业务允许,可以改成distribute by + sort by
2.MaxCompute SQL介绍以及与通用数据库的区别?

MaxCompute SQL在处理海量数据的情形下并不追求实时性

​ 有Bigint,double,String,datetime,Boolean,decimal类型。

​ 可以设置分区表,还可以给表指定生命周期LifeCycle

​ 具体区别如下:

  • 1.MaxCompute表不⽀持主键、索引和字段约束;
  • 2.MaxCompute表不⽀持UPDATE语句和DELECT语句,只能DROP 整个表或者某一分区数据;
  • 3.MaxCompute表创建表时不允许指定默认值,可以指定生命周期,周期结束后自动清除数据;
  • 4.SELECT语句输出的数据⾏数是受限制的,最⼤为10000条;
  • 5.MaxCompute 不支持主键,索引,不支持MINUS操作,MaxCompute的where子句也不支持between条件查询。
  • 6.MaxCompute把sql的关键字做为保留字,对列,表或是分区命名时不能直接使用保留字作命名。
  • 7.插入语句有insert into | overwrite into,overwrite into 写入前会清空表数据;
  • 8.可以直接在select中使用mapjoin,所有小表占用的内存总和不得超过512MB,在官方文档中说mapjoin最多支持6张小表,但工作中我们是规定不能超过8张小表,因为有些表真的容量不大。
  • 9.MaxCompute SQL不支持顶级的两个查询结果合并,要改写为一个子查询的形式,也就是一个union all连接的语句,外面必须套一层select * from。
  • 10.MaxCompute也有内置函数,和大部分数据库的用法差不多,如果忘记可以直接查看官方文档。
    • MaxCompute常用到的函数 :dateadd函数对日期加减法,datediff计算两个日期差值,getdate获取系统日期,cast转换目标数据类型, coalesce函数返回列表中第一个非空的值,case when;decode实现if-then-else分支选择的功能,concat连接所有字符串,instr函数计算子串在字符串中的位置,length函数,MD5函数计算输入字符串的md5值(常用作新加的主键),substr函数,to_char函数,to_date函数,lastday函数返回月的最后一天,lag窗口函数,row_number窗口函数计算行号从1开始,还有常用聚合函数等

其它细微的区别用法详见官方文档。

MaxCompute SQL

1.MaxCompute SQL中用到哪些优化?

为了优化SQL流程, 其核心目标是最大限度地降低I/O操作次数, 最大限度地降低计算资源的消耗, 最大限度地降低SQL语句的复杂程度, 同时提高处理效率.

  • (1)建议建立分区表时不要超过三层分层结构,在查询时可以通过分区裁剪的方式避免全表扫描;在插入数据时应尽量采用静态分区的方式以提高存储效率;如果使用动态分区可能会导致产生较多的小文件并增加多的Mapreduce任务量。

  • (2)在执行SELECT操作时应仅选择必要的列并结合LIMIT参数来限制返回结果的数量;需要考虑以下两种情况:

    1. 如果事实表中的字段数量较多甚至达到几十个以上这种情况实际是存在的例如企业税务申报表这种情况下如果对整个事实表的所有字段执行SELECT *操作不仅会占用大量存储空间还会显著延长查询时间;
    2. 另一种情况是指存在某种复杂格式的数据字段例如JSON格式的数据在这种情况下对整个事实表执行SELECT *操作将会导致耗时严重因此应该优先选择只选取有效列。
  • (3)优化MAPJOIN过程的核心在于先将小规模的数据加载到内存中然后通过与外层大表进行直接计算从而避免在REDUCE阶段进行耗时计算。

  • (4)

    • 尽量少用DISTINCT关键字因为这可能导致数据分布不均;
    • 使用COUNT(DISTINCT)可能会导致较高的计算开销建议将其转换为COUNT() + GROUP BY的方式来减少计算负担;
    • 避免使用ORDER BY指令因为它会导致全局排序只能单线程处理从而降低效率;
    • 如果允许可以选择DISTRIBUTE BY + SORT BY的方式来实现类似功能;
    • 在进行多表连接时应优先选择较小结果集的表格先连接这样能够有效减少中间数据量节省IO操作和计算资源;
    • 当处理相同来源的表格时可以通过合并为一条SQL语句以减少数据库读取次数从而提高系统性能。
    • (5)尽量使用内置的UDF函数和窗口函数,内置UDF在实现时做了很多优化,运行快,省资源,窗口函数本身能处理很多复杂问题。
    • (6)尽可能保证表达式两边的数据类型一致,如果发生隐式转换容易造成精度问题,比如string和bigint都转成double来相等比较,悲观情况下,可能触发数据倾斜。这时要cast显式转换一下
复制代码
    工作中还用到的:
    - 数据量达到千万级别的,尽量固化分区,不在查询sql里面进行动态分区,减少资源使用
    - sql行数较长的,尽量拆分成工作流任务,可以优化性能和排查问题的难易度。
    - 维度表要放到mapjoin里,加大资源利用率
    - 数据倾斜较高的表,先落地成临时表
    - 每日全量推送任务的,如果表级数据量较高的,分析是否可以改成增量模式。
2.MaxCompute SQL介绍以及与通用数据库的区别?

MaxCompute SQL主要用于处理海量数据,在对实时性要求不高的情形下进行作业提交时会经历一段时间的排队调度;其采用的是类似于SQL的传统语法体系但又有所区别例如不支持事务操作主键约束或索引等功能。具体而言MaxCompute SQL的功能集合是标准SQL的一个子集它不具备完整的事务管理能力也没有内置主键约束机制但仍然支持基本的索引操作以满足部分数据访问需求。

​ 有Bigint,double,String,datetime,Boolean,decimal类型。

​ 可以设置分区表,还可以给表指定生命周期LifeCycle。

​ 具体区别如下:

  • 1.MaxCompute表不⽀持主键、索引和字段约束;
  • 2.最明显的区别是,MaxCompute表不⽀持UPDATE语句和DELECT语句(不支持更新操作),只能DROP 整个表或者某一分区数据,然后用INSERT OVERWRITE/INSERT INTO写入数据。
  • 3.MaxCompute表创建表时不允许指定默认值,可以指定生命周期,周期结束后自动清楚数据;
  • 4.SELECT语句输出的数据⾏数是受限制的,最⼤为10000条;
  • 5.MaxCompute 不支持MINUS差集操作,如果需要做差集操作可以用LEFT OUTER JOIN 然后取右表关联为空的数据。MaxCompute的where子句也不支持between条件查询。
  • 6.MaxCompute把sql的关键子做为保留字,对列,表或是分区命名时不能直接使用保留字作命名。
  • 7.插入语句有insert into | overwrite into,overwrite into写入前会清空表数据;
  • 8.可以直接在select中使用mapjoin,所有小表占用的内存总和不得超过512MB,在官方文档中说mapjoin最多支持6张小表,但工作中我们是规定不能超过8张小表,因为有些表真的容量不大。
  • 9.MaxCompute SQL不支持顶级的两个查询结果合并,要改写为一个子查询的形式,也就是一个union all连接的语句,外面必须套一层select * from加别名。
  • 10.MaxCompute也有内置函数,和大部分数据库的用法差不多,如果忘记可以直接查看官方文档或者MaxCompute的IDE也可以直接搜索。
    • MaxCompute常用到的函数:dateadd函数对日期加减法,datediff计算两个日期差值,getdate获取系统日期,cast转换目标数据类型, coalesce函数返回列表中第一个非空的值,case when;decode实现if-then-else分支选择的功能,concat连接所有字符串,instr函数计算子串在字符串中的位置,length函数,MD5函数计算输入字符串的md5值(常用作新加的主键),substr函数,to_char函数,to_date函数,lastday函数返回月的最后一天,lag窗口函数,row_number窗口函数计算行号从1开始,还有常用聚合函数等

其它细微的区别用法详见官方文档。

3.MaxCompute的其他细节:

MaxCompute不支持删除列的。

参与Union All运算的所有列的数据类型和列个数、名称必须完全一致。

数据类型只能是bigint、double、boolean、datetime和string;

在创建表格的过程中明确指定该表格的时间范围;然而,在使用create table like指令创建新表格时,并未复制源表格的时间范围。

使用CREATE TABLE AS SELECT语句生成的表不会复制分区属性,而是将源表中的分区键作为目标表的一般列进行处理;如果希望目标表与源表具有相同的结构,建议采用CREATE TABLE ... AS ... LIKE ...的方式,并手动执行数据插入操作以完成迁移。

当我们配置了带有生命周期功能的数据库表时,默认情况下系统会为其设定生存期并进行自动归档处理。对于非分区内存表而言,在完成最后一次修改操作之后其生存期将从该记录的时间点开始计算当该生存期达到预设时长后将自动归档至MaxCompute系统中若有新的数据更新发生则该生存期的时间段将重新计算以反映最新的变更情况相反若是分区内存表则其生存期仅限于那些存在最近修改记录的分区内存表此时归档仅针对那些长时间未发生任何修改操作的具体分区内存表

删除分区:ALTER TABLE … DROP [IF NOT EXISTS] PARTITION …;

添加列:ALTER TABLE … ADD COLUMNS();

修改列名:ALTER TABLE … CHANGE COLUMN…RENAME TO …

根据指定的分隔条件调整数据库表的分隔设置

修改表的注释:ALTER TABLE…SET COMMENT ‘’;

修改表的生命周期:ALTER TABLE …SET LIFECYCLE = ‘’;

清除非分区表中的数据:TRUNCATE TABLE;如果是分区表的话,则需先执行ALTER TABLE … DROP PARTITION以删除相应的分片数据后方能进行TRUNCATE操作。

修改列、分区的注释:ALTER TABLE … CHANGE COLUMN 列名 COMMENT ‘’;

4.MaxCompute中的类型转换

MaxCompute中支持显示转换cast和隐式转换。

对于显示转换过程中,会发生如下问题:

  • 转换函数将双精度数据类型的数值转化为整型大数值时,其小数部分会被舍去;
  • 当双精度字符串满足特定条件并需将其重新解析回双精度数值后再进一步处理到整型大数值的过程中,中间的双精度数值同样会舍去其小数部分。

String类型和Datetime类型之间的转换

MaxCompute能够实现两个实体之间的双向转换。值得注意的是,在各个单位的值域范围内,如果起始位数为零,则必须保留以避免错误。例如,在函数cast(‘2020-1-1 12:12:!2’ as datatime)中的一月份未写明零会导致报错。

因为double类型在运算中存在精度问题,在直接比较两个double数值是否相等时不可靠。一种更为可靠的方法是通过计算两者之差的绝对值来实现。具体而言,在比较两个double类型的数值是否相等时,可以通过计算两者之差的绝对值来实现。当这个绝对值小于某个预先设定的极小时,则认为这两个数是相等的。

复制代码
    abs(0.9999999999 - 1.0000000000) < 0.000000001

String类型在参与运算前会进行隐式类型转换到double类型

在进行数值运算时,bigint类型的数据会自动转换为double类型后再参与计算,并且运算结果也会被强制转换为double类型

位运算操作无法执行隐式转换操作,并且仅限于使用bigint类型的值进行计算。逻辑运算操作也无法执行隐式转换操作,并且仅限于使用boolean类型的值进行计算。

5.MaxCompute中的mapjoin使用限制
  • 在左外联接操作中, 左端的数据源必须是一个较大的数据集; 在右外联接操作中, 右端的数据源也必须是一个较大的数据集; 内部联接可以在两端都采用较大的数据集; 全外联接操作则无法使用MapJoin方法。
  • 在MapJoin中, 小规模数据可作为子查询; 调用MapJoin时若涉及子查询需指定别名。
  • MapJoin允许采用不等式联结; 或者将多个条件通过OR逻辑组合进行联结。
  • 最多允许定义8个小表格(视版本而定); 所有这些小表格占用内存总量不得超过512MB, 否则程序会抛出语法错误。
  • 当进行多Table联结操作时, 最左侧两个Table不得同时作为MapJoin的操作对象。

- 学习参考

《开课吧-大数据开发高级工程师一期》课程

全部评论 (0)

还没有任何评论哟~