……

首先,数据传输组件:

①Kafka是用Scala编写的分布式消息处理平台。
②Logstash是用JRuby编写的一种分布式日志收集框架。
③Flume是用Java编写的分布式实时日志收集框架。

其次,数据存储组件:
④HDFS (Hadoop Distributed File System)用Java编写,是谷歌的GFS(Google File S ystem)的一种开源实现。
⑤Redis是用ANSIC编写的一种基于内存的Key-Value键值对数据库。
⑥HBase是用Java 编写的分布式列式数据库。
⑦Hive是用Java编写的,他是建立在Hadoop之上的分布式数据仓库。
⑧Elasticsearch是以Apache Lucene为核心打造的分布式全文搜索引擎。

最后,数据计算组件:
⑨Hadoop是受Google Lab开发的MapReduce和Google File System(GFS)的启发而全面实现的开源大数据处理平台。
⑩Storm是用Clojure语言编写的分布式实时流处理系统。
⑾Spark是用Scala语言编写的分布式数据处理平台。

常用组件介绍:具有特定功能的可复用组件正是计算机领域中的利器。在大数据的浪潮下,许多用于处理大数据的组件应运而生,分别应用在“数据传输”“数据存储”“数据计算”以及“数据展示”的环节中。这里,我们将着重介绍一些常用组件的内部原理以及使用方式,并讲述在大数据处理领域中的一些通用架构模式。
(一).数据传输:
数据传输时数据处理中至关重要的一步,数据工程师需要利用高效的传输方式把分散在不同机房不同地域的海量数据汇集在一起,才能进一步实现数据的处理。Kala、 Logtash和Flume是大数据传输中三种典型的组件

Kafka是用Scala编写的分布式消息处理平台,最初由LinkedIn公司开发,后成为Apache项目的部分 。与Kafka类似的常用消息队列包括RabbiMQ、ZeroMQ、ActiveMQ等,它的架构如图所示。
在这里插入图片描述

  1. kafka
    上图为 Kafka 架构图;Producer:消息的生产者,主要负责向Broker发送消息。Kafka 的负载均衡方式由Producer 自身决定,这就意味着由Producer 按照Round Robin、随机的方式或者其他方式向Broker集群发送消息。
    Broker:负责接受与存储Producer发送来的消息。一个 Broker就是一个KafkaServer,一个集群由N个Broker组成。
    Consumer:消息的消费者,负责从Broker拉取数据。
    ConsumerGroup:由N个Consumer组成的组。同一个Group的Consumer受同一Topic 的数据。Topic 是Broker 在组织与处理消息时用到的概念。Broker内部处理Topic的方式如下图所示
    在这里插入图片描述
    Topic:逻辑上的概念,可以理解成消息队列。Producer 向指定的Topic中发送数据,Consumer消费来自指定Topic的数据。
    Partition:一个 Topic 由多个Partition组成,分布在多个Broker中,实现负载均衡。同时,其在Broker集群中会保存多个副本,是Kafka集群实现可靠性保障的最小单位。如下图所示,单个Partition中的消息根据先后顺序不断追加。
    在这里插入图片描述
    Offset: 每个Partition在Broker机器中会分割成多个小的日志文件存储在磁盘上,这些日志文件按Offset的形式分割存储。
  2. logstash:
    Logstash是用JRuby编写的一种分布式日志收集框架,由Input、Filter和Output三个部分构成分别负责日志的输人、格式化以及输出。与Kafka这种消息队列相比,它更像是消息的传送带,连接源头接收数据,在中间传输的过程中做格式化处理,Output最终将消息以Push的方式推送到目的地。它的架构如下图所示:

