夸父追日——大数据技术原理与应用

1 本学期我们学习使用了哪些大数据框架,请根据各个框架的功能进行分类。

  • 数据采集:kafka、flume、sqoop
  • 数据存储:mysql、hbase、hive、hadoop
  • 数据处理与分析:hadoop、spark、flink
  • 数据可视化:superset、Apache Zeppelin
  • 编程语言:java、scala、python
    大数据框架们

2.什么是文件系统和什么是分布式文件系统?二者有哪些区别?

文件系统是操作系统在硬盘或者分区上保存文件信息的方法和数据结构
分布式文件系统是一种通过网络实现文件在多台主机上进行分布式存储的文件系统。

  • 1.文件管理模式不同
    • 文件系统用于管理机器上的文件和目录,使之能够被有效地存取
    • 分布式文件系统一般采用“客户机/服务器”模式,客户端以特定的通信协议通过网络与服务器建立连接,提出文件访问请求,客户端和服务器可以通过设置访问权限限制请求对方底层存储块的访问。
  • 2.文件存储模式不同
    • 文件以块为单位进行存储,一个大规模文件可以被分拆成若干个文件块, 不同的文件块可以被分发到不同的节点上,支持大规模文件存储。并且大大简化了存储系统。
  • 3.文件系统读取文件流程不同
    • 传统系统根据文件名找到对应的inode号码,通过inode号,获取inode信息。根据inode信息,找到文件数据所在的block,读出数据。
    • 分布式文件系统是根据名称节点、数据节点比较文件对应ID号进行文件读取。

文件系统

概念

文件系统是操作系统在硬盘或者分区上保存文件信息的方法和数据结构。文件系统用于管理机器上的文件和目录,使之能够被有效地存取。

在操作系统中,每个文件和目录都被指定了一个文件名,用户按文件名存取文件,而实际上,文件和目录在磁盘中是按照柱面、磁道等物理位置存放的,文件系统能够将操作系统对文件的按名存取转化成按磁盘的物理位置进行读写

inode索引节点

文件储存在硬盘上,硬盘的最小存储单位叫做扇区(Sector)。每个扇区储存512字节
(相当于0.5KB)。

操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取
多个扇区
,即一次性读取一个块(block)。这种由多个扇区组成的块,是文件存取的最小单位。

块的大小,最常见的是4KB,即连续八个扇区组成一个 block。

文件数据都储存在块中,还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译为索引节点。

文件系统读取文件流程

  1. 系统根据文件名找到对应的inode号码;
  2. 通过inode号,获取inode信息;
  3. 根据inode信息,找到文件数据所在的block,读出数据。
    文件系统读取文件流程

分布式文件系统(Distributed File System)

分布式文件系统(Distributed File System,DFS)是一种通过网络实现文件在多台主机上进行分布式存储的文件系统。分布式文件系统一般采用“客户机/服务器”(client/server)模式,客户端以特定的通信协议通过网络与服务器建立连接,提出文件访问请求,客户端和服务器可以通过设置访问权限限制请求对方底层存储块的访问。

分布式文件系统的设计目标包括通透性,并发控制,可伸缩性,容错以及安全。

  • 通透性。让实际上是通过网络来访问文件的动作,由程序与用户看来,就像是访问本地的磁盘一般。
  • 容错。即使系统中有某些节点脱机,整体来说系统仍然可以持续运作而不会有数据损失。

3 HDFS由哪几个组件构成,各自的作用是什么?

  • 名称节点负责文件和目录的创建、删除和重命名等,同时管理着数据节点和文件块的映射关系。
  • 数据节点是分布式文件系统HDFS的工作节点,负责数据的存储和读取,会根据客户端或者是名称节点的调度来进行数据的存储和检索,并且向名称节点定期发送自己所存储的块的列表
  • 第二名称节点是HDFS架构中的组成部分,它是用来保存名称节点中对HDFS元数据信息的备份,并减少名称节点重启的时间
  • 客户端: 代表用户与NameNode或者DataNode交互,来访问整个文件系统的对象。
    可以支持打开、读取、写入等常见的操作,并且提供了类似Shell的命令行方式来访问HDFS中的数据

分布式文件系统的结构

分布式文件系统在物理结构上是由计算机集群中的多个节点构成的,这些节点分为两类,一
类叫主节点(Master Node)或者也被称为名称结点(NameNode),另一类叫从节点(Slave Node)或者也被称为数据节点(DataNode)
在这里插入图片描述
名称节点负责文件和目录的创建、删除和重命名等,同时管理着数据节点和文件块的映射关系,因此客户端只有访问名称节点请求文件块所在的位置,进而到相应位置读取所需文件块。

数据节点负责数据的存储和读取,在存储时,由名称节点分配存储位置,然后由客户端把数据直接写入相应数据节点;在读取时,客户端从名称节点获取数据节点和文件块的映射关系,然后就可以到相应位置访问文件块,数据节点也要根据民称个节点的命令创建、删除和复制数据块。

HDFS默认一个块64MB,一个文件被分成多个块,以作为存储单位

在传统的文件系统中,为了提高磁盘读写效率,一般以数据块为单位,而不是以字节为单位。

块的大小远远大于普通文件系统,可以最小化寻址开销(包括磁盘寻道开销、数据块的定位开销)

HDFS采用抽象的块概念可以带来以下几个明显的好处:

  • 支持大规模文件存储:文件以块为单位进行存储,一个大规模文件可以被分拆成若干个文件块,不同的文件块可以被分发到不同的节点上,因此,一个文件的大小不会受到单个节点的存储容量的限制,可以远远大于网络中任意节点的存储容量
  • 简化系统设计:首先,大大简化了存储管理,因为文件块大小是固定的,这样就可以很容易计算出一个节点可以存储多少文件块;其次,方便了元数据的管理,元数据不需要和文件块一起存储,可以由其他系统负责管理元数据
  • 适合数据备份:每个文件块都可以冗余存储到多个节点上,大大提高了系统的容错性和可用

