Hadoop学习笔记


大数据:对海量数据进行存储和分析
工具:
存储:Hadoop(HDFS、HBASE、HIVE)
分析:MapReduce、spark、streaming、flink
大数据是指利用常用软件工具捕获、管理和处理数据所耗时间超过可容忍时间的数据集。
HDFS前身是GFS(谷歌)
HBASE前身是BigTable(google)

大数据应用领域:
物联网、智慧城市、区块链、人工智能
物联网:把物品通过信息传感设备与互联网连接起来,进行信息交换。
智慧城市:
区块链:本质是一个去中心化(点对点的交互,不涉及第三方)的分布式账本数据。

数据多样性:结构化、文本、音视频
大数据需要实时处理,需要数据的稳定

华为大数据解决方案:
FusionInsight HD 云计算

Hadoop的核心:HDFS和MapReduce

在这里插入图片描述
YARN是资源管理系统,一个通用的资源管理模块,为上层各类应用程序提供资源管理和调度功能,HBASE是底层存储,YARN的上层是各类应用程序。

HDFS(分布式文件存储系统)的特性:
高容错性:认为硬件是不可靠的(数据副本机制、副本重建)
高吞吐量:为大量数据访问提供高吞吐量的支持
大文件存储:支持TB~PB级别的数据
适用于大文件的存储与访问、流式数据访问(需要一次写入,多次读取)
不支持随机写入(支持追加写入,不支持offset修改),不支持大量小文件存储(namenode储存的元数据信息过多),低延时读取(高吞吐、高延时)。
HDFS可线性扩展:在当前节点的基础上可增加节点,namenode会感知到这个变化,进行负载均衡。
Yarn:资源管理器

namenode:负责整个集群的元数据管理(存放元数据及管理)
datanode:存储实际的数据
blocks:HDFS处理数据的最小单元,每个单元128MB。每个blocks可以有多个副本,存在不同的DataNode上(高容错性)
hdfs核心:block:存储单元128m,磁盘里面的和文件系统里面的两个都叫block,但是大小是不一样的,磁盘里面一般都是512bytes。
通常情况下:大文件切分成block大小的chunk作为独立储存单元,如果文件大小小于128M。比如1M,那么在hdfs中只会占用1M大小。
hdfs的block为什么是128M?
1.减少寻址开销 最小化查找时间
2.控制定位文件与传输文件所用的时间比
block也不能太大:太大会失去分布式存储这一特点。
block的好处:可以让大文件分布在多个节点上,在运算时如MapReduce可以并行读取数据。

请求向HDFS发送一个文件流程:
1.客户端和namenode进行通信,请求文件上传
2.namenode检查元数据目录树(nn检查文件路径是否存在,是否有重名文件)
3.返回信息给客户端是否能上传数据
4.上传blocks
5.查询datanode信息(将数据传入哪些datanode)
6.返回可用的datanode
7.客户端发出传送数据建立流水线的请求(pipeline),选择最近(最优)的一台进行写入
8.另外n台datanode之间建立流水线
9.发送数据
10.完成数据传输和副本建立
在这里插入图片描述
在这里插入图片描述

  • 客户端开始写文件时DFSOutputStream 会将文件分割成 packets 数据包(一般为 64K),然后将这些 packets 写到其内部的一个叫做 data queue(数据队列)。

  • DFSOutputStream 内部同样维护另外一个内部的写数据确认队列—— ack queue 。当 Pipeline 中的第三个 DataNode 节点将 packets 成功保存后,该节点回向第二个 DataNode 返回一个确认数据写成功的信息,第二个 DataNode 接收到该确认信息后在当前节点数据写成功后也会向 Pipeline 中第一个 DataNode 节点发送一个确认数据写成功的信息,然后第一个节点在收到该信息后如果该节点的数据也写成功后,会将 packets 从 ack queue 中将数据删除。

  • DistributedFileSystem对象:HDFS客户端通过调用DistributedFileSystem的Create()方法来请求创建文件。

  • FSDataOutputStream对象:DistributedFileSystem通过对NameNode发出RPC请求,在NameNode的Namespace里面创建一个新的文件信息。DistributedFileSystem返回一个FSDataOutputStream给客户端,让它从FSDataOutputStream中写入数据,FSDataOutputStream接着包装一个DFSOutputStream,用来与DataNode及NameNode的I/O 通信。

  • Flush:在返回写完成功后,更新当前状态。

请求读取数据流程:
1.请求读取一个文件,namenode的元数据中储存着文件被分为哪些数据块,这些数据块被放在哪些datenode上。
2.返回元数据的信息,告诉客户端从哪些datanode上读取信息。
3.读取blocks,把数据放在本地缓冲区,将数据排序整理之后再呈现出来。
在这里插入图片描述
读取数据过程中,如果datanode通信发生错误,DFSinputstream对象会尝试从下一个最佳节点读取数据,同时记住该失败节点,后续block的读取不会在连接该节点。读取block之后DFSinputstream对象回去验证block是否损坏,如果block损坏,尝试从其他节点进行读取,并且将损坏的block汇报给namenode

  • DistributedFileSystem对象:HDFS客户端通过调用DistributedFileSystem对象的open()方法打开需要读取的文件。
  • FSDataInputStream对象:DistributedFileSystem通过对NameNode发出RPC请求,确定要读取文件的block的位置。DistributedFileSystem返回一个FSDataInputStream给HDFS客户端,让它从FSDataInputStream中读取数据。FSDataInputStream接着包装一个DFSInputStream,用来与DataNode及NameNode的I/O 通信。

HDFS架构关键设计:
联邦存储机制(federation):namespace:根据不同业务创建不同的namespace,不同的namespace管理不同的nn
产生原因:单Active NN的架构使得HDFS在集群扩展性和性能上都有潜在的问题,当集群大到一定程度后,NN进程使用的内存可能会达到上百G,NN成为了性能的瓶颈。
数据块池:就是属于单个命名空间的一组block(块)。
隔离性。每个namenode只管理一部分文件 。不同用户可以被namespace隔离。
数据存储策略——分级存储:将四种不同存储类型的存储设备(RAM_DISK、DISK、ARCHIVE、SSD)进行组合,形成适用于不同场景的存储策略。标签存储,节点组存储。

HA高可用性
在这里插入图片描述

  • 利用zookeeper来实现主备namenode,来解决单点nn故障。
  • zookeeper:分布式锁机制 选举主备NameNode(zkfc),ZKFC(ZooKeeper Failover Controller)用于 - 监控NameNode节点的主备状态。
  • JN(JournalNode)用于存储Active NameNode生成的Editlog。Standby NameNode加载JN上Editlog,同步元数据。
  • 心跳线:连接作用,周期性的传递信息。(datanode向nn定期的发送心跳信息)。
  • Active状态nn的选举方案:奇数个zookeeper用来选举主备nn,zkfc监控nn的主备信息,并定期向zookeeper发送心跳信息。
  • 元数据同步
    在这里插入图片描述
  • 主NameNode对外提供服务。生成的Editlog同时写入本地和JN,同时更新主NameNode内存中的元数据。
  • 备NameNode监控到JN上Editlog变化时,加载Editlog进内存,生成新的与主NameNode一样的元数据。元数据同步完成。
  • 主备的FSImage仍保存在各自的磁盘中,不发生交互。FSImage是内存中元数据定时写到本地磁盘的副本,也叫元数据镜像。
  • EditLog:记录用户的操作日志,用以在FSImage的基础上生成新的文件系统镜像。
  • FSImage:用以阶段性保存文件镜像。
  • FSImage.ckpt:在内存中对fsimage文件和EditLog文件合并(merge)后产生新的fsimage,写到磁盘上,这个过程叫checkpoint.。备用NameNode加载完fsimage和EditLog文件后,会将merge后的结果同时写到本地磁盘和NFS。此时磁盘上有一份原始的fsimage文件和一份新生成的checkpoint文件:fsimage.ckpt. 而后将fsimage.ckpt改名为fsimage(覆盖原有的fsimage)。
  • EditLog.new: NameNode每隔1小时或Editlog满64MB就触发合并,合并时,将数据传到Standby NameNode时,因数据读写不能同步进行,此时NameNode产生一个新的日志文件Editlog.new用来存放这段时间的操作日志。Standby NameNode合并成fsimage后回传给主NameNode替换掉原有fsimage,并将Editlog.new 命名为Editlog。
  • 元数据持久化机制(即元数据同步):
    active nn对外服务产生日志(editlog:存在JN和nn本地),standby nn从JN中copy日志,FSImage(阶段性地保存文件)同步(和active状态里的日志对比,看看是否一致)。
    触发条件:editlog存满或工作一小时
    具体步骤(不断地将editlog中的内容追加更新到fsimage中):
    1.通知同步,由于nna还在工作,生成一个editlog.new
    2.nns从nna中获取editlog及FSImage(fsimage仅在nn初始化时进行下载,后续使用本地文件)
    3.将editlog和FSImage合并成FSImage.ckpt(checkpoint检查点)
    4.将生成checkpoint传到nna
    5.回滚更新nna中的fsimage,并将editlog.new改为editlog