在这里插入图片描述Logstash的各个功能模块通过配置的方式定义输人的监听端口、输出的目的地,以及格式化的方式。以下是来自官网的一个配置示例,可以让读者有直观的认知。
在这里插入图片描述
input可以配置很多的数据接收插件,比如Redis、filebeat等;以上配置中input代码块表示添加beats的输入插件;filter配置说明对日志消息格式化的方式;output配置日志打印到控制台。这是logstash配置的基本骨架,可以参照官方文档定制修改。
3.Flume
同logstash类似,Flume是用Java编写的分布式实时日志收集框架,它的原始版本由Cloudera公司开发,称为Flume OG。随着功能的不断扩展,核心组件设计的问题逐渐暴露,稳定性问题频发,迫使该公司对Flume实施大规模改动——重构后的Flume被称为Flume NG即Flume Next Generation。他最终被归于Apache旗下,改名为Apache Flume,架构如下图所示:
在这里插入图片描述
①Agent:每个JVM对应一个Agent进程,一个Agent中包含多个Source、Channel 、Sink。
②Source:用于搜集数据,并把数据传输到Channel。
③Channel:缓存Source发来的数据。当前有MemoryChannel、JDBCChannel、FileChannel、CustomChannel等可供配置。如果Channel中的数据选择存储在内存中,那么速度快,但易丢失;相反,如果存储在硬盘中,则可靠性更高。
④Sink: 从Channel中读取数据,可以向硬盘、HDFS、数据库等存储介质传输数据。Flume 本身支持HDFS Sink、Thrift Sink等类型。

Flume与Logstash的定位基本一致, 都是作为“传送带”把数据从一前运送到另端。不同的是,前者强调数据的传输,但是基本不会对数据做字段提取等操作;后者在传输数据的同时,会依据配置做字段提取、解析等预处理工作,和Flume相比,Logstash会耗费更多的系统资源、加重系统的负载。此外,Flume的数据保存在Channel中,只有流转完成后,才会删除数据,从而进一步保证了数据的可靠性。
(二).数据存储:
集中存储是有效分析数据的前提条件,为了解决数据集中存储的问题,各种组件层出不穷,我们这里简单介绍HDFS、Redis、HBase、Hive以及Elaticsearch这5种典型的组件予以介绍。
1.HDFS
HDFS (Hadoop Distributed File System)用Java编写,是谷歌的GFS的一种开源实现。HDFS 可在廉价的机器上实现存储能力的横向扩展,且以多副本的方式实现数据的可靠性保障,它的架构如下图所示:
在这里插入图片描述
由上图可知,HDFS采用了Master-Slave 的架构方式。其中NameNode和ScondaryNameNode分别为Master的主节点和备节点,复制管理文件的目录、文件、DataNode 以及Block的对应关系。

HDFS适合大文件一次性上传,多次读取;不支持对已上传数据块的随机读写。图中小方块代表Block,大文件会被分成多个小Block存储到多到多个DataNode中; 同一个Block也会被复制到其他DataNode中实现数据的多备份。

文件的写流程如下:
①Client上传大文件时,首先在本地文件系统建立临时存储区,当数据量积累到一个数据块的大小的时候,再于NameNode会话,获取DataNode位置和Block标识,进行写入。
②当数据副本设置为3时,DataNode使用流水式的复制方式实现数据的接收和备份。第一个 DataNode一边接收数据, 一边把数据发送给第二个 DataNode:第二个DataNode以相同的方式把数据传送给第三个DataNode。当三个数据块全部写完则认为一个Block上传成功。
③当文件关闭时,如果临时存储区还有不满一个Block的数据量,也会一并上传至HDFS,并告知NameNode写入结束。
④NameNode将文件操作提交给日志存储。

文件的读流程如下。
①与NameNode会话,获取待读取文件的DataNode和Block信息。
②选择“最近”的副本读取数据。
③读取完毕,发送Close给NameNode,断开连接。
2. Redis
Redis是用ANSIC编写的一种基于内存的Key-Value键值对数据库,类似于早期的memcached可以在内存数据库、缓存、消息代理等场景中使用。Redis更高级的使用方式比如“SortedSet” “发布-订阅”等可参见官网。