名称节点

在HDFS中,名称节点(NameNode)负责文件和目录的创建、删除和重命名等,同时管理着数据节点和文件块的映射关系。名称节点保存了两个核心的数据结构,即fsimage和edits。

  • fsimage用于维护文件系统树以及文件树中所有的文件和目录的元数据
  • 操作日志文件edits中记录了所有针对文件的创建、删除、重命名等操作

名称节点的数据结构

fsimage

每个fsimage文件存储的都是文件系统元数据信息(文件及目录结构,组成文件的块的信息,副本数量信息),如果namenode发生故障,最近的fsimage文件会被载入到内存中,用来重构元数据的最近状态,再从相关点开始向前执行edits日志文件中记录的每个事务。

fsimage文件没有记录文件包含哪些块以及每个块存储在哪个数据节点。而是由名称节点把这些映射信息保留在内存中,当数据节点加入HDFS集群时,数据节点会把自己所包含的块列表告知给名称节点,此后会定期执行这种告知操作,以确保名称节点的块映射是最新的。

名称节点的启动

在名称节点启动的时候,它会将fsimage文件中的内容加载到内存中,之后再执行edits文件中的各项操作,使得内存中的元数据保持最新

一旦在内存中成功建立文件系统元数据的映射,则创建一个新的fsimage文件和一个空的edits文件

名称节点启动成功进入正常状态之后,HDFS中的更新操作会写到edits文件中,因为fsimage文件一般都很大(GB级别的很常见),如果所有的更新操作都往fsimage文件中添加,这样会导致系统运行的十分缓慢,往edits文件里面写就不会这样,因为edits要小很多。

名称节点在启动的过程中出于“安全模式”,只能对外提供读操作,无法提供写操作。启动过程结束后,系统就会退出安全模式,进入正常与逆行状态,对外继续提供读写操作。

SecondaryNameNode

在名称节点运行期间,HDFS的所有更新操作都是直接写到edits中,久而久之, edits文件将会变得很大。

虽然这对名称节点运行时候是没有什么明显影响的,但是,当名称节点重启的时候,名称节点需要先将fsimage里面的所有内容映像到内存中,然后再一条一条地执行edits中的记录,当edits文件非常大的时候,会导致名称节点启动操作非常慢,而在这段时间内HDFS系统处于安全模式,一直无法对外提供写操作,影响用户的使用。

如何解决?答案是:SecondaryNameNode第二名称节点

第二名称节点是HDFS架构中的一个组成部分,它是用来保存名称节点中对HDFS元数据信息的备份,并减少名称节点重启的时间。

SecondaryNameNode一般是单独运行在一台机器上。

它可以完成edits和fsimage的合并操作,减小editlog文件大小,缩短名称节点重启的时间
作为名称节点的检查点,保存名称节点的元数据信息
第二名称节点工作示意图

  1. 使用新的日志
  2. 使用新的日志,从名称节点上获得fsimage和edits
  3. 合并fsimage和edits
  4. 把检查点回传给名称节点
  5. 用fsimage.ckpt替换fsimage,用edits.new替换edits

数据节点(DataNode)

数据节点是分布式文件系统HDFS的工作节点,负责数据的存储和读取,会根据客户端或者是名称节点的调度来进行数据的存储和检索,并且向名称节点定期发送自己所存储的块的列表。

每个数据节点中的数据会被保存在各自节点的本地Linux文件系统

客户端

客户端是用户操作HDFS最常用的方式,HDFS在部署时都提供了客户端

HDFS客户端是一个库,暴露了HDFS文件系统接口,这些接口隐藏了HDFS实现中的大部分复杂性

严格来说,客户端并不算是HDFS的一部分

客户端可以支持打开、读取、写入等常见的操作,并且提供了类似Shell的命令行方式来访问HDFS中的数据

此外,HDFS也提供了Java API,作为应用程序访问文件系统的客户端编程接口

HDFS体系结构的局限性

HDFS只设置唯一一个名称节点,这样做虽然大大简化了系统设计,但也带来了一些明显的局限性,具体如下:
(1)命名空间的限制:名称节点是保存在内存中的,因此,名称节点能够容纳的对象(文件、块)的个数会受到内存空间大小的限制。
(2)性能的瓶颈:整个分布式文件系统的吞吐量,受限于单个名称节点的吞吐量。
(3)隔离问题:由于集群中只有一个名称节点,只有一个命名空间,因此,无法对不同应用程序进行隔离。
(4)集群的可用性:一旦这个唯一的名称节点发生故障,会导致整个集群变得不可用。

4 MapReduce任务执行过程分为哪几个阶段,叙述MapReduce的Shuffle过程。

Mapreduce的各个执行阶段

MapReduce工作流程
不同的map任务之间不会进行通信,不同的reduce任务之间也不会发生任何信息交换

HDFS 以固定大小的block为基本单位存储数据,而对于MapReduce而言,其处理单位是 split

split 是一个逻辑概念,它只包含一些元数据信息,比如数据起始位置、数据长度、 数据所在节点等。它的划分方法完全由用户自己决定。

在这里插入图片描述
(1)MapReduce框架使用InputFormat模块做Map前的预处理,比如验证输入的格式是否符合输入定义;然后,将输入文件切分为逻辑上的多个InputSplit,InputSplit是MapReduce对文件进行处理和运算的输入单位,只是一个逻辑概念,每个InputSplit并没有对文件进行实际切割只是记录了要处理的数据的位置和长度。

