大数据架构简介

article/2025/9/12 4:16:29

大数据技术其实是分布式技术在数据处理领域的创新性应用,其本质和此前讲到的分布式技术思路一脉相承,即用更多的计算机组成一个集群,提供更多的计算资源,从而满足更大的计算压力要求。

大数据技术讨论的是,如何利用更多的计算机满足大规模的数据计算要求。

大数据就是将各种数据统一收集起来进行计算,发掘其中的价值。这些数据,既包括数据库的数据,也包括日志数据,还包括专门采集的用户行为数据;既包括企业内部自己产生的数据,也包括从第三方采购的数据,还包括使用网络爬虫获取的各种互联网公开数据。

面对如此庞大的数据,如何存储、如何利用大规模的服务器集群处理计算才是大数据技术的核心。

01 HDFS分布式文件存储架构

大规模的数据计算首先要解决的是大规模数据的存储问题。如何将数百TB或数百PB的数据存储起来,通过一个文件系统统一管理,这本身就是一项极大的挑战。

HDFS的架构,如图31-1所示。

图片

▲图31-1 HDFS架构

HDFS可以将数千台服务器组成一个统一的文件存储系统,其中NameNode服务器充当文件控制块的角色,进行文件元数据管理,即记录文件名、访问权限、数据存储地址等信息,而真正的文件数据则存储在DataNode服务器上。

DataNode以块为单位存储数据,所有的块信息,比如块ID、块所在的服务器IP地址等,都记录在NameNode服务器上,而具体的块数据则存储在DataNode服务器上。理论上,NameNode可以将所有DataNode服务器上的所有数据块都分配给一个文件,也就是说,一个文件可以使用所有服务器的硬盘存储空间。

此外,HDFS为了保证不会因为硬盘或者服务器损坏而导致文件损坏,还会对数据块进行复制,每个数据块都会存储在多台服务器上,甚至多个机架上。

02 MapReduce大数据计算架构

数据存储在HDFS上的最终目标还是为了计算,通过数据分析或者机器学习获得有益的结果。但是如果像传统的应用程序那样把HDFS当作普通文件,从文件中读取数据后进行计算,那么对于需要一次计算数百TB数据的大数据计算场景,就不知道要算到什么时候了。

大数据处理的经典计算框架是MapReduce。MapReduce的核心思想是对数据进行分片计算。既然数据是以块为单位分布存储在很多台服务器组成的集群上的,那么能不能就在这些服务器上针对每个数据块进行分布式计算呢?

事实上,MapReduce可以在分布式集群的多台服务器上启动同一个计算程序,每个服务器上的程序进程都可以读取本服务器上要处理的数据块进行计算,因此,大量的数据就可以同时进行计算了。但是这样一来,每个数据块的数据都是独立的,如果这些数据块需要进行关联计算怎么办?

MapReduce将计算过程分成两个部分:

  • 一部分是map过程,每个服务器上会启动多个map进程,map优先读取本地数据进行计算,计算后输出一个<key, value>集合;

  • 另一部分是reduce过程,MapReduce在每个服务器上都会启动多个reduce进程,然后对所有map输出的<key, value>集合进行shuffle操作。所谓的shuffle就是将相同的key发送到同一个reduce进程中,在reduce中完成数据关联计算。

下面以经典的WordCount,即统计所有数据中相同单词的词频数据为例,来认识map和reduce的处理过程,如图31-2所示。

图片

▲图31-2 词频统计程序WordCount的MapReduce处理过程

假设原始数据有两个数据块,MapReduce框架启动了两个map进程进行处理,它们分别读入数据。

map函数会对输入数据进行分词处理,然后针对每个单词输出<单词, 1>这样的<key, value>结果。然后MapReduce框架进行shuffle操作,相同的key发送给同一个reduce进程,reduce的输入就是<key, value列表>这样的结构,即相同key的value合并成了一个value列表。

在这个示例中,这个value列表就是由很多个1组成的列表。reduce对这些1进行求和操作,就得到每个单词的词频结果了。