多方式访问机制
空间回收机制
nn/dn主从模式
统一的文件系统命名空间
健壮机制
数据副本机制(默认副本有3个)

  • 同机架的不同节点distance=2,不同机架的节点distance=4,同台服务器的distance=0
  • 副本放置策略:
    第一个副本在本节点。
    第二个副本在远端机架的节点。
    第三个副本看之前的两个副本是否在同一机架,如果是则选择其他机架,否则选择和第一个副本相同机架的不同节点,第四个及以上,随机选择副本存放位置。

数据完整性保障:
重建失效数据盘副本数据:DataNode向NameNode周期上报失败时,NameNode发起副本重建动作以恢复丢失副本。
集群数据均衡机制:HDFS架构设计了数据均衡机制,此机制保证数据在各个DataNode上分布是平均的。
元数据可靠性保证:采用日志机制操作元数据,同时元数据存放在主备NameNode上。快照机制实现了文件系统常见的快照机制,保证数据误操作时,能及时恢复。
安全模式:HDFS提供独有安全模式机制,在数据节点故障,硬盘故障,能防止故障扩散。(如在故障时只能进行读操作,而不能进行写等操作)
在这里插入图片描述
在这里插入图片描述

MapReduce

MapReduce用于大规模数据的并行运算。

  • 在启动MapReduce之前,确保待处理的文件放在HDFS上面。
  • MapReduce应用将请求提交给RM,由RM创建对应的Job,一个应用对应一个Job(jobID形如,job_201431281420_0001)。
  • Job提交前,先将待处理的文件进行分片(Split)。MR框架默认将一个块(Block)作为一个分片。客户端应用可以重定义块与分片的映射关系。
  • Job提交给RM,RM根据NM的负载在NM集群中挑选合适的节点调度AM,AM负责Job任务的初始化并向RM申请资源,由RM调度合适的NM启动Container, Container来执行Task。