(2)因为InputSplit是逻辑切分而非物理切分,所以还需通过RecordReader根据InputSplit中的信息来处理InputSplit中的具体记录,加载数据并转换为适合Map任务读取的键值对,输入给Map任务。

(3)Map任务会根据用户自定义的映射规则,输出一系列的<key,value>作为中间结果。

(4)为了让Reduce可以并行处理Map的结果,需要对Map的输出进行一定的分区(partition)、排序(sort)、合并(combine)、归并(merge)等操作,得到<key,value>形式的中间结果,再交给对应的Reduce进行处理,这个过程称为shuffle。从无序的<key,value>到有序的<key,value-list>,这个过程用Shuffle来称呼是非常形象的。

(5)Reduce以一系列<key,value-list>中间结果为输入,执行用户定义的逻辑,输出结果给OutputFormat模块。

(6)OutpFormat模块会验证输出目录是否已经存在以及输出结果类型是否符合配置文件中的配置类型,如果都满足,就输出Reduce的结果到分布式文件系统。

Shuffle过程

shuffle是指对Map任务输出结果进行分区、排序、合并、归并等处理并交给Reduce的过程。
在这里插入图片描述

Map端的Shuffle过程

在这里插入图片描述

  1. 写入数据和执行Map任务
  2. 写入缓存
  3. 溢写(分区、排序、合并)
  4. 文件归并

合并(Combine)和归并(Merge)的区别:
两个键值对<“a”,1>和<“a”,1>,如果合并,会得到<“a”,2>,如果归并,会得到<“a”,<1,1>>

Reduce端的Shuffle过程

在这里插入图片描述

  • Reduce任务通过RPC(Remote Procedure Call,远程过程调用)询问Map任务是否已经完成,若完成,则领取数据
  • Reduce领取数据先放入缓存,来自不同Map机器,先归并,再合并,写入磁盘
  • 多个溢写文件归并成一个或多个大文件,文件中的键值对是排序的。
    当数据很少时,不需要溢写到磁盘,直接在缓存中归并,然后输出给Reduce

5 在Yarn上执行一个MapReduce任务从提交到完成所经历了哪些步骤。

Apache Hadoop YARN (Yet Another Resource Negotiator,另一种资源协调者) 是一种新的Hadoop 资源管理器,它是一个通用资源管理系统,可为上层应用提供统一的资源管理和调度,它的引入为集群在利用率、资源统一管理和数据共享等方面带来了巨大好处。

Yarn主要由ResourceManager、NodeManager、ApplicationMaster和Container等几个组件构成。

Yarn体系结构

在这里插入图片描述

ResourceManager资源管理器

ResourceManager主要负责整个系统的资源管理和分配,内部主要有两个组件:

  • ResourceScheduler资源调度器:这个组件的唯一功能就是给提交到集群的应用程序分配资源,并且对可用的资源和运行的队列进行限制。Scheduler并不对作业进行监控; 只管理分配不监控
  • ApplicationsManager (AsM) 应用程序管理器:这个组件用于管理整个集群应用程序的application masters,负责接收应用程序的提交;为application master启动提供资源;监控应用序的运行进度以及在应用程序出现故障时重启它。

ApplicationMaster

ApplicationMaster是应用程序级别的,每个ApplicationMaster 管理运行在YARN上的应用程序。 YARN 将ApplicationMaster看做是第三方组件,ApplicationMaster负责和ResourceManager scheduler 协商资源,并且和NodeManager通信来运行相应的task。ResourceManager 为 ApplicationMaster 分配Container,这些Container将会用来运行task。

ApplicationMaster也会追踪应用程序的状态,监控Container的运行进度。
当Container运行完成,ApplicationMaster 将会向ResourceManager注销这个Container;
如果是整个作业运行完成,其也会向ResourceManager注销自己,这样这些资源就可以分配给其他的应用程序使用了。

NodeManager

NodeManager是YARN中每个节点上的代理,它管理Hadoop集群中单个计算节点,根据相关的设置来启动Container。NodeManager会定期向ResourceManager发送心跳信息来更新其健康状态。同时其也会监督Container的生命周期管理,监控每个Container的资源使用(内存、 CPU等)情况,追踪节点健康状况,管理日志和不同应用程序用到的附属服务(auxiliary service)。

总体来说, NodeManager有以下作用

  • (1)管理单个节点上的资源
  • (2)处理来自ResourceManager的命令
  • (3)处理来自ApplicationMaster的命令

Container

Container是与特定节点绑定的,其包含了内存、CPU磁盘等逻辑资源。容器是由ResourceManager scheduler服务动态分配的资源构成。容器授予 ApplicationMaster使用特定主机的特定数量资源的权限。ApplicationMaster也是在容器中运行的,其在应用程序分配的第一个容器中运行。
在这里插入图片描述

步骤

在启动MapReduce之前,确保待处理的文件放在HDFS上面。

MapReduce应用将请求提交给RM,由RM创建对应的Job,一个应用对应一个Job

Job提交前,先将待处理的文件进行分片(Split)。MR框架默认将一个块(Block)作为一个分片。客户端应用可以重定义块与分片的映射关系

Job提交给RM,RM根据NM的负载在NM集群中挑选合适的节点调度AM, AM负责Job任务的初始化并向RM申请资源,由RM调度合适的NM启动Container, Container来执行Task。