下面我们介绍Redis的其他特性。Redis支持用“日志快照”和“追加日志”的方式实现数据的持久化。“快照”主要是每隔一段时间把内存的数据完整地复制到磁盘;而“追加”则是对每一条操作追加一条日志。 使用日志快照的方式实现数据持久化时。两次快照具有一定的间隔时间,在该时间窗口内如果Redis发生故障,则会造成数据的丢失;采用追加日志的方式实现数据持久化时,由于实时记录每一条操作, 不存在快照方式中的“时间窗口”,因此,可以降低数据丢失的风险,但是在故障恢复时,如果采用追加日志的方式实现持久化,工程师要使用工具逐条重放日志才能恢复数据,速度较慢。
3. HBase
HBase是用Java 编写的分布式列式数据库,它仿照的是谷歌列式数据库BigTable的开源实现。HDFS是分布式文件系统,HBase 则是在该文件系统的上层实现的数据库,它的架构如下图所示。
在这里插入图片描述
由图可知,一个HMaster管理多个HRegionServer; 一个HRegionServer管理多个HRegion;一个HRegion管理多个Store模块;每个Store模块下又由Memstore和多个StoreFile构成,StoreFile 是对HFile的轻量级封装。
在说明HBase的读写流程之前,需要先介绍两张表-ROOT-和.META.其中.META记录了用户表的HRegionServer信息;由于.META 表可能分裂到多个HRegion上存储,因此-ROOT-记录了.META表的Region信息,-ROOT-只有一个Region。-ROOT 和.META共同构成了HBase的索引,如下图所示:
在这里插入图片描述
写入的流程如下。
①每个表的数据都有唯一的RowKey (行键)。
②根据表名字和RowKey,从-ROOT和.META中定位写入的HRegionServer的地址。
③HRegionServer根据配置决定是否写入Hlog;之后把数据写入到MemStore,如果其已满,则刷新成一个StoreFile,即HDFS的一个文件。

HBase使用RowKey,根据-ROOT-和.META表直接定位数据的位置,读取数据。如果某个RowKey被查询过,它的相关信息会被缓存,后续针对这个RowKey的查询会非常之快。

HBase中RowKey决定写入的HRegionServer地址,因此RowKey的设计会决定写入、读取的负载程度。最初一个Table只有一个 HRegion,随着数据的增加,HMaster会对其进行Split 操作,将其一分为二;同时下线父HRegion,而新的子HRegion上线;子HRegion可能被分配到不同的HRegionServer中以实现负载均衡。

HBase采用LSM作为数据存储引擎,大致的思路是数据按顺序入,且更新数据就相当于写入一份新数据,并不更改原数据。当HFile 的个数超过一定的阈值时,就会触发Compact操作,对所有数据版本进行合并和删除。

HBase的数据存储在HDFS中,实现了数据的多副本存储;同时引人Hlog降低了写入MemStrore过程中数据丢失的风险。同一行数据同一时间只有一个HRegion提供访问,因此HBase支持行级锁,且实现了数据的强一致性; 如果某HRegion 宕机,则需要一段时间用日志更新其他HRegion后才能继续提供服务 。
4. Hive
Hive是用Java编写的,他是建立在Hadoop之上的分布式数据仓库。与HBase数据库相比,两者的定位截然不同;数据仓库针对大量的历史数据,提供非实时的联机分析操作:而数据库针对量级较小的业务数据,提供实时的事务处理操作。Hive 开发了自身的SQL语言,称为HQL。Hive的数据存储在HDFS上,HQL语句经过解析生成MapReduce任务,依托Hadoop的MapReduce计算框架进行数据的处理。他的架构如图所示:
在这里插入图片描述
Hive提供CLI、Thritf以及HWI三种对外服务。其中CLI是命令行工具;Thritf是PRC服务;HWI为Web接口,可以通过浏览器访问Hive。客户端通过上述三种服务把HQL提交到Hive,Hive负责HQL的解析、编译、生成,并提交MR任务到Hadoop平台,流程如图所示:
在这里插入图片描述
由图可知,Hive依赖于Hadoop做数据运算,而Hadoop只用于海量数据的非实时处理,因此Hive的速度是他的短板。Shark、Tez、SparkSQL等与Hive具有相同或相似功能的组件,在计算速度上优于Hive;但是Hive的稳定性、强大功能及与Hadoop的完美融合,是他成为首选的分布式数据仓库。
5. Elasticsearch:
Elasticsearch是以Apache Lucene为核心打造的分布式全文搜索引擎。由于它还实现了分布式文件存储和部分实时分析的功能,有时候也把它当成文档数据库来使用。
Lucene是一个开源的, 用于文档索引和搜索的高性能Java 库,其核心只有一个jar文件。
我们举例说明它的使用:假设有三个文档分别是No1: {“lamalawyer”}、 No2:{Tomorrowwisagoodday} .No3:(“partyisfulloffun”},这些文档存储在数据文件中。Lucene 库的接口提供了这样的功能:指定数据文件的路径及相关参数,就可以对文档创建全文索引;当调用search(“lawyer” )函数搜索时,接口可以及时返回文档No1。当然,Lucene 库还包含文件过滤、排序等辅助功能。