map+reduce(拆分+组合)
map过程:
启动MapReduce,将HDFS上的文件进行逻辑上的切片(以block的大小进行切片),每一个切片都生成一个maptask。——>对每一个block的文件的每一行都生成一个键值对<key,value>,(默认按行读取数据)。——>对键值对调用map方法(map方法具体由自己编写,决定要实现什么功能)。——> Map的输出放入一个环形内存缓冲区,当缓冲区数据溢出时,需将缓冲区中的数据写入到本地磁盘,写入本地磁盘之前通常需要做如下处理:1.分区:对上一阶段的输出进行逻辑上分区(分区:即reducetask的个数来确定分区数,默认采用hash算法进行分区),具备相同的key值的记录送到相同的reduce task(reducetask的数目是自己设定的)来处理。(在分区部分,hash算法,数值 mod N = 数组存放地址,当地址相同时,在数组位置中建立列表存放相同key(地址值相同)的数据;——> 2.排序:对每一个分区中的键值对进行排序,先根据key进行排序,再根据value进行排序**——>** 3.combine组合(局部聚合):对同一个map任务进行一个reduce操作(map端的reduce)。(可以减少数据量)——> 4.合并(Spill)—Map Task在处理后会产生很多的溢出文件(spill file),这时需将多个溢出文件进行合并处理(合并的过程中会不断地进行排序和combine操作),生成一个经过分区和排序的Spill File(MOF:MapOutFile,一个MOF文件可能有多个分区,由reduce Task决定)。为减少写入磁盘的数据量,MR支持对MOF进行压缩(就是指combine操作)后再写入。
每个map task都有一个内存缓冲区,存储着map的输出结果,当缓冲区快满的时候需要将缓冲区的数据以一个临时文件的方式存放到磁盘,当整个map task结束后再对磁盘中这个map task产生的所有临时文件做合并,生成最终的正式输出文件,然后等待reduce task来拉数据。
reduce过程:
copy:将maptask的输出结果复制,拉取到一台机器上。——> 复制到本地,合成一个文件(默认一个分区的情况下,多个分区的情况下文件数会和map阶段的分区数和task阶段的分区数一致),进行排序。**——>**调用reduce方法生成输出。
shuffle机制:(不需要编写)(洗牌)
map阶段和reduce阶段之间传递中间数据的过程,包括reducetask从各个Maptask获取MOF文件的过程,以及对mof的排序与合并处理。

可以通过Wordcount实例来认识MapReduce过程。

YARN资源管理器

组件:
resource manager 全局资源管理器,一个集群只有一个rm 负责和am(application master)交互资源调度,资源分配(老板)
application manager 应用程序的管理器,一个应用程序只有一个am 和rm通信,开始任务时和rm要资源。任务完时和rm注销。和nm通信 启动/停止相应的任务,接受nm的任务进度信息(项目经理)
node manager 一台机器上的管理者 管理本机上若干个container的生命周期、资源、节点健康情况——》上报给rm,接收处理来自am的container的启动、停止等各种请求(部门经理)
container 一台机器上具备资源,yarn中资源的抽象 task是运行在container里面 ,container是一个动态资源分配单位。(底层员工)

MapReduce on Yarn
步骤1:用户向YARN 中提交应用程序, 其中包括ApplicationMaster 程序、启动ApplicationMaster 的命令、用户程序等。
步骤2:ResourceManager 为该应用程序分配第一个Container, 并与对应的NodeManager 通信,要求它在这个Container 中启动应用程序的ApplicationMaster 。
步骤3:ApplicationMaster 首先向ResourceManager 注册, 这样用户可以直接通过ResourceManage 查看应用程序的运行状态,然后它将为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复步骤4~7。
步骤4:ApplicationMaster 采用轮询的方式通过RPC 协议向ResourceManager 申请和领取资源。
步骤5:一旦ApplicationMaster 申请到资源后,便与对应的NodeManager 通信,要求它启动任务。
步骤6:NodeManager 为任务设置好运行环境(包括环境变量、JAR 包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务。
步骤7:各个任务通过某个RPC 协议向ApplicationMaster 汇报自己的状态和进度,以让ApplicationMaster 随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。在应用程序运行过程中,用户可随时通
过RPC 向ApplicationMaster 查询应用程序的当前运行状态。
步骤8 应用程序运行完成后,ApplicationMaster 向ResourceManager 注销并关闭自己。

yarn资任务调度流程:
客户端向rm发起请求——》resource manager找一个node manager启动一个container作为application manager——》application manager向rm请求资源——》am得到资源,和具体的nm进行通信,启动container,执行相应的任务,在任务执行过程中container会向am汇报执行情况——》任务完成时am向rm注销,结束整个应用程序。

yarn HA方案

  • ResourceManager的高可用性方案是通过设置一组Active/Standby的ResourceManager节点来实现的。与HDFS的高可用性方案类似,任何时间点上都只能有一个ResourceManager处于Active状态。当Active状态的ResourceManager发生故障时,可通过自动或手动的方式触发故障转移,进行Active/Standby状态切换。
  • 开启自动故障转移后,ResourceManager会通过内置的基于ZooKeeper实现的ActiveStandbyElector来决定哪一个ResouceManager应该成为Active节点。当Active状态的ResourceManager发生故障时,另一个ResourceManager将自动被选举为Active状态以接替故障节点。
  • 当集群的ResourceManager以HA方式部署时,客户端使用的“YARN-site.xml”需要配置所有ResourceManager地址。客户端(包括ApplicationMaster和NodeManager)会以轮询的方式寻找Active状态的ResourceManager。如果当前Active状态的ResourceManager无法连接,那么会继续使用轮询的方式找到新的ResourceManager。
  • 备RM升主后,能够恢复故障发生时上层应用运行的状态。当启用ResourceManager Restart时,重启后的ResourceManager就可以通过加载之前Active的ResourceManager的状态信息,并通过接收所有NodeManager上container的状态信息重构运行状态继续执行。这样应用程序通过定期执行检查点操作保存当前状态信息,就可以避免工作内容的丢失。状态信息需要让Active/Standby的ResourceManager都能访问。当前系统提供了三种共享状态信息的方法:通过文件系统共享(FileSystemRMStateStore)、通过LevelDB数据库共享(LeveldbRMStateStore)或通过ZooKeeper共享(ZKRMStateStore)。这三种方式中只有ZooKeeper共享支持Fencing机制。Hadoop默认使用ZooKeeper共享。

yarn APPmaster容错机制(计算迁移)

  • 在YARN中,ApplicationMaster(AM)与其他Container类似也运行在NodeManager上(忽略未管理的AM)。AM可能会由于多种原因崩溃、退出或关闭。如果AM停止运行,ResourceManager(RM)会关闭ApplicationAttempt中管理的所有Container,包括当前任务在NodeManager(NM)上正在运行的所有Container。RM会在另一计算节点上启动新的ApplicationAttempt。
  • 不同类型的应用希望以多种方式处理AM重新启动的事件。MapReduce类应用目标是不丢失任务状态,但也能允许一部分的状态损失。但是对于长周期的服务而言,用户并不希望仅仅由于AM的故障而导致整个服务停止运行。
  • YARN支持在新的ApplicationAttempt启动时,保留之前Container的状态,因此运行中的作业可以继续无故障的运行。

Yarn资源管理
Yarn当前支持内存和CPU的管理和分配。
可以通过以下命令来配置:

  • Yarn.nodemanager.resource.memory-mb(内存)
  • Yarn.nodemanager.vmem-pmem-ratio
  • Yarn.nodemanager.resource.cpu-vcore(内核数)

容量调度器:
在这里插入图片描述
容量调度器使得Hadoop应用能够共享的、多用户的、操作简便的运行在集群上,同时最大化集群的吞吐量和利用率。

YARN动态内存管理:
在这里插入图片描述
NM总内存阈值的计算方法是Yarn.nodemanager.resource.memory-mb10241024*Yarn.nodemanager.dynamic.memory.usage.threshold,单位GB

SPARK

Apache spark是一种基于内存的快速、通用,可扩展的大数据计算引擎。是一站式解决方案,集批处理、实时流处理、交互式查询、图计算与机器学习于一体。
在这里插入图片描述

  • SparkCore:类似于MR的分布式内存计算框架,最大的特点是将中间计算结果直接放在内存中,提升计算性能。自带了Standalone模式的资源管理框架,同时,也支持YARN、MESOS的资源管理系统。FI集成的是Spark On Yarn的模式。其它模式暂不支持。
  • SparkSQL:Spark SQL是一个用于处理结构化数据的Spark组件,作为Apache Spark大数据框架的一部分,主要用于结构化数据处理和对数据执行类SQL查询。通过Spark SQL,可以针对不同数据格式(如:JSON,Parquet, ORC等)和数据源执行ETL操作(如:HDFS、数据库等),完成特定的查询操作。
  • SparkStreaming:微批处理的流处理引擎,将流数据分片以后用SparkCore的计算引擎中进行处理。相对于Storm,实时性稍差,优势体现在吞吐量上。
  • Mllib和GraphX主要一些算法库。
  • FusionInsight Spark默认运行在YARN集群之上。
  • Structured Streaming为2.0版本之后的spark独有。

RDD:弹性分布式数据集(数据的抽象)
RDD默认储存在内存,内存不足会溢写到磁盘。
RDD数据以分区的形式在集群中存储。
RDD发生数据丢失时,可以快速进行数据恢复(会记录某个块上的单个操作,或可以说是记录的是元数据的信息)。

RDD的依赖关系(两个连续的RDD之间的关系):宽依赖【又叫shuffle依赖】(一[父RDD的一个分区]对多[子RDD的一个分区])、窄依赖(一对一)

DAG(有向无环导图)
RDD的stage(阶段)划分:调度器从DAG图末端出发,逆向遍历整个依赖关系链,遇到ShuffleDependency(宽依赖关系的一种叫法)就断开,遇到NarrowDependency就将其加入到当前stage,窄依赖会在一个stage中完成,宽依赖是阶段划分的依据:
在这里插入图片描述

spark任务调度

  • DAGSchedule将Job划分一个个stage。每个stage对应一个TaskSet,TaskSet由一组业务逻辑完全相同只是数据不同的Task组成。这些TaskSet最终被提交给TaskSchedule。

spark中的重要角色

  • Driver:负责应用的业务逻辑和运行规划(DAG)
  • ApplicationMater:负责应用的资源管理,根据业务需求,向ResourceManager中申请资源。
  • Client:负责提交需求。
  • ResourceManager:资源管理部门,负责整个集群的资源统一调度和分配。
  • Nodemanager:负责本节点的资源管理。
  • Executor:实际任务的执行者。一个应用会分拆给多个Executor来进行计算。

spark-shell
spark context初始化一个对象:sc
textfile:读取数据文件(可以读取本地文件,也可读取HDFS文件)
flatmap():切分压平
map((元组)):映射,将key和1结合起来形成一个(key,value)对
reducebykey:按key进行结合
collect:将数据收集到driver端
在这里插入图片描述

spark on yarn-client 和 spark on yarn-cluster
client模式:driver运行在client上,要提交任务,并进行任务的调度,appM只用向RM申请资源,之后由driver直接和executor进行通信。
cluster模式:driver运行在AM上,AM包含driver进程,所以appMaster不但负责资源的申请,还负责与executor和RM的通信。
在这里插入图片描述

在这里插入图片描述

spark SQL
Spark SQL是Spark中用于结构化数据处理的模块。在Spark应用中,可以无缝的使用SQL语句亦或是DataFrame API对结构化数据进行查询。
Spark SQL将SQL语言解析成RDD,再由Spark Core执行。

DataSet

  • Dataset是一个新的数据类型。Dataset与RDD高度类似,性能比较好。
  • DataSet以Catalyst逻辑执行计划表示,并且数据以编码的二进制形式存储,不需要反序列化就可以执行sort、filter、shuffle等操作。本质上,数据集表示一个逻辑计划,该计划描述了产生数据所需的计算。
  • Dataset 与 RDD 相似, 然而, 并不是使用 Java 序列化或者 Kryo 编码器来序列化用于处理或者通过网络进行传输的对象。 虽然编码器和标准的序列化都负责将一个对象序列化成字节,编码器是动态生成的代码,并且使用了一种允许 Spark 去执行许多像 filtering, sorting 以及 hashing 这样的操作, 不需要将字节反序列化成对象的格式。
  • jvm中存储的java对象可以是序列化的,也可以是反序列化的。序列化的对象是将对象格式化成二进制流,可以节省内存。反序列化则与序列化相对,是没有进行二进制格式化,正常存储在jvm中的一般对象。RDD可以将序列化的二进制流存储在jvm中,也可以是反序列化的对象存储在JVM中。至于现实使用中是使用哪种方式,则需要视情况而定。例如如果是需要最终存储到磁盘的,就必须用序列化的对象。如果是中间计算的结果,后期还会继续使用这个结果,一般都是用反序列化的对象。

DataFrame
指定列名的DataSet。DataFrame是Dataset[Row]的特例(Row:代表关系型操作符的输出行;类似Mysql的行)。

  • DataFrame提供了详细的结构信息,使得Spark SQL可以清楚地知道该数据集中包含哪些列,每列的名称和类型各是什么。DataFrame多了数据的结构信息,即schema(schema就是数据库对象的集合,这个集合包含了各种对象如:表、视图、存储过程、索引等)。
  • DataFrame在序列化与反序列化时,只需对数据进行序列化,不需要对数据结构进行序列化。

RDD、DataFrame和DataSet

  • RDD:
    优点:类型安全,面向对象。
    缺点:序列化和反序列化的性能开销大;GC的性能开销,频繁的创建和销毁对象, 势必会增加GC。
  • DataFrame:
    优点:自带scheme信息,降低序列化反序列化开销。
    缺点:不是面向对象的;编译期不安全。
  • Dataset的特点:
    快:大多数场景下,性能优于RDD;Encoders(编码器)优于Kryo或者Java序列化;避免不必要的格式转化。
    类型安全:类似于RDD,函数尽可能编译时安全。
    和DataFrame,RDD互相转化。
    Dataset具有RDD和DataFrame的优点,又避免它们的缺点。

Spark SQL vs Hive
区别:
Spark SQL的执行引擎为Spark core,Hive默认执行引擎为MapReduce。
Spark SQL的执行速度是Hive的10-100倍。
Spark SQL不支持buckets,Hive支持。
联系:
Spark SQL依赖Hive的元数据。
Spark SQL兼容绝大部分Hive的语法和函数。
Spark SQL可以使用Hive的自定义函数。
Spark-sql的元数据和数据文件与Hive完全共用。

Structured Streaming是构建在Spark SQL引擎上的流式数据处理引擎。可以像使用静态RDD数据那样编写流式计算过程。当流数据连续不断的产生时,Spark SQL将会增量的、持续不断的处理这些数据,并将结果更新到结果集中。

  • Structured Streaming的核心是将流式的数据看成一张数据不断增加的数据库表,这种流式的数据处理模型类似于数据块处理模型,可以把静态数据库表的一些查询操作应用在流式计算中,Spark执行标准的SQL查询,从无边界表中获取数据。

  • 无边界表:新数据不断到来,旧数据不断丢弃,实际上是一个连续不断的结构化数据流。
    structured Streaming计算模型

  • 每一条查询的操作都会产生一个结果集Result Table。每一个触发间隔,当新的数据新增到表中,都会最终更新Result Table。无论何时结果集发生了更新,都能将变化的结果写入一个外部的存储系统。

  • Structured Streaming在OutPut阶段可以定义不同的数据写入方式,有如下3种:

  1. Complete Mode:整个更新的结果集都会写入外部存储。整张表的写入操作将由外部存储系统的连接器完成。
  2. Append Mode:当时间间隔触发时,只有在Result Table中新增加的数据行会被写入外部存储。这种方式只适用于结果集中已经存在的内容不希望发生改变的情况下,如果已经存在的数据会被更新,不适合适用此种方式。
  3. Update Mode:当时间间隔触发时,只有在Result Table中被更新的数据才会被写入外部存储系统。注意,和Complete Mode方式的不同之处是不更新的结果集不会写入外部存储。

spark streaming实时计算框架(处理微批数据)
Spark Streaming 计算基于DStream,将流式计算分解成一系列短小的批处理作业。
Spark Streaming基本原理:把输入数据以秒(毫秒)为单位切分,再定时提交这些切分后的数据。
在这里插入图片描述
spark streaming的容错机制:Spark Streaming本质仍是基于RDD计算,当RDD的某些partition丢失,可以通过RDD的血统机制重新恢复丢失的RDD。
在这里插入图片描述
storm可以动态调整并行度,spark streaming位于Spark生态技术栈中,因此Spark Streaming可以和Spark Core、Spark SQL无缝整合,也就意味着,我们可以对实时处理出来的中间数据,立即在程序中无缝进行延迟批处理、交互式查询等操作。这个特点大大增强了Spark Streaming的优势和功能。

Hive数据仓库(数据分析的平台)

Hive 是一种基于hadoop的数据仓库软件,可以查询和管理PB级别的分布式数据。默认由M/R进行查询分析,使用类SQL的HiveQL语言实现数据查询功能,所有Hive的数据都存储在HDFS中。
在这里插入图片描述
Hive可以做海量数据的存储(储存在hdfs中,没有专门的数据储存格式)和分析。
灵活方便的ETL(extract/transform/load)。支持MapReduce,Tez,Spark等多种计算引擎。可直接访问HDFS文件以及HBase。易用易编程。

HIVE有很多内置的函数,还可有用户自定义函数。

可以将Hive看做hadoop的一个客户端。HIve利用hdfs储存数据,利用M/R查询分析数据。

应用场景:数据挖掘、非实时分析、数据汇总、数据仓库

在这里插入图片描述
HIve的优点

  1. 高可靠、高容错:HiveServer(Hive对外提供SQL服务的主要进程)采用集群模式、双MetaStore、超时重试机制
  2. 类SQL:内置SQL语法、内置大量函数
  3. 可扩展:存储在hdfs上、可自定义函数
  4. 多接口:Beeline(hive命令行的客户端)、JDBC(Java统一数据库接口)、Thrift(一种序列化通信协议)、Python、ODBC(基于c/c++的数据库标准接口)

Hive架构
在这里插入图片描述
MetaStore : 存储表、列和Partition等元数据,存放在关系型数据库中(MySQL或Derby )。
Driver : 管理HiveQL执行的生命周期,并贯穿Hive任务整个执行期间。(将HiveQL语句翻译解析成不同执行任务存放在HDFS中,交由M/R执行业务逻辑。)
Compiler : 编译HiveQL并将其转化为一系列相互依赖的Map/Reduce任务。(用户 编写HQL语言,由compiler编译转化为M/R任务来执行查询)
Optimizer : 优化器,分为逻辑优化器和物理优化器,分别对HiveQL生成的执行计划和MapReduce任务进行优化。
Executor : 按照任务的依赖关系分别执行Map/Reduce任务。
ThriftServer : 提供thrift接口,作为JDBC和ODBC的服务端,并将Hive和其他应用程序集成起来。(将数据仓库的数据提供给用户)
Clients : 包含命令行接口(CLI/Beeline) 和JDBC/ODBC 接口,为用户访问提供接口。

Hive数据存储模型
数据库:在hdfs中表现为一个目录(/usr/hive/warehouse/)
数据表:表对应的是一个目录。外部表、内部表
桶:表目录下的多个文件,数据可以根据桶的方式将不同数据放入不同的桶中,建表时指定桶的个数,桶内可排序。(数据按照某个字段的值Hash后放入某个桶中)。可以提高查询效率
分区:表目录下的子目录,数据表可以按照某个字段的值划分分区(将大的数据集根据业务需求划分成不同的分区,作用是筛选数据集)。
倾斜数据:某一项数据特别得多,导致某个节点处理数据的速度特别慢
正常数据:正常处理的数据

Hive shell窗口(类SQL语言)
查看数据库:show databases;
创建数据库:create database myhive;使用数据库:use myhive;
查看表的属性结构:desc tablename;

Hive数据存储模型:托管表(内部表)和外部表
托管表:默认创建托管表,hive会将数据移到数据仓库目录(做了一个数据移动,将hdfs中的数据移动到数据仓库目录下)。删除的时候元数据和数据会一起删除。
创建外部表:hive会到仓库目录以外的位置访问数据。删除外部表,只会删除元数据。
表的建议使用:如果所有处理都由hive完后,建议使用托管表。如果要用hive和其他工具来处理同一个数据集,建议使用外部表。

创建托管表:
create table if not exists example.employee(……)
row format delimited fields terminated by ‘,’(以逗号作为分隔符)
stored as textfile;(以文本形式进行存储)
创建外部表:
create external table if not exists example.employee(……)
row format delimited fields terminated by ‘,’(以逗号作为分隔符)
stored as textfile location “/local”(指定外部存储位置);

hive支持的函数:
数学函数(round(),floor(),abs())
日期函数(to_date()……)
字符串函数(length()……)
自定义函数(UDF)

设置成本地模式(数据操作量比较小,而检索hive的时间比较长,可以将数据设置成本地模式)
set hive.exec.mode.local.auto=true

Hive增强特性
colocation(同分布):将存在关联的数据或可能要进行关联的操作的数据储存在相同的储存节点上
列加密:Hive支持对表的某一列或多列进行加密。
Hbase记录批量删除:在Hive on HBase功能中,FusionInsight HD Hive提供了对HBase表的单条数据的删除功能,通过特定的语法,Hive可以将HBase表中符合条件的一条或者多条数据批量清除。
控流特性:避免客户端请求数过多,对服务端造成重启,需要做服务端流控。
指定行分隔符:Hive以文本文件存储的表会以回车作为其行分隔符,即在查询过程中,以回车符作为一行表数据的结束符(STORED AS inputformat “org.apache.hadoop.hive.contrib.fileformat.SpecifiedDelimiterInputFormat”
outputformat “org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat”;

Hive SQL
DDL(数据定义语言):建表、修改表、删表、分区、数据类型
DML(数据管理语言):数据导入、数据导出
DQL(数据查询语言):简单查询、复杂查询

HBase

在这里插入图片描述
HBase在FusionInsihgt当中与HDFS,ZooKeeper等组件皆为基础组件,HBase提供海量数据存储,Hive、Spark等组件也皆有基于HBase做上层分析的应用实践。

HBase是一种高可靠、高性能、面向列,可伸缩的分布式储存系统。

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

HBase适用场景
海量数据、不需要完全拥有传统关系型数据库所具备的ACID(事物的四个特性:原子性、一致性、独立性及持久性。)、高吞吐量、需要在海量数据中实现高效的随机读取、需要很好的性能伸缩能力、能够同时处理结构化和非结构化数据。

HBase面向列储存,数据以列为单位,储存在底层文件系统中。有利于面向单列数据的读取、统计操作,缺点是整行读取时,可能需要多次I/O操作。

KeyValue储存模型:
在这里插入图片描述

  • KeyValue具有特定的结构。Key部分被用来快速的检索一条数据记录,Value部分用来存储实际的用户数据信息。
  • KeyValue作为承载用户数据的基本单元,需要保存一些对自身的描述信息,例如,时间戳,类型等等。那么,势必会有一定的结构化空间开销。
  • 支持动态增加列,容易适应数据类型和结构的变化。以块为单元操作数据,列间、表间并无关联关系。
  • KeyValue型数据库数据分区方式是按key值连续范围分区。(数据按照RowKey的范围(按RowKey的字典顺序),划分为一个个的子区间。每一个子区间都是一个分布式存储的基本单元。)
  • HBase的底层数据以KeyValue的形式存在,KeyValue具有特定的格式。
  • KeyValue中拥有时间戳、类型等关键信息。
  • 同一个Key值可以关联多个Value,每一个KeyValue都拥有一个Qualifier标识。
  • 即使是Key值相同,Qualifier也相同的多个KeyValue,也可能有多个,此时使用时间戳来区分,这就是同一条数据记录的多版本。

HBase架构
一个master主服务器:
(1).负责管理和维护HBase表的分区信息(一个表的region信息)
(2).维护region服务器列表
(3).分配region,负载均衡
许多个region服务器:存储维护分配给自己的region。
zookeeper:保证集群中只有一个active的master。
client:客户端直接和region服务器进行沟通,通过zookeeper向master寻找region相关信息。
在这里插入图片描述

  • zookeeper为HBase集群中个进程提供分布式协作服务。各RegionServer(region服务器)将自己的信息注册到zookeeper中,主Master据此感知各个RegionServer的状态。

  • Client使用HBase的RPC机制与Master、RegionServer进行通信。Client与Master进行管理类通信,与RegionServer进行数据操作类通信。

  • RegionServer负责提供表数据读写等服务,是HBase的数据处理和计算单元。RegionServer一般与HDFS集群的DataNode部署在一起,实现数据的存储功能。

  • HMaster,在HA模式下,包含主用Master和备用Master。

  • 主用Master :负责HBase中RegionServer的管理,包括表的增删改查;RegionServer的负载均衡,Region分布调整;Region分裂以及分裂后的Region分配;RegionServer失效后的Region迁移等。

  • 备用Master:当主用Master故障时,备用Master将取代主用Master对外提供服务。故障恢复后,原主用Master降为备用。

  • HDFS为HBase提供高可靠的文件存储服务,HBase的数据全部存储在HDFS中。
    在这里插入图片描述

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

  • Store:一个Region由一个或多个Store组成,(一个族(columns family)对应一个store)

  • MemStore:一个Store包含一个MemStore,MemStore缓存客户端向Region插入的数据。

  • StoreFile:MemStore的数据flush到HDFS后成为StoreFile。随着数据的插入,StoreFile的数量不断增加,RegionServer会进行StoreFile的合并。

  • Hfile:HFile定义了StoreFile在文件系统中的存储格式,它是当前HBase系统中StoreFile的具体实现。

  • Hlog:HLog日志保证了当RegionServer故障的情况下用户写入的数据不丢失,RegionServer的多个Region共享一个相同的Hlog。往Memstore写入数据的同时也会往Hlog写入,防止断电导致内存中的数据清零的情况。

  • Region:最开始HBase中只有一个Region,在数据量达到一定阈值的时候,region会发生分裂。分裂的时候会暂停读写服务。Region是HBase分布式存储的最基本单元。
    region分为元数据region和用户region两类:
    (meta region):记录user region的路由信息(存储了region和region服务器的映射关系)
    root表:存储在zookeeper上(只有一个),meta region当HBase上的数据量很大的话,会被分为多个region,这些多个meta region地址存储在root表上
    读写region数据的路由
    (1)找root表
    (2)找meta region的地址
    (3)由meta region找寻user region地址

在这里插入图片描述
ColumnFamily列族,支持动态扩展。HBase中表的列非常稀疏,不同行的列的个数和类型都可以不同。

ZooKeeper为HBase 提供:

  • 分布式锁的服务
    多个HMaster进程都尝试着去ZooKeeper中写入一个对应的节点,该节点只能被一个HMaster进程创建成功,创建成功的HMaster进程就是Active。
  • 事件监听机制
    主HMaster进程宕掉之后,备HMaster在监听对应的ZooKeeper节点。主HMaster进程宕掉之后,该节点会被删除,其它的备HMaster就可以收到相应的消息。
  • 微型数据库角色
    ZooKeeper中存放了metaRegion地址信息的root表,此时,可以将它理解成一个微型数据库。

元数据表
元数据表记录用户region信息,用来帮助client定位到具体的region。
元数据表也会被切分为多个Region,Region的元数据信息保存在ZooKeeper中。

flush 下刷
数据写入先写到memstrore(内存缓冲区),再写到storefile里(持久化到磁盘)。
在这里插入图片描述
compaction(合并)
为了减少同一个region中同一个store中storefile的数目,从而提升读取的性能。
Compaction分为Minor、Major两类:

  • Minor:小范围的Compaction。有最少和最大文件数目限制。通常会选择一些连续时间范围的小文件进行合并。
  • Major:涉及该Region该ColumnFamily下面的所有的HFile文件。

region split
一个表最开始只有一个region,随着数据量变大,当一个region里的数据量大于之前所设定的阈值(10g),region会进行split。好处是负载均衡,充分利用hdfs的特性(分布式)。

读数据:(get方式,精确查找,scan,范围查找)
根据rowkey范围——》找到region——》找到region server——》请求发送到RegionServer,由其具体处理数据读取 -> 数据读取返回到客户端。
写流程
(1).client发起写入数据的请求
(2).通过zookeeper中的root表找到对应的meta region表。meta region中记载各个user region信息(region所在的region server的rowkey范围,)找到要写入的region所在的regionserver——>先按照region进行打包(rowkey),再根据region server进行打包——>发送到相应的region server——>由该RegionServer具体处理数据写入。
写流程的数据分组:

  1. 根据meta表找到表的region信息,此时也得到了对应的regionserver信息。即找到每个region都在哪个regionserver上。
  2. 每个RegionServer上的数据会一起发送。发送数据中,都是已经按照Region分好组了。

OpenScanner
OpenScanner的过程中,会创建两种不同的Scanner来读取Hfile、 MemStore的数据:

  1. HFile对应的Scanner为StoreFileScanner。
  2. MemStore对应的Scanner为MemStoreScanner。
    在寻找到rowkey所对应的RegionServer和Region之后,需要打开一个查找器Scanner,由其具体执行查找数据,Region中会包含内存数据MemStore,文件数据Hfiles,那么在open scanner的时候就需要分别读取这两块数据,打开对应不同的scanner做查询操作。

Filter(过滤器)
Filter允许在Scan过程中,设定一定的过滤条件。符合条件的用户数据才返回。

HBase最小存储单元是cell

华为增强特性:

  • 支持二级索引 :二级索引就是把要查找的列与rowkey关联成一个索引表。此时列成新的rowkey,原rowkey成为value。其实就是查询了2次。
  • hfs(HBase FileStream,HBase文件存储模块)是HBase的独立模块,是对HBase与HDFS接口的封装,应用于FusionInsight HD的上层应用,为上层应用提供文件的存储、读取、删除等功能。
  • HBase MOB:MOB数据(即100KB到10MB大小的数据)直接以HFile的格式储存在文件系统上,然后把这个文件的地址信息及大小信息作为value储存在普通的HBase的store上,通过工具集中管理这些文件。这样就可以大大降低HBase的compation和split频率,提升性能。
  • 在实际应用中,用户需要存储大大小小的数据,比如图像数据、文档。小于10MB的数据一般都可以存储在HBase上,对于小于100KB的数据,HBase的读写性能是最优的。如果存放在HBase的数据大于100KB甚至到10MB时,插入同样个数的数据文件,其数据量很大,会导致频繁的compaction和split,占用很多CPU,磁盘IO频率很高,性能严重下降。
  • MOB模块表示存储在HRegionServer上的mobstore,mobstore存储的是key-value,key即为HBase中对应的key,value对应的就是存储在文件系统上的引用地址以及数据偏移量。读取数据时,mobstore会用自己的scanner,先读取mobstore中的key-value数据对象,然后通过value中的地址及数据大小信息,从文件系统中读取真正的数据。
    在这里插入图片描述

Flume

Flume是开源流式日志采集工具。是一个分布式、可靠和高可用的海量日志聚合的系统,支持在系统中定制各种数据发送方,用于收集日志,同时,Flume提供对数据进行简单处理,并写到各种数据接收方。
Flume提供从本地文件(spooling directory source)、实时日志(taildir、exec)、REST消息、 Thrift 、Avro、Syslog、Kafka等数据源上收集数据的能力。

Flume架构
Flume基础架构:Flume可以单节点直接采集数据,主要应用于集群内数据:
在这里插入图片描述
Flume多agent架构:Flume可以将多个节点连接起来,将最初的数据源经过收集,储存到最终的储存系统中。主要应用于集群外的数据导入到集群中:
在这里插入图片描述

在这里插入图片描述

  • source:数据源,是产生日志信息的源头,flume会将原始数据建模抽象成自己处理的数据对象:event。
  • Channel Processor:通道处理器,主要作用是将source发过来的数据放入通道(channel)中。
  • Interceptor:拦截器,主要作用是将采集到的数据根据用户的配置进行过滤、修饰。
  • Channel Selector:通道选择器,主要作用是根据用户的配置将数据放到不同的通道中去。
  • Channel:通道,用于临时缓存数据。
  • Sink Runner:Sink运行器,主要作用是通过它来驱动Sink Processor,Sink Processor驱动sink来从channel中取数据。
  • Sink Processor:sink处理器,主要根据配置使用不同的策略驱动sink从channel中取数据,目前策略有:负载均衡、故障转移、直通。
  • Sink:主要作用是从channel中取数据并将数据放到不同的目的地。
  • event:一个数据单元,带有一个可选的消息头,Flume传输的数据基本单位是event,如果是文本文件,通常是一行记录,这也是事务的基本单位。
  • Event 从 Source,流向 Channel,再到 Sink,event本身为一个 byte 数组,并可携带 headers 信息。event代表着一个数据流的最小完整单元,从外部数据源来,流向最终目的。

source
source负责接收或通过特殊机制产生events,并将events批量放到一个或多个channels,有驱动和轮询两种方式:

  • 驱动型source:是外部数据主动发送给Flume,驱动Flume接收数据。
  • 轮询source:是Flume周期性主动获取数据。
    source必须至少和一个channel关联。
source类型说明
exec source执行某个命令或脚本,并将执行的结果输出作为数据源
avro source提供一个基于arvo协议的server,bind到某个端口上,等待avro协议客户端发过来的数据
thrift source同avro,不过传输协议为thrift
HTTP source支持http的post发送数据
syslog source采集系统syslog
spooling directory source采集本地静态文件
jms source从消息队列中获取数据
kafka source从kafka中获取数据

channel
channel位于source和sink之间,channel的作用类似于队列,用于临时缓存进来的events,当sink成功地将events发送到下一跳的channel或最终目的,events从channel移除。
不同channel提供的持久化水平是不一样的:

  • memory channel:不会持久化,提供高吞吐。
  • file channel:基于WAL(预写式日志Write-Ahead Log)实现。但是配置较为麻烦,需要配置数据目录和checkpoint目录;不同的file channel均需要配置一个checkpoint 目录。
  • JDBC channel:基于嵌入式database实现。内置的derby数据库,对event进行了持久化,提供高可靠性;可以取代同样具有持久特性的file channel。
    channel支持事务,提供较弱的顺序保证,可以连接任何数量的source和sink。
  • Channels支持事务:Flume的channel数据在传输到下个环节(通常是批量数据),如果出现异常,则回滚这一批数据,数据还存在channel中,等待下一次重新处理。

Sink
Sink负责将events传输到下一跳或最终目的,成功完成后将events从channel移除。
必须作用于一个确切的channel。

Sink类型说明
hdfs sink将数据写到hdfs上
avro sink使用avro协议将数据发送给另下一条的Flume
thift sink同avro,不过传输协议为thrift。
file roll sink将数据保存在本地文件系统中
HBASE sink将数据写入到HBASE
kafka sink将数据写入到kafka中
MorphlineSolr sink将数据写入到solr中

Flume关键特性:

  • 支持采集日志文件
  • 支持多级级联和多路复用:支持将多个Flume级联起来,同时级联节点内部支持多路复用。
  • 级联消息压缩、加密:节点之间数据传输支持压缩和加密,提升数据传输效率和安全性。
  • 数据监控:FusionInsight Manager,Flume source接受数据量、channel缓存数据量、sink写入数据量,通过Manager图形化呈现监控指标。
  • 传输可靠性:在数据传输过程中,采用事务管理方式(事件采集或发送失败,会重新采集或发送。),保证传输过程中的数据不会丢失,增强了数据传输的可靠性,同时缓存在channel中的数据如果采用file channel,进程或者节点重启数据不会丢失。
  • 传输可靠性:在数据传输过程中,如果下一跳的Flume节点故障或者数据接收异常时,可以自动切换到另一路上自动传输。
  • 传输过程中数据过滤:Flume支持第三方过滤插件调用。
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
可定制:因为能设置source类型和sink类型

Streaming(实时,storm)

在这里插入图片描述

Streaming基于开源Strom,是一个分布式,实时计算框架。
Streaming具有以下几种特点:实时响应、低延迟;数据不出储存、先计算;连续查询;事件驱动。

批处理和流式计算区别(本质上是一样的,时间跨度不一样):
批处理数据是有界的,通常是使用储存在硬件上的数据。
流处理处理的数据是无界的,真正的实时(来一条处理一条)。

SparkStreaming和Streaming区别
任务执行方式:SparkStreaming执行逻辑即时启动,运行完回收。Streaming执行逻辑预先启动,持续存在。
时间处理方式:SparkStreaming时间积累到一定量在处理(微批),Streaming事件实时处理
时延:SparkStreaming秒级,Streaming毫秒级
吞吐量:SparkStreaming高(约为Streaming的2~5倍),Streaming较高

streaming架构

  • Topology:Streaming中运行的一个实时应用程序。
  • Nimbus:负责资源分配和任务调度(再集群中分发代码)。
  • Supervisor:每个负责接受Nimbus分配的任务,启动和停止属于自己管理的worker进程。
  • Worker:Topology运行时的物理进程。每个Worker是一个JVM进程。
  • Spout(数据采集器):在一个Topology中产生源数据流的组件。
  • Bolt(数据处理器):接收数据执行处理的组件。
  • task:worker中每一个Spout/Bolt的线程称为一个task
  • Tuple:Streaming的核心数据结构,是消息传递的基本单元,不可变key-value对,这些Tuple会以一种分布式的方式进行创建和处理。
  • Stream:一个无边界的连续Tuple序列。
  • Zookeeper:为Streaming服务中的进程提供分布式协作服务。Nimbus、Supervisor、Worker将自己的信息注册到ZooKeeper中,Nimbus据此感知各个角色的健康状态。Nimbus生成的任务清单会提交给ZK,ZK上有专门的目录存放任务,每个supervisor会监控该目录。
  • Topology是由一组Spout(数据源)组件和Bolt组件通过Stream Groupings(消息分组方式:声明Bolt接受什么样的流作为数据输入)进行连接的有向无环图(DAG)。Topology一旦生成会一直执行,直到被kill。
  • Stream groupings声明每个Bolt接受怎样的流作为输入,Stream grouping定义一个Stream(流)应该如何分配给该Bolt上面的多个Task。

Worker介绍
一个Worker是一个JVM进程,所有的Topology都是在一个或多个worker中运行的。Worker进程的个数取决于Topology的设置。具体可获得调度并启动的Worker个数则取决于Supervisor配置的slot个数。(每一个Worker进程启动时需要一个端口号,即slot,因此每启动一个Worker就消耗掉一个slot。)在一个单独的Worker进程中会运行一个或多个Executor线程,每个Executor只能运行Spout或者Bolt的一个或多个task实例。Task是最终完成数据处理的实体单元。

Task介绍
Topology里的每一个Component(Spout/Bolt)节点都是并行的。在Topology里面,可以指定每个节点的并发度,Streaming则会在集群里面分配相应的task来同时计算,以增强系统的处理能力。Task就是具体的处理逻辑对象, 一个executor线程可以执行一个或多个tasks,但一般默认每个executor只执行一个task, 所以我们往往认为task就是执行线程, 其实不然,task代表最大并发度,一个component的task数是不会改变的, 但是一个componet的executer数目是会发生变化的,当task数大于executor数时, executor数代表实际并发数。

  • Spout和Bolt的并发度,指的是Spout和Bolt中的Task个数。

消息分发策略

分组方式功能
fieldsGrouping(字段分组)按照消息的哈希值分组发送给目标Bolt的Task
globalGrouping(全局分组)所有消息都发送给目标Bolt固定的一个Task
shuffleGrouping(随机分组)消息发送给目标Bolt的随机一个task。
localOrShuffleGrouping(本地或者随机分组)如果目标Bolt在同一工作进程存在一个或多个Task,数据会随机分配给这些Task。否则,该分组方式与随机分组方式相同。
allGrouping(广播分组)消息群发给目标Bolt的所有Task。
directGrouping(直接分组)由数据生产者决定数据发送给目标Bolt的哪一个Task。需在发送时使用emitDirect(taskID, tuple)接口指定TaskID。
partialKeyGrouping(局部字段分组)更均衡的字段分组。
noneGrouping(不分组)当前和随机分组相同。

消息分发策略的指定需要在开发阶段使用API来指定。

Streaming关键特性

  • Nimbus HA:使用zookeeper分布式锁实现,主备Nimbus之间会周期性的同步元数据,保证在发生主备切换后拓扑数据不丢失,业务不受损。解决Nimbus单点问题。

  • 容灾能力:节点失效,自动迁移到正常节点,业务不中断。无需人工干预。

  • 消息可靠性
    在这里插入图片描述
    在streaming里面一个tuple被完全处理的意思是:这个tuple以及由这个tuple所派生的所有的tuple都被成功处理。如果这个消息在Timeout所指定的时间内没有成功处理,这个tuple就被认为处理失败了。

  • Streaming里面有一类特殊的task称为:acker, 他们负责跟踪spout发出的每一个tuple的tuple树。当acker发现一个tuple树已经处理完成了。它会发送一个消息给产生这个tuple 的那个task。在spout中发射一个新的源tuple时为其指定一个64位的message id,acker跟踪这个消息ID。

  • acker所参与的工作流程:

  1. Spout创建一个新的Tuple时,会发一个消息通知acker去跟踪。
  2. Bolt在处理Tuple成功或失败后,也会发一个消息通知acker。
  3. acker会找到发射该Tuple的Spout,回调其ack或fail方法。

ACK机制
在这里插入图片描述

  • Spout发送一个Tuple时,会通知Acker一个新的根消息产生了,Acker会创建一个新的tuple tree,并初始化校验和为0。
  • Bolt发送消息时向Acker发送anchor tuple,刷新tuple tree,并在发送成功后向Acker反馈结果。如果成功则重新刷新校验和,如果失败则Acker会立即通知Spout处理失败。
  • 当tuple tree被完全处理(校验和为0),Acker会通知Spout处理成功。
  • Spout提供ack()和fail()接口方法用于处理Acker的反馈结果,需要用户实现。一般在fail()方法中实现消息重发逻辑。
  • Spout在初始化时会产生一个tasksId。
  • Spout中创建新的Tuple,其id是一个64位的随机数。
  • Spout将新建的Tuple发送出去(给出了messageId来开启Tuple的追踪), 同时会发送一个消息到某个acker,要求acker进行追踪。该消息包含两部分:
  1. Spout的taskId:用户acker在整个Tuple树被完全处理后找到原始的Spout进行回调ack或fail。
  2. 一个64位的ack val值: 标志该tuple是否被完全处理。初始值为0。
  • 简单的说就是伴随tuple有个id,在整个Topology中每个处理步骤都会生产新的id。接收到的id与新id做异或,如果为0则成功,不为0则调用fail函数处理。
  • 一个Bolt在处理完Tuple后,如果发射了一个新的anchor tuple,Streaming会维护anchor tuple的列表。
  • 该Bolt调用OutputCollector.ack()时,Streaming会做如下操作:
  1. 将anchor tuple列表中每个已经ack过的和新创建的Tuple的id做异或(XOR)。假定Spout发出的TupleID是tuple-id-0,该Bolt新生成的TupleID为tuple-id-1,那么,tuple-id-0XOR tuple-id-1。
  2. Streaming根据该原始TupleID进行一致性hash算法,找到最开始Spout发送的那个acker,然后把上面异或后得出的ack val值发送给acker。
  • acker收到新的ack val值后,与保存的原始的Tuple的id进行异或,如果为0,表示该Tuple已被完全处理,则根据其taskId找到原始的Spout,回调其ack()方法。
  • fail的机制类似,在发现fail后直接回调Spout的fail方法。

streaming处理消息的可靠性机制:
(1)worker宕掉,nimbus会协调supervisor去重启worker
(2)supervisor宕掉,nimbus会直接启动任务,迁移到其他supervisor上继续运行
(3)nimbus宕掉,如果有新的业务提交的话,没办法处理,supervisor没办法做相应的业务请求。对于已经在运行的业务没有影响(HA—>zookeeper)

StreamCQL
StreamCQL是建立在分布式流处理平台基础上的查询语言(CQL),架构支持构建在多种流处理引擎之上,目前主要适配StreamCQL。StreamCQL使用类SQL语言开发业务,语法基本通用。开发方式上比原生API更加简练,且不依赖任何编程工具。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

kafka

在这里插入图片描述

Kafka是高吞吐、分布式、基于发布(生产者)订阅(消费者)的消息系统(服务器不会主动地发消息给消费者,消费者主动的将消息拉取过来,主动进行消费消息)。利用Kafka可以再廉价的pc server上搭建起大规模的消息系统。

kafka应用场景
Kafka和其他组件比较,具有消息持久化、高吞吐、实时等特性,适用于离线(异步)和实时(同步)的消息消费,如网站活性跟踪、聚合统计系统运营数据(监控数据)、日志收集等大量数据的数据收集场景。

kafka架构
**加粗样式**
一个典型的kafka集群包括若干producer(可以是web前端产生的page view,或者是服务器日志,系统cpu,memory等),若干broker(kafka支持水平扩展,一般broker数量越多,集群吞吐量越高),若干consumer么人,以及zookeeper集群。
kafka通过zookeeper管理集群配置,选举leader,以及在consumer发生变化时进行rebalance。

spark90%的数据来源是kafka。
理解kafka:消息队列,消息缓冲区,producer(生产者)——》broker(kafka)——》consumer(消费者)生产者和消费者之间可以异步进行。【kafka之间也需要zookeeper进行协调工作,zookeeper可以判断kafka节点是否正常运行】
应用场景:消息持久化、高吞吐、实时等特性,适用于离线和实时消息消费。

kafka topics(一类消息)
producer往broker里push消息时,要带上topic,用于区分不同类别的消息。consumer使用offset(偏移量)来记录读取位置。

kafka partition

  • 每个topic都有一个或多个partition构成,partition机制的存在可以让我们对同一个topic进行并行访问,从而提高kafka的吞吐量。partition是topic物理上的分组,每个partition在储存层面对应一个log文件。
  • topic的partition数量可以在创建时配置。
  • 消费者:消费者访问kafka,需要有一个group来管理,同一个消费组里的消费者的业务逻辑相同(即访问相同topic中的数据)。

kafka partition偏移量
每条消息在文件中的位置称为offset(偏移量),他唯一标记一条消息,消费者通过(topic、partition、offset)跟踪数据。
producer向kafka中发送数据时,有一个自增序列,所以producer不需要管理kafka,kafka自己会进行负载均衡。
创建topic时,会在配置文件中指定有多少个partition,这个配置文件在运行中也可修改。

kafka partition副本:提高kafka的容错能力

  • 副本以分区为单位
  • 主副本叫做leader,从副本叫做follower。follower通过拉取的方式从leader中同步数据。
  • 消费者和生产者都是从leader中读取数据,不与follower进行交互。
  • 副本机制,对外提供服务的前提是follower和leader同步完成,如果follower落后太多,leader就会把follower从follower的列表中移除

在kafka集群里有很多broker,很多broker中的(相同的partition之间)会选举出一个leader(producer向leader中push数据之后,leader会往本地log写入)(还有一个follower(主动地向leader中定期拉取数据,拉取数据后写入本地log,然后会向leader发送一个ack确认,leader在收到所有follower的ack反馈之后,向producer发送一个ack),用于进行数据同步,防止leader宕掉),往partition里读写数据就要和leader进行连接。

  • kafka把leader分散到多个节点上,为了分散集群上节点的压力(防止某个节点压力越大)。

kafka logs

  • 一个partition就是一个log(逻辑上的,partition有自己的命名规则:topic名加序列号),topic中一个partition大文件分成多个小文件段(segment file,大小是固定的,为1G,为了进一步增加读写效率(感觉很像HBase的region)),通过多个小文件段,就容易定期清除或删除已消费完的文件,减少磁盘占用。
  • segment file组成:由2大部分组成,分别为index file和data file,此2个文件一 一对应,成对出现,后缀“.index”和“.log”分别表示为segment索引文件、数据文件。
  • segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件的最大offset(偏移message数)。数值最大为64位long大小,19位数字字符长度,没有数字用0填充。
  • Topic的每个分区对应一个逻辑日志。物理上,一个日志为相同大小的一组分段文件。
  • 同一个topic下有不同分区,每个分区下面会划分为多个文件,只有一个当前文件(位于内存)在写,其他文件(位于磁盘)只读。当写满一个文件(写满的意思是达到设定值)后,文件写入磁盘,新建一个空文件用来写,老的文件切换为只读。
  • 一个日志文件默认1G,当达到1G的时候,创建新的log文件和index文件。如果参数设置过小,则会产生大量的log文件和index文件,系统在启动时,需要加载大量index到内存,占用大量句柄。如果设置太大,分段文件比较少,不利于快速查找消息。
  • producer往partition里写数据,相当于往segmentfile里写数据,用于写入消息的segmentfile存在于内存,当数据写满1G或到达某个时间片,segmentfile会下刷到磁盘,consumer只会消费持久化到磁盘的数据。
    一个segmentfile本质是由两个文件组成(索引文件(index文件),即元数据信息(index元数据全部映射到memory,可以避免segment file的index数据IO磁盘操作。);数据文件(log文件))
  • 稀疏存储:隔一定字节的数据记录数据索引位置(可以减少索引文件的内存占用)。

kafka log cleanup
日志的清理方式有两种:delete和compact(默认是delete)。

  • compact(压缩):保留数据最新状况(每个key-value对,一个key对应多个value,删除老的value,保留新的value)

kafka数据可靠性

  • kafka消息传输机制:
    最多一次:消息可能丢失,消息不会重复发送和处理
    最少一次:消息不会丢失,消息可能重复发送和处理
    仅有一次:消息不会丢失,消息仅被处理一次(master确认收到)
  • 消息不丢失
    消息发布订阅两种方式:同步、异步
    ack响应:三个状态值。
    0:生产者只管发送数据,并不关心数据是否丢失
    1:partition中的leader收到数据,回复ack
    -1:所有的follower都收到数据,回复ack
  1. 如果broker端一直不给ack状态,producer永远不知道消息发送是否成功:
    producer可以设置一个超时机制,超出这一时间认定失败
  2. 如果一条消息发送一次就得到一次ack响应,则在大量消息发送的情况下,会占据大量带宽:
    生产者先把数据缓存在producer端,在达到一定阈值后,或一定时间后再发送(500s)
  3. 如果在producer端设置了缓冲区,如果broker不响应buffer中的数据,buffer满了,producer又要去生产数据,producer会选择清空buffer。
  4. 同步模式:
    生产者等待10s,如果broker没有给出ack响应。就认为失败
    生产者重发3次,如果没有响应,就报错
  5. 异步模式
    先把数据保存在生产者的buffer中,buffer中数据满足阈值,就可以发送数据,发送一批数据的大小是500条,如果broker迟迟不给ack,而buffer中满了,生产者需要生产数据,则生产者可以选择清空buffer中的数据。

kafka cluster mirroring(kafka跨集群数据同步方案)
producer1——》broker1——》consumer2——》producer2——》broker2(1指集群1,2指集群2)

  • producer写数据:
    Producer连接任意存活的Broker,请求制定Topic、Partition的Leader元数据信息,然后直接与对应的Broker直接连接,发布数据。
  • consumer读数据:
    Consumer连接指定TopicPartition所在的LeaderBroker,用主动获取方式从Kafka中获取消息。

producer生产了100条数据,cosumer怎么保证顺序读出这一百条数据:
comsumer先开起来,消息一往leader上发——>内存只要follower同步了——>ack——>comsumer可以订阅消息

producer先开起来,consumer会按partition顺序读取数据,这样不能保证是按顺序读的
如果是comsumer group,多个comsumer读取不同的partition。

producer以键值对进行发送,会以hash算法进行发送。
不以键值对的方式进行发送,会议轮询方式进行发送。

kafkaconsumer多线程
KafkaConsumer不是线程安全的,在使用中必须确保线程安全。
写n个内存队列,具有相同key的数据写入到同一个内存队列,对于多线程,每个线程消费一个队列就能保证线程安全。(comsumer中有多个线程,每个线程都维护专属的kafkaconsumer)

comsumer端消息不丢失
offset:offset存在

为什么要将文件进行切分:
kafka作为消息中间件,对数据进行临时存储,并不是永久存储,对文件进行切分更方便清理过期数据。

flink

flink是业界最顶级的开源流处理引擎,与storm类似,属于事件驱动型实时流处理引擎。
批处理和流处理都可以做
实时三大引擎:spark、streaming、flink。
在数据量能达到TB级别的同时,能做到高吞吐、低延迟。
特点:流处理、容错,可靠性、可扩展性(Scalable)、高吞吐量,低延迟
应用场景:高并发处理数据,时延毫秒级,兼并可靠性。互联网金融业务,点击流日志处理,舆情监控。
关键特性
exactly once:提供异步快照机制,保证所有数据真正只处理一次。
HA(jobmanager支持主备模式)、水平扩展能力(taskmanager支持手动水平扩展)
hadoop兼容性
支持yarn,能够从HDFS、HBase中读取数据。能够使用所有的Hadoop的格式化输入和输出;
能够使用Hadoop原有的Mappers和Reducers,并且能与Flink的操作混合使用;
能够更快的运行Hadoop的作业。

Flink架构
在这里插入图片描述

  • Data storage底层是数据存储
  • Single node execution表示的是部署方式
  • Local Environment等表示的是不同的运行环境
  • Flink Local Runtime表示是运行线程
  • Flink Optimizer,Flink Stream Builder等表示的是优化器
  • Common API表示的是Flink平台的API
  • Scala API和Java API表示的是对外提供的API

Flink技术栈
在这里插入图片描述

  • Flink提供了三种部署方式:local、cluster、cloud,即,本地部署、集群部署和云部署
  • Runtime层是Flink流处理及批处理公用的一个引擎,以jobGraph的形式接收程序。jobGraph即一个一般化的并行数据流图(data flow),它拥有任意数量的task来接收和产生data stream
  • DataStream API和DataSet API都会使用单独编译的处理方式生成JobGraph。DataSet API使用optimizer来决定针对程序的优化方法,而DataStream API则使用stream builder来完成该任务。
  • Libraries层对应的是Flink不同的API对应的一些功能:处理逻辑表查询的Table,机器学习的FlinkML,图像处理的Gelly,复杂事件处理的CEP。

flink核心概念:Datastream
用来表示程序中的流式数据。用户可以认为他们是含有重复数据的不可修改的集合,Datastream中的元素数量是无限的。
在这里插入图片描述
data source:流数据的接入。支持HDFS文件、kafka、文本数据等。
transformations:流数据转换
data sink:数据输出。支持HDFS、kafka、文本等。

Flink数据源
批处理:files、JDBC、HBase、Collections
流处理:Files、Socket Streams、Kafka、RabbitMQ、Flume、Collections

DataStream Transformation
public SingleOutputStreamOperator map(MapFunction<T, R> mapper)
public SingleOutputStreamOperator flatMap(FlatMapFunction<T, R> flatMapper)
public SingleOutputStreamOperator filter(FilterFunction filter)
public KeyedStream<T, Tuple> keyBy(int… fields)
public DataStream partitionCustom(Partitioner partitioner, int field)
public DataStream rebalance()
public DataStream shuffle()
public DataStream broadcast()
public SingleOutputStreamOperator project(int… fieldIndexes)

三种架构方式:
standalone(单节点)、yarn(集群)、cloud(云端)

flink应用运行流程-关键角色

  • client:需求提出方,负责提交需求,构造流图
  • jobmanager(AM(yarn)):负责应用的资源管理,根据应用的需要,向资源管理部门(ResourceManager)申请资源。
  • yarn的resourcemanager:资源管理部门,负责整个集群的资源统一调度和分配。
  • taskmanager:负责实际计算工作,一个应用会分拆给多个TaskManager来进行计算。
  • TaskSlot(任务槽)类似yarn中的container用于资源隔离,但是该组件只包含内存资源,不包含cpu资源。每一个TaskManager当中包含3个Task Slot,TaskManager最多能同时并发执行的任务是可以控制的,那就是3个,因为不能超过slot的数量。 slot有独占的内存空间,这样在一个TaskManager中可以运行多个不同的作业,作业之间不受影响。slot之间可以共享JVM资源, 可以共享Dataset和数据结构,也可以通过多路复用(Multiplexing) 共享TCP连接和心跳消息(Heatbeat Message)。

flink on yarn
靠yarn来做资源的申请和调度

  1. Flink yarn Client首先检验是否有足够的资源 来启动YARN集群,如果资源足够,会将jar包、配置文件等上传到HDFS。
  2. Flink YARN Client首先与YARN Resource Manager进行通信,申请启动ApplicationMaster(以下简称AM)。在Flink YARN的集群中,AM与Flink JobManager在同一个Container中。
  3. AM在启动的过程中会和YARN的RM进行交互,向RM申请需要的Task ManagerContainer,申请到Task Manager Container后,在对应的NodeManager节点上启动TaskManager进程。
  4. AM与Fink JobManager在同一个container中,AM会将JobManager的RPC地址通过HDFS共享的方式通知各个TaskManager,TaskManager启动成功后,会向JobManager注册。
  5. 等所有TaskManager都向JobManager注册成功后,Flink基于YARN的集群启动成功,Flink YARN Client就可以提交Flink Job到Flink JobManager,并进行后续的映射、调度和计算处理。

Flink原理

  • 用户实现flink程序由stream数据和transformation算子组成。
  • source(整个数据流的入口)操作载入数据,经过map()、keyby()等transformation操作符处理stream,数据处理完成后,调用sink(流数据出口)写入相关存储系统(hdfs、hbase、kafka)
  • Flink程序执行时,它会被映射为Streaming Dataflow。一个Streaming Dataflow是由一组Stream和Transformation Operator组成,它类似于一个DAG图,在启动的时候从一个或多个Source Operator开始,结束于一个或多个Sink Operator。
  • Stream是Flink计算流程中产生的中间数据。Flink是按event驱动的,每个event都有一个event time就是事件的时间戳,表明事件发生的时间,这个时间戳对Flink的处理性能很重要,后面会讲到Flink处理乱序数据流时,就是靠时间戳来判断处理的先后顺序。

Flink并行数据流
Flink操作符链
一对一的操作组成一个操作符链(将两个线程合成一个线程,减少了线程之间的转换,提高了性能)

Flink支持基于时间窗口操作,也支持基于数据的窗口操作:

  • 什么是窗口?数据源源不断的流进来,需要定义一个窗口,处理比如一分钟内的数据,对一个窗口内的数据进行计算并得到相应结果。
  • 按分割标准划分:timewindow、countwindow(事件驱动)
  • 按窗口行为划分:tumbling window(滚动窗口:时间点无重叠,需要设定窗口大小)、sliding window(滑动窗口:时间点有重叠,需要设定窗口大小,滑动距离。滑动驱动可以是事件驱动,也可以是时间驱动)、会话窗口(经过一段时间无数据认为是窗口完成)。

Flink容错能力
checkpoint机制(快照)是flink运行过程中容错的重要手段。不断绘制流应用的快照,流应用的状态快照被保存在配置位置(如:jobmanager的内存里/hdfs上)
快照机制的核心是barriers(标记/屏障),这些barriers周期性的插入到数据流中,并作为数据的一部分随之流动,当流经算子的时候,会进行拍照。
barrier是一个特殊的元组,这些元组被周期性注入到流图中并随数据流在流图中流动。每个barrier是当前快照和下一个快照的分界线。

flink优秀在哪:windows和exeactly once(分布式checkpoint机制保证了数据被处理且仅被处理一次)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值