Map的输出放入一个环形内存缓冲区,当缓冲区数据溢出时,需将缓冲区中的数据写入到本地磁盘,写入本地磁盘之前通常需要做如下处理:

  • 1.分区(Partition)——默认采用Hash算法进行分区,MR框架根据Reduce Task个数来确定分区个数具备相同Key值的记录最终被送到相同的Reduce Task来处理。
  • 2.排序(Sort)——将Map输出的记录排序,例如将(’Hi’,’1’),(‘Hello’,’1’)重新排序为(‘Hello’,’1’), (’Hi’,’1’)
  • 3.合并(Combine)——这个动作MR框架默认是可选的。例如将(’Hi’,’1’), (’Hi’,’1’),(‘Hello’,’1’), (Hello’,’1’)进行合并操作为(’Hi’,’2’), (‘Hello’,’2’)
  • 4.归并(Merge)——Map Task在处理后会产生很多的溢写文件,这时需将多个溢出文件进行归并处理,生成一个经过分区和排序的溢写文件(MOF:MapOutFile)。为减少写入磁盘的数据量,MR支持对MOF进行压缩后再写入。

通常在Map Task任务完成MOF输出进度到**3%**时启动Reduce,从各 个Map Task获取MOF文件。前面提到Reduce Task个数由客户端决 定,Reduce Task个数决定MOF文件分区数。因此Map Task输出的 MOF文件都能找到相对应的Redcue Task来处理。

前面提到的MOF文件是经过排序处理的。当Reduce Task接收的数据量不大时,则直接存放在内存缓冲区中,随着缓冲区文件的增多, MR后台线程将它们合并成一个更大的有序文件,这个动作是Reduce阶段的Merge操作,过程中会产生许多中间文件,最后一次合并的结果直接输出到用户自定义的Reduce函数。

在这里插入图片描述

步骤 1:用户编写客户端应用程序,向 YARN提交应用程序,提交的内容包括ApplicationMaster 程序、启动 ApplicationMaster 的命令、用户程序等。

步骤 2:YARN 中的 ResourceManager 负责接收和处理来自客户端的请求。接到客户端应用程序请求后,ResourceManager里面的调度器会为应用程序分配一个容器。同时,ResourceManager 的应用程序管理器会与该容器所在的 NodeManager 通信,为该应用程序在该容器中启动一个ApplicationMaster。

步骤 3:ApplicationMaster 被创建后会首先向 ResourceManager 注册,从而使得用户可以通过 ResourceManager 来直接查看应用程序的运行状态。接下来的步骤4~7 是具体的应用程序执行步骤。

步骤 4:ApplicationMaster 采用轮询的方式通过 RPC 协议(Remote Procedure Call )向 ResourceManager 申请资源。

步骤 5:ResourceManager 以“**容器”**的形式向提出申请的 ApplicationMaster 分配资源,一旦 ApplicationMaster 申请到资源后,就会与该容器所在的NodeManager 进行通信,要求它启动任务。

步骤 6:当 ApplicationMaster 要求容器启动任务时,它会为任务设置好运行环境(包括环境变量、JAR 包、二进制程序等),然后将任务启动命令写到一个脚本中,最后通过在容器中运行该脚本来启动任务。

步骤 7:各个任务通过某个RPC 协议向ApplicationMaster 汇报自己的状态和进度,让 ApplicationMaster 可以随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。

步骤 8:应用程序运行完成后,ApplicationMaster 向 ResourceManager 的应用程序管理器注销并关闭自己。若 ApplicationMaster 因故失败,ResourceManager中的应用程序管理器会监测到失败的情形,然后将其重新启动,直到所有的任务执行完毕。

6 实现一个Hadoop自定义类型有哪几个步骤?

hadoop数据类型

hadoop数据类型
除char类型以外,每个Java基本类型的Writable封装,其类的内部都包含一个对应基本类型的成员变量value,get()set()方法就是用来对该变量进行取值/赋值操作的。这些类型都位于org.apache.hadoop.io包中

Writable接口

序列化是Hadoop核心的一部分,在Hadoop中,位于org.apache.hadoop.io包中的Writable接口是Hadoop序列化格式的实现。

Hadoop Writable接口是基于DataInput和DataOutput实现的序列化协议,紧凑(高效使用存储空间),快速(读写数据、序列化与反序列化的开销小)。Hadoop中的键(key)和值(value)必须是实现了Writable接口的对象(键还必须实现WritableComparable,以便进行排序)。

package org.apache.hadoop.io;
import java.io.DataOutput;
import java.io.DataInput;
import java.io.IOException;
public interface Writable {
	/*
	object将自身字段序列化后的字节流写入输出流out中。
	参数:
	out - 接收object序列化后的字节流的输出流.
	*/
	void write(DataOutput out) throws IOException;
	/*
	将输入流in中的字节流反序列化然后写入object的字段
	参数:
	字节流的出处
	*/
	void readFields(DataInput in) throws IOException;
}

WritableComparable接口

WritableComparable接口定义如下:

package org.apache.hadoop.io;
public interface WritableComparable<T> extends Writable, comparable<T> {
}

WritableComparable没有方法,其方法都是通过继承而来,继承自Writable接口的有以下两个方法。

void write(DataOutput out) throws IOExceptionvoid readFields(DataInput in) throws IOException

还有继承自comparable的方法,comparable是属于java.lang.*中的一个接口,它只有一个方法。

int compareTo( T other);
/*
比较此对象与指定对象other的顺序。如果该对象小于、等于或大于指定对象,则
分别返回负整数、零或正整数。
参数:other - 要比较的对象。
返回:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。
*/

ObjectWritable类的实现

  1. 创建类实现WritableComparable或者Writable
  2. 根据需要定义属性,生成get/set函数
  3. 构造函数:空参/带参数
  4. 序列化反序列方法实现
    • 重写write方法并添加逻辑以写入所有字段值(就是调用基本类型的write方法)
    • 重写readFields方法从输入流读取所有字段值
  5. 重写compareTo方法并实现自定义数据类型排序的逻辑