Elasticsearch以Lucene框架为核心,构造了分布式的全文搜索引擎。它对外提供两种访问方式:Java API交互和基于HTTP协议的Restful接口。
我们以MySQL为类比,阐述几个重要概念,类比图如下:
在这里插入图片描述
如果我们把Elasticsearch 看成是文档数据库,那么它的index 与MySQL的DB实例其实是一个概念。请注意这里的index和MySQL中的index (索引)有很大的区别;type 表示同一scheme存储的数据,此处的scheme就是PUT数据时的JSON格式; document 泛指一个文档,与MySQL的row的概念类似;一个document可以划分成多个field。 Elasticsearch 的集群架构如下图所示:
在这里插入图片描述
Elasticsearch会把index进行切片,负载均衡到集群中多个计算节点中;同时,会备份分片作为副本,这些副本分散在集群中,以实现数据存储的可靠性。
Elasticsearch的任意节点都对外提供服务,不存在Master-Slave这种方式。他的工作流程如下:
①客户端请求发送给Elasticsearch集群中任意一个节点NodeA,该节点根据请求携带的ID,计算出数据应存储在分片Shard0上。
②根据集群信息,获取该分片Shard0对应节点NodeC的物理地址。
③所有到NodeA的请求,将被转发到NodcC的Shard0上进行读写操作。
(三)数据计算
当前的高性能PC机、中型机等机器在处理海量数据时,其计算能力、内存容量等指标都远远无法达到要求。在大数据时代,工程师采用廉价的PC机组成分布式集群, 以集群协作的方式完成海量数据的处理,从而解决单台机器在计算到与存储上的瓶颈。本节主要介绍Hadoop、Storm 以及Spark三种常用的分布式计算组件,其中Hadoop是对非实时数据做批量处理的组件; Storm 和Spark是针对实时数据做流式处理的组件。
1.Hadoop
Hadoop是受Google Lab开发的MapReduce和Google File System(GFS)的启发而全面实现的开源大数据处理平台。Hadoop的核心由HDFS分布式文件系越和MapReduce编程框架组成。前者已经有过介绍,它为海量数据提供存储;后者则用于对海量数据的计算,我们这里将着重讲述它。其(MapReduce)工作流程如下图所示:
在这里插入图片描述
我们以字母统计为例说明上述流程。假设有文件内容为“Iamapanda,andIanfromChina”。首先,把大文件分割成data数据块;其次,把data发送到各个工作机;此时,工作机解析内容,形成Key-Value键值对数据。本例中形成的数据为<I,1>,<I,1>, <am, 1>, <am, 1>,<a, 1>, <panda, 1>, <and, 1>, <fron, 1>.<China, 1>, 这些数据保存在中间文件中,Map阶段结束。之后,根据Key值路由,把相同Key值的键值对路由到同一台工作机,并在工作机上实现单词计数。本例中计数结果<I,2>, <am, 2>, <a, 1>, <panda, 1>, <and, 1>, <from, 1>, <China, 1>最后,各Reduce工作机把结果写入文件,Reduce 阶段结束。

Hadoop平台上通过JobTracker和TaskTracker协调调度,实现MapReduce的运行,其工作机制如下图所示
在这里插入图片描述
由上图可知:JobTracker负责任务调度,而TaskTracker负责任务的执行;同时,需要处理的数据存储在HDFS中,TaskTracker根据MR程序读取并处理数据。

以上对Hadoop的介绍根据的是Hadoop1.0(第一代Hadoop)的整体框架,当前Hadoop2.0(第二代Hadoop)引入了YARN作为其资源调度的方式,架构与1.0略有不同,但依然采用MR的计算模型