具体的MapReduce程序如下:

public class WordCount {public static class TokenizerMapperextends Mapper<Object, Text, Text, IntWritable>{private final static IntWritable one = new IntWritable(1);private Text word = new Text();public void map(Object key, Text value, Context context) throws IOException, InterruptedException {StringTokenizer itr = new StringTokenizer(value.toString());while (itr.hasMoreTokens()) {word.set(itr.nextToken());context.write(word, one);}}public static class IntSumReducerextends Reducer<Text,IntWritable,Text,IntWritable> {private IntWritable result = new IntWritable();public void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {int sum = 0;for (IntWritable val : values) {sum += val.get();}result.set(sum);context.write(key, result);}
}

上面讲述了map和reduce进程合作完成数据处理的过程,那么这些进程是如何在分布式的服务器集群上启动的呢?数据是如何流动并最终完成计算的呢?下面以MapReduce1为例来看这个过程,如图31-3所示。

图片

▲图31-3 MapReduce1计算处理过程

MapReduce1主要有JobTrackerTaskTracker这两种进程角色,JobTracker在MapReduce集群中只有一个,而TaskTracker则和DataNode一起启动在集群的所有服务器上。

MapReduce应用程序JobClient启动后,会向JobTracker提交作业,JobTracker根据作业中输入的文件路径分析需要在哪些服务器上启动map进程,然后就向这些服务器上的TaskTracker发送任务命令。

TaskTracker收到任务后,启动一个TaskRunner进程下载任务对应的程序,然后反射加载程序中的map函数,读取任务中分配的数据块,并进行map计算。map计算结束后,TaskTracker会对map输出进行shuffle操作,然后TaskRunner加载reduce函数进行后续计算。

HDFS和MapReduce都是Hadoop的组成部分。

03 Hive大数据仓库架构

MapReduce虽然只有map和reduce这两个函数,但几乎可以满足任何大数据分析和机器学习的计算场景。不过,复杂的计算可能需要使用多个job才能完成,这些job之间还需要根据其先后依赖关系进行作业编排,开发比较复杂。

传统上,主要使用SQL进行数据分析,如果能根据SQL自动生成MapReduce,就可以极大降低大数据技术在数据分析领域的应用门槛。

Hive就是这样一个工具。我们来看对于如下一条常见的SQL语句,Hive是如何将其转换成MapReduce计算的。

SELECT pageid, age, count(1) FROM pv_users GROUP BY pageid, age;

这是一条常见的SQL统计分析语句,用于统计不同年龄的用户访问不同网页的兴趣偏好,具体数据输入和执行结果示例如图31-4所示。

图片

▲图31-4 SQL统计分析输入数据和执行结果举例

看这个示例我们就会发现,这个计算场景和WordCount很像。事实上也确实如此,我们可以用MapReduce完成这条SQL的处理,如图31-5所示。

图片

▲图31-5 MapReduce完成SQL处理过程举例

map函数输出的key是表的行记录,value是1,reduce函数对相同的行进行记录,也就是针对具有相同key的value集合进行求和计算,最终得到SQL的输出结果。

Hive要做的就是将SQL翻译成MapReduce程序代码。实际上,Hive内置了很多Operator,每个Operator完成一个特定的计算过程,Hive将这些Operator构造成一个有向无环图DAG,然后根据这些Operator之间是否存在shuffle将其封装到map或者reduce函数中,之后就可以提交给MapReduce执行了。

Operator组成的DAG如图31-6所示,这是一个包含where查询条件的SQL,where查询条件对应一个FilterOperator。

图片

▲图31-6 示例SQL的MapReduce 有向无环图DAG

Hive整体架构如图31-7所示。Hive的表数据存储在HDFS。表的结构,比如表名、字段名、字段之间的分隔符等存储在Metastore中。用户通过Client提交SQL到Driver,Driver请求Compiler将SQL编译成如上示例的DAG执行计划中,然后交给Hadoop执行。

图片

▲图31-7 Hive整体架构

04 Spark快速大数据计算架构

MapReduce主要使用硬盘存储计算过程中的数据,虽然可靠性比较高,但是性能却较差。

此外,MapReduce只能使用map和reduce函数进行编程,虽然能够完成各种大数据计算,但是编程比较复杂。而且受map和reduce编程模型相对简单的影响,复杂的计算必须组合多个MapReduce job才能完成,编程难度进一步增加。

Spark在MapReduce的基础上进行了改进,它主要使用内存进行中间计算数据存储,加快了计算执行时间,在某些情况下性能可以提升上百倍。

Spark的主要编程模型是RDD,即弹性数据集。在RDD上定义了许多常见的大数据计算函数,利用这些函数可以用极少的代码完成较为复杂的大数据计算。前面举例的WorkCount如果用Spark编程,只需要三行代码:

val textFile = sc.textFile("hdfs://...")
val counts = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey(_ + _)
counts.saveAsTextFile("hdfs://...")

首先,从HDFS读取数据,构建出一个RDD textFile。然后,在这个RDD上执行三个操作:

  • 一是将输入数据的每一行文本用空格拆分成单词;

  • 二是将每个单词进行转换,比如word→(word, 1),生成<Key, Value>的结构;

  • 三是针对相同的Key进行统计,统计方式是对Value求和。最后,将RDD counts写入HDFS,完成结果输出。

上面代码中flatMap、map、reduceByKey都是Spark的RDD转换函数,RDD转换函数的计算结果还是RDD,所以上面三个函数可以写在一行代码上,最后得到的还是RDD。

Spark会根据程序中的转换函数生成计算任务执行计划,这个执行计划就是一个DAG。Spark可以在一个作业中完成非常复杂的大数据计算,Spark DAG示例如图31-8所示。

图片

▲图31-8 Spark RDD有向无环图DAG示例

在图31-8中,A、C和E是从HDFS上加载的RDD。A经过groupBy分组统计转换函数计算后得到RDD B,C经过map转换函数计算后得到RDD D,D和E经过union合并转换函数计算后得到RDD F,B和F经过join连接转换函数计算后得到最终结果RDD G。

05 大数据流计算架构

Spark虽然比MapReduce快很多,但是在大多数场景下计算耗时依然是分钟级别的,这种计算一般被称为大数据批处理计算。而在实际应用中,有些时候需要在毫秒级完成不断输入的海量数据的计算处理,比如实时对摄像头采集的数据进行监控分析,这就是所谓的大数据流计算。

早期比较著名的流式大数据计算引擎是Storm,后来随着Spark的火爆,Spark上的流式计算引擎Spark Streaming也逐渐流行起来。Spark Streaming的架构原理是将实时流入的数据切分成小的一批一批的数据,然后将这些小的一批批数据交给Spark执行。

由于数据量比较小,Spark Streaming又常驻系统,不需要重新启动,因此可以在毫秒级完成计算,看起来像是实时计算一样,如图31-9所示。

图片

▲图31-9 Spark Streaming流计算将实时流式数据转化成小的批处理计算

最近几年比较流行的大数据引擎Flink其架构原理和Spark Streaming很相似,它可以基于不同的数据源,根据数据量和计算场景的要求,灵活地适应流计算和批处理计算。

06 小结

大数据技术可以说是分布式技术的一个分支,两者都是面临大量的计算压力时,采用分布式服务器集群的方案解决问题。差别是大数据技术要处理的数据具有关联性,所以需要有个中心服务器进行管理,NameNode、JobTracker都是这样的中心服务器。

而高并发的互联网分布式系统为了提高系统可用性,降低中心服务器可能会出现的瓶颈压力、提升性能,通常不会在架构中使用这样的中心服务器。

关于作者:李智慧,资深架构专家,同程旅行交通首席架构师,曾在NEC、阿里巴巴、Intel等知名企业担任架构师,也曾在WiFi万能钥匙等企业担任CTO。长期从事大数据、大型网站的架构和研发工作,领导设计过多个日活用户在千万级以上的互联网系统架构,实战经验丰富。曾设计、开发过 Web 服务器防火墙、分布式NoSQL 系统、大数据仓库引擎、反应式编程框架等各种类型的软件系统


http://chatgpt.dhexx.cn/article/eYu72rJS.shtml

相关文章

大数据之大数据技术架构

上期我们说到大数据的概念&#xff0c;其实&#xff0c;大数据比我们想象中的还要复杂&#xff0c;本期&#xff0c;我们主要从技术的角度介绍一下大数据的知识。 大数据技术是一系列技术的总称&#xff0c;它是集合了数据采集与传输、数据存储、数据处理与分析、数据挖掘、数据…

常用的几种大数据架构剖析

数据分析工作虽然隐藏在业务系统背后&#xff0c;但是具有非常重要的作用&#xff0c;数据分析的结果对决策、业务发展有着举足轻重的作用。随着大数据技术的发展&#xff0c;数据挖掘、数据探索等专有名词曝光度越来越高&#xff0c;但是在类似于Hadoop系列的大数据分析系统大…

一张图解释清楚大数据技术架构,堪称阿里的核心机密

我们先来看看这张图&#xff0c;这是某公司使用的大数据平台架构图&#xff0c;大部分公司应该都差不多&#xff1a; 从这张大数据的整体架构图上看来&#xff0c;大数据的核心层应该是&#xff1a;数据采集层、数据存储与分析层、数据共享层、数据应用层&#xff0c;可能叫法有…

一文搞懂Matlab的3种取整函数(round、ceil、floor)

1、四舍五入取整&#xff1a;round(x) 对实数和复数&#xff08;实部和虚部&#xff09;都是四舍五入取整 2、向上取整&#xff1a;ceil(x) 对实数和复数&#xff08;实部和虚部&#xff09;都是向上取整 3、向下取整&#xff1a;floor(x) 对实数和复数&#xff08;实部和…

MATLAB取整及位数

Matlab取整函数: fix, floor, ceil, round 函数操作Y fix(X)向零取整Y floor(X)向下取整Y ceil(X)向上取整Y round(X)四舍五入取整 Y fix(X)将 X 的每个元素朝零方向四舍五入为最近的整数。对于正方向的 X&#xff0c;fix 的行为与 floor 相同。对于负方向的 X&#xff…

Matlab之取整函数

一、函数取整函数 函数取整&#xff0c;有如下四种函数 floor():向下取整ceil():向上取整round():取最近整数fix():向0取整 二、例程 1、floor():向下取整 disp(floor-向下取整); A1floor(1.2) A2floor(2.5) A3floor(-2.5) 2、ceil():向上取整 disp(ceil-向上取整); B1ce…

matlab中的取整函数(ceil、floor、round)

matlab中的取整函数主要有三种&#xff1a;ceil()、floor()、round() 1.ceil()&#xff1a;在英文中&#xff0c;是天花板的意思&#xff0c;有向上的意思&#xff0c;所以&#xff0c;此函数是向上取整&#xff0c;它返回的是大于或等于函数参数,并且与之最接近的整数。 ceil…

Java中的拦截器和过滤器有什么区别

本文收录于JavaStarter &#xff0c;里面有我完整的Java系列文章&#xff0c;学习或面试都可以看看 &#xff08;一&#xff09;什么是过滤器 过滤器Filter基于Servlet实现&#xff0c;过滤器的主要应用场景是对字符编码、跨域等问题进行过滤。Servlet的工作原理是拦截配置好的…

过滤器和拦截器区别以及执行顺序

过滤器和拦截器区别 觉得这个总结的很好&#xff0c;所以用来借鉴借鉴 摘抄于网络&#xff0c;侵删 过滤器和拦截器执行顺序 在SpringBoot中编写测试代码 自定义过滤器 /*** Author: xiaoshijiu* Date: 2019/5/22* Description: 自定义过滤器*/ public class MyFilter exten…

过滤器和拦截器总结

过滤器和拦截器在日常业务开发中不是经常用到&#xff0c;近来项目中偶尔遇到了&#xff0c;对过滤器和拦截器进行了一次系统学习&#xff0c;现总结如下。 一、过滤器Filter 1.1 什么是过滤器 过滤器是Servlet的高级特性之一&#xff0c;是实现Filter接口的Java类。其基本功能…

Java 过滤器与拦截器的区别

什么是过滤器&#xff08;Filter&#xff09; 过滤器&#xff0c;是在java web中将你传入的request、response提前过滤掉一些信息&#xff0c;或者提前设置一些参数。然后再传入Servlet或Struts2的 action进行业务逻辑处理。比如过滤掉非法url&#xff08;不是login.do的地址请…

Java拦截器和过滤器的区别

过滤器和拦截器的区别&#xff1a; ①拦截器是基于java的反射机制的&#xff0c;而过滤器是基于函数回调。   ②拦截器不依赖与servlet容器&#xff0c;过滤器依赖与servlet容器。   ③拦截器只能对action请求起作用&#xff0c;而过滤器则可以对几乎所有的请求起作用。  …

Java过滤器与拦截器的区别

Java过滤器与拦截器的区别 1. 过滤器与拦截器概述1.1 过滤器 Filter1.2 拦截器 interceptor 2. 过滤器与拦截器区别3. 过滤器与拦截器实现3.1 过滤器&#xff08;Filter&#xff09;3.2 拦截器 (Interceptor)3.3 拦截器WebMvc配置3.4 切片&#xff08;Aspect&#xff09; 4. 过…

C语言pow函数的调用

1.pow函数的含义&#xff1a;在math.h的头文件中是指a的b次方。 2.对于pow函数的直接应用&#xff1a; #include<stdio.h> #include<math.h> //***math头文件 int main() {double a2,b3;double result;resultpow(2,3); …

mysql pow函数怎么用_pow函数怎么用

PHP pow函数表示指数表达式。 pow函数怎么用&#xff1f; php pow()函数 语法 作用&#xff1a;pow()函数的作用是将一个数进行n次方计算后返回 语法&#xff1a;pow(X,Y); 参数&#xff1a; X表示要做处理的数字 Y表示指定n次方中的n数值 说明&#xff1a;返回X的Y次方幂&…

c语言的pow函数运用

在c语言当中我们要计算一个数的n次方时候&#xff0c;可以使用多种方法&#xff0c;但是也有一种比较简单的方法&#xff0c;便是调用一个函数pow函数。 pow函数在使用时候需要引用头文件#include<math.h>&#xff0c;接下来可以引用一个例子&#xff1a; 如果现在假设我…

C语言中的pow函数

在我们学习C语言时&#xff0c;在一些算法的问题上常常会遇到让我们求一个数的n次方&#xff0c;这时候为了方便我们可以使用C语言函数库给我们的pow函数&#xff0c;*因为这是从C语言函数库调用出来的所以我们在使用前需要引入头文件#include<math.h>。 比如当我们输入…

pow函数python_python pow函数怎么用

python中的pow函数的功能是计算x的y次幂。本篇文章将带大家一起了解一下&#xff0c;pow()函数在Python中的用法。感兴趣的朋友了解一下。 以下是 math 模块 pow() 方法的语法:import math math.pow( x, y ) 内置的 pow() 方法pow(x, y[, z]) 函数是计算x的y次方&#xff0c;如…

计算机里pow函数是什么,pow函数是什么?

pow函数&#xff1a; C/C中的数学函数&#xff1b; pow() 函数用来求 x 的 y 次幂(次方)&#xff0c;x、y及函数值都是double型 pow()用来计算以x 为底的 y 次方值&#xff0c;然后将结果返回。设返回值为 ret&#xff0c;则 ret xy。 可能导致错误的情况&#xff1a; 如果底数…