7 简述Hadoop分区函数的作用,及自定义分区函数的方法。

Hadoop中自带了一个默认的分区类HashPartitioner,继承Partitioner类,提供了一个getPartition的方法,定义如下:

public class HashPartitioner<K, V> extends Partitioner<K, V> {
	public int getPartition(K key, V value, int numReduceTasks) {
		return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
	}
}

实现了将key均匀分布在Reduce Tasks上,例如:如果Key为Text的话,Text的hashcode方法跟String的基本一致,得到一个int整数。但是,如果string太大的话这个int整数值可能会溢出变成负数,所以和整数的上限值Integer.MAX_VALUE(即0111111111111111)进行与运算,然后再对reduce任务个数取余,这样就可以让key均匀分布在reduce上。
在这里插入图片描述
分区的作用:

  1. 根据业务需要,产生多个文件输出
  2. 多个reduce任务在运行,提高整体job的运行速度。

8 什么是HBase? HBase 的存储结构是怎样的(Region, 列族)?

HBase

HBase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,是谷歌BigTable的开源实现,主要用来存储非结构化和半结构化的松散数据

  • 适合于存储大表数据,并且对大表数据的读、写访问可以达到实时级别
  • 利用Hadoop HDFS作为其文件存储系统,提供实时读写的分布式数据库系统。
  • 利用ZooKeeper作为协同服务。

HBase与传统关系数据库的对比分析

(1)数据类型:关系数据库采用关系模型,具有丰富的数据类型和存储方式,HBase则采用了更加简单的数据模型,它把数据存储为未经解释的字符串。用户可以把不同格式的结构化数据和非结构化数据都序列化成字符串保存到HBase中。

(2)数据操作:关系数据库中包含了丰富的操作,其中会涉及复杂的多表连接,通常借助于多个表之间的主外键关联实现。HBase操作则不存在复杂的表与表之间的关系,只有简单的插入、查询、删除、清空等,因为HBase在设计上就避免了复杂的表和表之间的关系,通常只采用单表的主键查询

(3)存储模式:关系数据库是基于行模式存储的。HBase是基于列存储的,每个列族都由几个文件保存,不同列族的文件是分离的。

(4)数据索引:关系数据库通常可以针对不同列构建复杂的多个索引,以提高数据访问性能。HBase只有一个索引——行键,通过巧妙的设计,HBase中的所有访问方法,或者通过行键访问,或者通过行键扫描,从而使得整个系统不会慢下来。

(5)数据维护:在关系数据库中,更新操作会用最新的当前值去替换记录中原来的旧值, 旧值被覆盖后就不会存在。而在HBase中执行更新操作时,并不会删除数据旧的版本,而 是生成一个新的版本,旧有的版本仍然保留

(6)可伸缩性:关系数据库很难实现横向扩展,纵向扩展的空间也比较有限。相反, HBase和BigTable这些分布式数据库就是为了实现灵活的水平扩展而开发的,能够轻易地通过在集群中增加或者减少硬件数量来实现性能的伸缩。

数据模型

概述

  • HBase是一个稀疏、多维度、排序的映射表,这张表的索引是行键、列族、列限定符和时间戳
  • 每个值是一个未经解释的字符串,没有数据类型
  • 用户在中存储数据,每一行都有一个可排序的行键任意多的列
  • 表在水平方向由一个或者多个列族组成,一个列族中可以包含任意多个列,同一个列族里面的数据存储在一起
  • 列族支持动态扩展,可以很轻松地添加一个列族或列,无需预先定义列的数量以及类型, 所有列均以字符串形式存储,用户需要自行进行数据类型转换
  • HBase中执行更新操作时,并不会删除数据旧的版本,而是生成一个新的版本,旧有的版本仍然保留(这是和HDFS只允许追加不允许修改的特性相关的)

数据模型相关概念

  • 表:HBase采用表来组织数据,表由行和列组成,列划分为若干个列族
  • 行:每个HBase表都由若干行组成,每个行由**行键(rowkey)**来标识
  • 列族:一个HBase表被分组成许多列族(ColumnFamily)的集合,它是基本的访问控制单元列
  • 限定符:列族里的数据通过列限定符(或列)来定位。没有数据类型,总被视为字节数组byte[]。有点像数据库里的主键哦,区别某一行数据与其他数据。
  • 单元格:在HBase表中,通过行、列族和列限定符确定一个“单元格”(cell),单元格中存储的数据没有数据类型,总被视为字节数组byte[]。每个单元格可以保存一个数据的多个版本,每个版本对应一个不同的时间戳
  • 时间戳:每个单元格都保存着同一份数据的多个版本,这些版本采用时间戳进行索引

数据坐标

HBase中需要根据行键、列族、列限定符和时间戳来确定一个单元格,因此,可以视为一个“四维坐标”,即[行键, 列族, 列限定符, 时间戳]

Region

  • 将一个数据表按Key值范围连续划分为多个的子表,这个子表,在HBase中被称作 “Region”。

  • 每一个Region都关联一个Key值范围,即一个使用StartKey和EndKey描述的区间。

  • 事实上,每一个Region仅仅记录StartKey就可以了,因为它的EndKey就是下一个 Region的StartKey。

  • Region是HBase分布式存储的最基本单元

在这里插入图片描述

RegionServer

  • RegionServer是HBase的数据服务进程。 负责处理用户数据的读写请求。

  • Region由RegionServer管理。所有用户数据的读写请求,都是和RegionServer上的Region进行交互。

  • Region可以在RegionServer之间迁移。

  • 每个RegionServer负责管理一个region集合。