2.Storm
Storm是用Clojure语言编写的分布式实时流处理系统。Hadoop平台执行批处理操作,数据处理的延时较高;而进入Storm的数据则像水流一样源源不断流入,并对其进行实时处理,Storm集群架构如下图所示:
在这里插入图片描述
Nimbus与Hadoop中JobTracker的功能类似,负责资源的管理和任务的调度。从Zookeeper中读取个节点信息,协调整个集群的运行。
Supervisor与Hadoop 中TaskTracker的功能类似,负责接受任务。负责自身Worker进程的创建和任务的执行。
Worker是机器上具体的运行进程,Executor是该进程中的线程。一个Executor可以执行多个Task。在该集群架构的方式下, Storm 实现了如下图所示的计算模型。
在这里插入图片描述
Spout是数据的入口,负责接受推送的数据,或者主动拉取数据。同时,把接收的数据转换为Tuple对象发送到Blot中处理。数据从Spout进人,封装成Tuple,传输到第一层的某个Blot中,该Blot处理完成后,路由到第二层的某个 Blot中,依此类推直到最后组Blot处理结束。
Blot是Storm实际的数据处理单元,接受Spout或者上一级Blot传输的数据并处理。根据并发度的设置,Blot 会分散到集群的一台或多台集群上并发执行,从而有效利用集群的计算能力,提高数据处理的实时性。这和在单台机器上多线程处理有相似之处。

Tuple是一个或多个包含键值对的列表。数据会封装成Tuple对象在Spout与Blot之间传输。Storm 支持7种路由策略,分别为
●Shuffle分组,Tuple 随机分散传输到后续的多个Task中;
●Fields分组,根据指定field来做哈希,相同的哈希值传输到同一个Task;
●All分组,广播式地发送,把所有的Tuple发送到所有的Task中;
●Global分组,把所有的Tuple发送到一个 Task中;
●None分组,也就是不关心如何路由,目前等同于shuffle分组;
●Direct分组,是一种特殊的分组,需要手动指定Task;
●localorshuffle分组,如果目标Blot中的Task和产生数据的Task在同一个Worker中,就执行线程间的内部通信,否则等同于shuffle分组。
3. Spark
Spark是用Scala语言编写的分布式数据处理平台。Spark的核心数据处理引擎依然是运行MapRaduce计算框架,并且围绕引擎行生出多种数据处理组件,共同打造了轻量级的数据处理生态圈,如下图所示
在这里插入图片描述
Spark数据引擎是各组件库的核心。Spark 与Hadoop的计算框架都是基于MapReduce模型的,Spark 自身不包含类似HDFS的文件系统模块,而是借助外部的平台如HDFS、HBase 等存取数据。Spark在执行MapReduce的过程中做了重要的优化:第一,计算的中间数据不写磁盘,全部在内存中执行(可以设置对磁盘的依赖);第二,支持任务的迭代。Hadoop 任务必须依照Map -Reduce 成对执行,然而Spark可以依据任务的DAG图,按照Map ——> Map ——> Reduce 等任意方式执行。这两点改进极大缩短了任务时延。

下图所示为Spark的工作流程。RDD是Spark的重要概念,代表了数据集和操作的结合。数据集来自内部或者外部,操作包含map, group, reduce等。
在这里插入图片描述
lineLengths就代表数据集lines和操作map组成的RDD。一个RDD又可以分成多个Task执行,按照其执行的顺序组成DAG图。后续RDD的执行依赖先前的RDD的执行,因此这种依赖关系又可以划分为Stage,如下图所示,直观说明了DAG、Stage、RDD以及Task的概念。
在这里插入图片描述
Spark Streaming 是基于Spark核心处理引擎实现的高吞吐与低延迟的分布式流处理系统。与Storm相比,两者在功能上是一致的,都实现了数据流的实时处理; Storm 的延迟在亚秒级别,而Spark Streaming是在秒级别,主要因为前者对数据的处理就像水流一样,来一条数据则处理一 条, 而后者是不断进行小批量处理,只有在某些苛刻的场景下才能对比出这两种方式的优劣。Spark Streaming数据处理流程如下图所示。
在这里插入图片描述
SparkSQL 是分布式SQL查询引擎与Hive类似,并对Hive提供支持。Hive基于Hadoop的MapReduce实现查询,SparkSQL则是基于Spark引擎,因此查询速度更快。但是,SparkSQL需要更多的内存,在实际应用中其功能的丰富性和稳定性却不如Hive,不过随着系统的不断演化,SparkSQL逐渐取代Hive,成为分布式SQL查询引擎的佼佼者。
MLlib是Spark封装的一些常用的机器学习算法相关库。基于RDD的方式实现了二元分类、回归、系统过滤等一些算法。GraphX主要对并行图计算提供支持,开发并实现了一些和图像相关新的Spark API。

 
 posted on 2022-08-31 23:38  大码王  阅读(830)  评论(0编辑  收藏  举报
复制代码