Column Family

ColumnFamily是Region的一个物理存储单元。同一个Region下面的多个ColumnFamily, 位于不同的路径下面。

一个表在水平方向上由一个或多个Column Family组成。一个Column Family可以由任意多个Column组成。Column是CF下的一个标签,可以在写入数据时任意添加,因此CF支持动态扩展,无需预先定义Column的数量和类型。HBase中表的列非常稀疏,不同行的列的个数和类型都可以不同。
在这里插入图片描述

9 什么是Hive?Hive中内部表和外部表的区别是什么?

Hive

Hive是基于Hadoop构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop分布式文件系统中的数据:

  • 可以将结构化的数据文件映射为一张数据库表,并提供完整的SQL查询功能;
  • 可以将SQL语句转换为MapReduce任务运行,通过自己的SQL查询分析需要的内容,这套SQL简称Hive SQL,使不熟悉MapReduce的用户可以很方便地利用SQL语言查询、汇总和分析数据。
  • MapReduce开发人员可以把自己写的mapperreducer作为插件来支持Hive做更复杂的数据分析。

数据仓库(DataWarehouse,DW)
数据仓库是一个面向主题的(SubjectOriented)、集成的(Integrated)、相对稳定的(Non-Volatile)、反映历史变化(TimeVariant)数据集合,用于支持管理决策。

  • 面向主题,即数据仓库中表的设计是按照一个个主题进行组织的而非按照业务流程设计;
  • 集成性,是指将企业中各大业务系统进行数据集中、整合、加工从而形成全局统一的数据视图;
  • 相对稳定,则是指数据仓库中的数据不会做频繁的增删改操作,相对于业务系统中频繁的事务处理,其数据变化相对稳定;
  • 反应历史变化,表明数据仓库通常会保存数据的历史备份,因此就可以从中获取数据历史变化情况。

可以对多种业务数据进行筛选和整合,用于数据分析、数据挖掘、数据报表

在这里插入图片描述

查询语言HiveQLSQL
数据存储位置HDFS本地FS
数据格式用户定义系统决定
数据更新不支持支持
索引新版本有,但弱,仅支持有限索引有,支持复杂索引
执行MapReduce、Tez、SparkExecutor
执行延迟
可扩展性
数据规模

hive数据分成两类:数据文件和元数据。

  • 元数据
    • 用于存放hive库的基础信息
    • 它存储在关系数据库中(如:MySQL、Derby)。
    • 主要包括数据库信息、表的名字,表的列和分区及其属性,表的属性,表的数据所在目录等。
  • 数据文件
    • hive的数据存储在HDFS中
    • 大部分的查询由MapReduce完成
    • 对于包含*的查询不会产生MapReduce作业

Driver负责将hive sql 解析和优化HQL语句,将其转换成一个Hive Job(可以是MapReduce,也可以是Spark等其他任务)并提交给Hadoop集群。

Hive的运行机制

① 用户通过用户接口连接Hive,发布Hive SQL
② Hive解析查询并制定查询计划
③ Hive将查询转换成MapReduce作业
④ Hive在Hadoop上执行MapReduce作业

内部表

内部表与关系数据库中的Table在概念上类似。每一个Table在Hive中都有一个相应的目录存储数据。所有的Table数据(不包括External Table)都保存在这个目录中。删除表时,元数据与数据都会被删除。

外部表

外部表指向已经在HDFS中存在的数据。

它和内部表在元数据的组织上是相同的,而实际数据的存储则有较大的差异。

内部表的创建过程和数据加载过程这两个过程可以分别独立完成,也可以在同一个语句中完成,在加载数据的过程中,实际数据会被移动到数据仓库目录中;之后对数据访问将会直接在数据仓库目录中完成。删除表时,表中的数据和元数据将会被同时删除。

而外部表只有一个过程加载数据和创建表同时完成,实际数据是存储在LOCATION后面指定的 HDFS 路径中,并不会移动到数据仓库目录中。当删除一个External Table时,仅删除该链接

如何选择使用内部表或外部表?

  • 如果所有处理都由Hive来完成,则使用内部表
  • 如果需要用Hive和外部其他工具处理同一组数据集,则使用外部表

10 叙述Hive中分区和分桶的概念?

分区

Partition就是一种对表进行粗略划分的机制,可以实现加快查询速度的组织形式
在Hive中,表中的一个Partition对应于表下的一个目录,所有的Partition的数据都存储在对应的目录中。
在这里插入图片描述

Buckets是将表的列通过Hash算法进一步分解成不同的文件存储。
它对指定列计算Hash,根据Hash值切分数据,目的是为了并行,每一个Bucket对应一个文件。

分区是粗粒度的划分,桶是细粒度的划分,这样做为了可以让查询发生在小范围的数据上以提高效率。适合进行表连接查询、适合用于采样分析在这里插入图片描述

11 Spark生态包含了哪些模块,各个模块的功能是什么?

Spark的生态系统主要包含了Spark Core、Spark SQL、Spark Streaming、MLlib和GraphX等组件。

  • Spark Core实现了Spark框架的基本功能,包含任务调度,内存管理,错误恢复,与存储系统交互等模块。Spark Core还包含了对弹性分布式数据集RDD的API定义。
  • Spark Streaming是Spark提供的对实时数据进行流计算的组件。
  • Spark SQL是Spark用来操作结构化数据的程序包,通过它可以使用SQL语言来查询数据,同时支持多种数据源,比如Hive, Parquet以及JSON等。
  • MLLib是Spark提供的常见机器学习功能的程序库,提供了包括分类、回归、聚类、协同过滤等机器学习算法,还提供了模型评估,数据导入等额外的功能。
  • GraphX是用来操作图的程序库,可以进行并行的图计算
    在这里插入图片描述
应用场景时间跨度其它框架Spark生态系统中的组件
复杂的批量数据处理小时级MapReduceSpark
基于历史数据的交互式查询分钟级、秒级Hive、Impala、Dremel、DrillSpark SQL
基于实时数据流的数据处理毫秒、秒级Storm、S4Spark Streaming
基于历史数据的数据挖掘-MahoutMLlib
图结构数据的处理-Pregel、HamaGraphX

12 什么是RDD?RDD的Stage是如何划分的?RDD算子分为哪两类,分别举例说明。

RDD

概念

RDD:是Resillient Distributed Dataset(弹性分布式数据集)的简称,是分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型

一个RDD就是一个分布式对象集合,本质上是一个只读的分区记录集合,每个RDD可分成多个分区,每个分区就是一个数据集片段,并且一个RDD的不同分区可以被保存到集群中不同的节点上, 从而可以在集群中的不同节点上进行并行计算。

RDD提供了一种高度受限的共享内存模型,即RDD是只读的记录分区的集合,不能直接修改,只能基于稳定的物理存储中的数据集创建RDD,或者通过在其它RDD上执行确定的转换操作(如 map、join和group by)而创建得到新的RDD
在这里插入图片描述

RDD属性

  • 只读:不能修改,只能通过转换操作生成新的 RDD。
  • 分布式:可以分布在多台机器上进行并行处理。
  • 弹性:计算过程中内存不够时它会和磁盘进行数据交换。
  • 基于内存:可以全部或部分缓存在内存中,在多次计算间重用

RDD运行原理

RDD执行过程如下:

  • RDD读入外部数据源进行创建
  • RDD经过一系列的转换(Transformation)操作,每一次都会产生不同的RDD,供给下一个转换操作使用
  • 最后一个RDD经过“动作”操作进行转换,并输出到外部数据源

这一系列处理称为一个Lineage(血缘关系),即DAG拓扑排序的结果优点:惰性调用、管道化、避免同步等待、不需要保存中间结果、每次操作变得简单
在这里插入图片描述

RDD之间的依赖关系

  • 窄依赖表现为一个父RDD的分区对应于一个子RDD的分区或多个父RDD的分区对应于一个子RDD的分区
  • 宽依赖则表现为存在一个父RDD的一个分区对应一个子RDD的多个分区

在这里插入图片描述

窄依赖

1)子RDD的每个分区依赖于常数个父分区(即与数据规模无关)。
2)输入输出一对一的算子,且结果RDD的分区结构不变,如map、flatMap。
3)输入输出一对一的算子,但结果RDD的分区结构发生了变化,如union。
4)从输入中选择部分元素的算子,如filter、distinct、subtract、sample。

宽依赖

1)子RDD的每个分区依赖于所有父RDD分区。
2)对单个RDD基于Key进行重组和reduce,如groupByKey、reduceByKey。
3)对两个RDD基于Key进行join和重组,如join

Spark的这种依赖关系设计,使其具有了天生的容错性,大大加快了Spark的执行速度。RDD通过血缘关系记住了它是如何从其他RDD中演变过来的。当这个RDD的部分分区数据丢失时,它可以通过血缘关系获取足够的信息来重新运算和恢复丢失的数据分区,从而带来性能的提升。

Stage的划分

Spark通过分析各个RDD的依赖关系生成了DAG,再通过分析各个RDD中的分区之间的依赖关系来决 定如何划分Stage,具体划分方法是:

  • 在DAG中进行反向解析,遇到宽依赖就断开
  • 遇到窄依赖就把当前的RDD加入到Stage中
  • 将窄依赖尽量划分在同一个Stage中,可以实现流水线计算

RDD的算子

Transformation

  • Transformation是通过转换从一个或多个RDD生成新的RDD,该操作是lazy的,当调用action算子,才发起job。
  • 典型算子:mapflatMap、filter、reduceByKey等。

Action

  • 当代码调用该类型算子时,立即启动job
  • 典型算子:takecountsaveAsTextFile等。

13 Spark运行架构包括哪些组件,各个组件的功能是什么。

Spark运行架构包括

  • 集群资源管理器(Cluster Manager)
  • 运行作业任务的工作节点(Worker Node)
  • 每个应用的任务控制节点(Driver)
  • 每个工作节点上负责具体任务的执行进程(Executor)

其中,资源管理器可以为spark自带的,也可以是Mesos或YARN等资源管理框架
spark运行架构
一个Application由一个Driver和若干个Job构成,一个Job由多个Stage构成,一个Stage由多个没 有Shuffle关系的Task组成 。

当执行一个Application时,Driver会向集群管理器申请资源,启动Executor,并向Executor发送应用程序代码和文件,然后在Executor上执行Task,运行结束后,执行结果会返回给Driver,或者写到HDFS或者其它数据库中。

spark中各种概念之间的相互关系

14 Spark Streaming的设计原理是什么?什么是无状态转换和有状态转换?

流计算是针对流数据的实时计算

Spark Streaming是构建在Spark上的实时计算框架,且是对Spark Core API的一个扩展,它能够实现对流数据进行实时处理,并具有很好的可扩展性、高吞吐量和容错性

Spark Streaming可整合多种输入数据源,如Kafka、Flume、HDFS,甚至是普通的TCP套接字。经处理后的数据可存储至文件系统、数据库,或显示在仪表盘里。

sparksreaming支持的输入、输出数据源

设计原理@

Spark Streaming的基本原理是将实时输入数据流时间片(秒级)为单位进行拆分,然后经Spark引擎以类似批处理的方式处理每个时间片数据

有状态和无状态转换

无状态转换

和Spark core的语义一致,无状态转化操作就是把简单的RDD转化操作应用到每个批次上。

那么Spark Streaming的无状态转化操作,也就是对Dstream的操作会映射到每个批次的RDD上

无状态转换操作不会跨多个批次的RDD去执行,即每个批次的RDD结果不能累加。

有状态转换

有状态操作是跨时间区间跟踪处理数据的操作。依赖于之前批次的数据。

1)updateStateByKey函数

有时我们需要在DStream 中跨所有批次维护状态(例如跟踪用户访问网站的会话)。针对这种情况,updateStateByKey() 为我们提供了对一个状态变量的访问,用于键值对形式的Dstream。
使用updateStateByKey需要完成两步工作:
第一步:定义状态,状态可以是任意数据类型
第二步:定义状态更新函数- update(events, oldState)

之前我们写过的wordcount程序,我们应该发现了:单词数统计是按批次的,批次与批次互不影响,当你不断输入某个单词的时候,总的计数不会累加。那么如果想要在任意状况下都去更新某个信息,就需要使用UpdateStateByKey ,使用此功能必须执行两个步骤。

2)windows函数

windows(窗口)函数也是一种有状态操作,基于windows的操作会在一个比StreamingContext的批次间隔更长的时间范围内,通过整合多个批次的结果,计算出整个窗口的结果。
所有基于窗口的操作都需要两个参数,分别为windowDuration以及slideDuration,两者都必须是StreamContext的批次间隔的整数倍

windowDuration表示窗口框住的时间,slideDuration表示每次窗口移动的时间

间隔多久进行整合操作?slideDuration
对多少个批次进行整合?windowDuration

假设batchDuration为5秒,slideDuration为10秒,windowDuration为15秒。

  • 每5秒采集的数据会生成一个RDD。
  • 每10秒会执行一次计算。即每3个RDD会执行一次计算。
  • 每次计算会计算最新的15秒内所采集的数据。即每次计算最新的3个RDD在合并之后的大RDD。

在这里插入图片描述

15 Spark与Hadoop的相同点和不同点?

1)应用场景不同

Hadoop和Spark两者都是大数据框架,但是各自应用场景是不同的。Hadoop是一个分布式数据存储架构,它将巨大的数据集分派到一个由普通计算机组成的集群中的多个节点进行存储,降低了硬件的成本。Spark是那么一个专门用来对那些分布式存储的大数据进行处理的工具,它要借助hdfs的数据存储。

2)处理速度不同

hadoop的MapReduce是分步对数据进行处理的,从磁盘中读取数据,进行一次处理,将结果写到磁盘,然后在从磁盘中读取更新后的数据,再次进行的处理,最后再将结果存入磁盘,这存取磁盘的过程会影响处理速度。spark从磁盘中读取数据,把中间数据放到内存中,,完成所有必须的分析处理,将结果写回集群,所以spark更快。

3)容错性不同

Hadoop将每次处理后的数据都写入到磁盘上,基本谈不上断电或者出错数据丢失的情况。Spark的数据对象存储在弹性分布式数据集 RDD,RDD是分布在一组节点中的只读对象集合,如果数据集一部分丢失,则可以根据于数据衍生过程对它们进行重建。而且RDD 计算时可以通过 CheckPoint 来实现容错。

16 我们在实验中构建的流处理框架由哪几个组件构成?各个组件所起的作用是什么?

参与方们@

我们模拟生成电商平台购买日志,然后使用Flume对日志进行收集,收集的日志一方面存入HDFS,一方面传给Kafka,Kafka收到的日志传给SparkStreaming进行实时流处理,处理的结果存入Mysql。

SparkStreaming组件成分

  • StreamingContext:SparkStreaming中Driver端的上下文对象,初始化的时候会构造SparkStreaming应用程序需要使用的组件,比如DStreamGraph、JobScheduler等。
  • DStreamGraph:用于保存DStream和DStream之间依赖关系等信息。
  • JobScheduler:主要用于调度job。JobScheduler主要通过JobGenerator产生job,并且通过ReceiverTracker管理流数据接收器Receiver。
  • JobGenerator:主要是从DStream产生job,且根据指定时间执行checkpoint.它维护了一个定时器,该定时器在批处理时间到来的时候会进行生成作业的操作。
  • ReceiverTracker:管理各个Executor上的Receiver的元数据。它在启动的时候,需要根据流数据接收器Receiver分发策略通知对应的Executor中的ReceiverSupervisor(接收器管理着)启动,然后再由ReceiverSupervisor来启动对应节点的
  • ReceiverStreamingContext:SparkStreaming中Driver端的上下文对象,初始化的时候会构造SparkStreaming应用程序需要使用的组件,比如DStreamGraph、JobScheduler等。
  • DStreamGraph:用于保存DStream和DStream之间依赖关系等信息。
  • JobScheduler:主要用于调度job。JobScheduler主要通过JobGenerator产生job,并且通过ReceiverTracker管理流数据接收器Receiver。
  • JobGenerator:主要是从DStream产生job,且根据指定时间执行checkpoint.它维护了一个定时器,该定时器在批处理时间到来的时候会进行生成作业的操作。
  • ReceiverTracker:管理各个Executor上的Receiver的元数据。它在启动的时候,需要根据流数据接收器Receiver分发策略通知对应的Executor中的ReceiverSupervisor(接收器管理着)启动,然后再由ReceiverSupervisor来启动对应节点的Receiver
    在这里插入图片描述
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值