大数据常用技术概要

前言

相关技术

大数据技术

整体生态

20220422144142(1)

Hadoop生态2

img

相关概念

数据采集=>数据存储和管理=>数据处理和分析=>数据隐私和安全

大数据两大核心技术

  1. 分布式存储
  2. 分布式处理

大数据技术是以谷歌技术为代表的

  • 分布式数据库BigTable
  • 分布式文件系统GFS
  • 分布式并行处理技术MapReduce

对应的开源实现

  • Hbase
  • Hadoop(HDFS)
  • Hadoop(MapReduce)、Spark、Flink

处理数据的两种方式

  1. 批处理:Hadoop(MapReduce),Spark
  2. 流计算:Flink
  3. 图计算
  4. 查询分析计算:(数据仓库)Hive

如图

image-20220419170351748

Hadoop生态系统

image-20220419170435215

MapReduce工作流程

image-20220419170522002

YARN解决的问题

  • 资源利用率低

  • 数据无法共享

  • 维护代价高

YARN原理

image-20220419170609244

Spark架构

image-20220419170702545

Hadoop

Hadoop 包含了三个组件:

  1. 分布式存储技术 HDFS
  2. 分布式计算框架 MapReduce => Flink/Spark
  3. 分布式资源管理技术 Yarn => K8S

Spark并不能替换Hadoop,它可以替换Hadoop中的MapReduce,所以现在常见的是Hadoop和Spark配合使用。

Yarn 与 K8S

Spark做为基于jvm的通用计算引擎,跑在yarn和k8s上没啥区别,该有的功能都能有。

但是在未来整个数据处理的链路/生态上,yarn的能力不如k8s。yarn提供的JAVA进程级别的container天生不适合jvm体系以外的计算框架,比如tensorflow。而k8s的容器则完美契合。

HDFS

hadoop fs | dfs

什么是MapReduce

MapReduce其实上是两种操作

  • Map
  • Reduce

Map

map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

1
2
3
4
5
6
7
const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2);

console.log(map1);
// expected output: Array [2, 8, 18, 32]

map和flatMap

1
2
3
4
5
6
7
let arr1 = ["it's Sunny in", "", "California"];

arr1.map(x => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]

arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]

Reduce

reduce() 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Arrow function
reduce((previousValue, currentValue) => { /* ... */ } )
reduce((previousValue, currentValue, currentIndex) => { /* ... */ } )
reduce((previousValue, currentValue, currentIndex, array) => { /* ... */ } )
reduce((previousValue, currentValue, currentIndex, array) => { /* ... */ }, initialValue)

// Callback function
reduce(callbackFn)
reduce(callbackFn, initialValue)

// Inline callback function
reduce(function(previousValue, currentValue) { /* ... */ })
reduce(function(previousValue, currentValue, currentIndex) { /* ... */ })
reduce(function(previousValue, currentValue, currentIndex, array) { /* ... */ })
reduce(function(previousValue, currentValue, currentIndex, array) { /* ... */ }, initialValue)

参数

  • callbackFn

    一个 “reducer” 函数,包含四个参数:previousValue:上一次调用 callbackFn 时的返回值。在第一次调用时,若指定了初始值 initialValue,其值则为 initialValue,否则为数组索引为 0 的元素 array[0]currentValue:数组中正在处理的元素。在第一次调用时,若指定了初始值 initialValue,其值则为数组索引为 0 的元素 array[0],否则为 array[1]currentIndex:数组中正在处理的元素的索引。若指定了初始值 initialValue,则起始索引号为 0,否则从索引 1 起始。array:用于遍历的数组。

  • initialValue 可选

    作为第一次调用 callback 函数时参数 previousValue 的值。若指定了初始值 initialValue,则 currentValue 则将使用数组第一个元素;否则 previousValue 将使用数组第一个元素,而 currentValue 将使用数组第二个元素。

返回值

使用 reducer 回调函数遍历整个数组后的结果。

MapReduce/Spark/Flink

批处理和实时流处理

  • 批处理:数据不能实时计算,但是批处理的逻辑可以非常的复杂
  • 实时流处理:数据可以实时计算,但是计算逻辑相对比较简单

对比

框架 批处理 实时流处理
MapReduce(Hadoop) 支持 不支持
Spark 支持
对比MapReduce性能高
支持
使用批处理模拟的
Flink 支持
使用实时流处理模拟的
支持

详情

MapReduce 适合批处理任务,也就是说每天对一个大量的静态数据集进行一次处理,同样,Spark 也非常的适合批处理任务,但是 Spark 有一个子模块就是 Spark Streaming 用于实时数据流处理

Flink 同样适合对大数据进行批处理,也可以使用在实时数据流的处理中,那么 Spark 和 Flink 到底选择哪一个呢?

Spark 是以批处理起家的,它的内核就是以批处理的思想来设计实现的。Spark Streaming 虽然可以实时处理数据,但是它的本质还是批处理,只是批处理的时间间隔缩短,比如时间间隔设置成 1 秒,那也就是说每隔 1 秒钟发起一个批处理,所以严格来说 Spark Streaming 只能是近实时处理的技术,适合用于延迟是秒级别的实时计算应用。

Flink 是以实时流处理起家的,它的内核就是以实时流处理的思想来设计实现的。所以 Flink 的实时流处理才是真正意义上的实时处理,如果你的实时处理应用要求延迟非常低的话,那就是用 Flink 的实时流处理了。

Flink 也是支持批处理的,Flink 批处理是基于 Flink 的实时流处理来实现的,也就是说实时收集到的数据先不做处理,等收集了一段时间的数据后,再对这段时间收集的数据做全量的批处理。

所以,对于计算逻辑非常复杂的应用,建议使用 Spark,对于实时要求非常高的场景,建议使用 Flink 的实时流处理技术,如果实时要求不高的话,仍然可以选择使用 Spark Streaming。

Kafka/Rabbitmq

Rabbitmq比Kafka可靠,kafka更适合IO高吞吐的处理,比如ELK日志收集

Kafka和RabbitMq一样是通用意图消息代理,他们都是以分布式部署为目的。但是他们对消息语义模型的定义的假设是非常不同的。

a) 以下场景比较适合使用Kafka。如果有大量的事件(10万以上/秒)、你需要以分区的,顺序的,至少传递成功一次到混杂了在线和打包消费的消费者、希望能重读消息、你能接受目前是有限的节点级别高可用就可以考虑kafka。

b) 以下场景比较适合使用RabbitMQ。如果是较少的事件(2万以上/秒)并且需要通过复杂的路由逻辑去找到消费者、你希望消息传递是可靠的、并不关心消息传递的顺序、而且需要现在就支持集群-节点级别的高可用就可以考虑rabbitmq。

Sqoop和DataX的区别

  1. sqoop采用map-reduce计算框架进行导入导出,而datax仅仅在运行datax的单台机器上进行数据的抽取和加载,速度比sqoop慢了许多;

  2. sqoop只可以在关系型数据库和hadoop组件之间进行数据迁移,而在hadoop相关组件之间,比如hive和hbase之间就无法使用sqoop互相导入导出数据,同时在关系型数据库之间,比如mysql和oracle之间也无法通过sqoop导入导出数据。与之相反,datax能够分别实现关系型数据库hadoop组件之间、关系型数据库之间、hadoop组件之间的数据迁移;

  3. sqoop是专门为hadoop而生,对hadoop支持度好,而datax可能会出现不支持高版本hadoop的现象;

  4. sqoop只支持官方提供的指定几种关系型数据库和hadoop组件之间的数据交换,而在datax中,用户只需根据自身需求修改文件,生成相应rpm包,自行安装之后就可以使用自己定制的插件

DataX

https://developer.aliyun.com/article/59373

Pig与Hive的区别

Pig与Hive作为一种高级数据语言,均运行于HDFS之上,是hadoop上层的衍生架构,用于简化hadoop任务,并对MapReduce进行一个更高层次的封装。

Pig与Hive的区别如下:

  • Pig是一种面向过程的数据流语言;Hive是一种数据仓库语言,并提供了完整的sql查询功能。
  • Pig更轻量级,执行效率更快,适用于实时分析;Hive适用于离线数据分析。
  • Hive查询语言为Hql,支持分区;Pig查询语言为Pig Latin,不支持分区。
  • Hive支持JDBC/ODBC;Pig不支持JDBC/ODBC。
  • Pig适用于半结构化数据(如:日志文件);Hive适用于结构化数据。

什么是Spark?

分布式计算框架

Mapreduce也是分布式计算框架,但是Spark要多加2个字,分布式内存计算框架,牛就牛在内存这块。

  • MR分布式计算框架比较会偷懒,干活干着干着就把活放着休息(写到磁盘)

  • Spark则不偷懒,一直干不停(数据都在内存),随叫随到,从不犹豫

  • Spark干活也比较有方法,爱动脑子(DAG)

所以和它的堂兄MapRedcue比起来,有如哪些不同点呢:

1)Spark脑子聪明、不偷懒- 中间结果不输出磁盘

MR喜欢将中间结果写到磁盘上,MR做事又喜欢将一件事情分层几个环节来做(多个stage,执行的时候讲多个stage串联起来),每个环节都把中间结果写到磁盘,下个stage又从磁盘拿出来,难免啰嗦、麻烦效率低(MR做事比较死板,一板一眼按流程挨个做(一个任务分为多个stage串行执行))。

Spark相对机灵一点,事先评估好做事情的策略和方法,哪些事情可以放在一起,哪些不放在一起,方法策略定好后(所有动作抽象为有向五环图执行计划DAG),再动手干,规划好的事情可以挨个做,也可以同时做,活不离手(数据在内存),当然有时候拿不过来了,也可以放一放手(写到磁盘上),下次再要做的时候再拿起来继续。

但是显然spark的缺点也明显了,内存,你的数据一致放在内存,哪有那么多内存让你败啊,如果和其他一样需要消耗内存的服务在一起,肯定要打个你死我活。MR就不会,别人想多点内存,他一点都不在意,谁要谁拿去,哥不稀罕。

2)脾气不好-Spark容错比maprduce要差

有点才华的人脾气都大啊,spark比较有个性,脾气确实不咋地。如果活干着干着失败了,spark暴怒之下就要从头再来(做事太急,急的都不知道自己在哪里跌倒了-因为数据在内存,需要重新计算),而MR则不会从头再来,他哪里跌倒哪里爬起来,因为做事情慢,所以也是有条不紊(知道在哪里跌倒了-数据在磁盘)。

其实两个人都有比较好的脾气- 好的容错能力,但是他们对比起来,MR容错能力略好一点。

3)相处能力(与其他组件的兼容性)

Spark可以自己单干,也可以在yarn上一伙人干,吃饭也不挑剔-(数据源可以是HDFS支持的各类文件格式),还可以通过jdbc和odbc和家族之外人共事(与传统BI工具)

mr内心是这样想的:这有什么好拿出来炫耀的,我也可以做到。确实他们两兄弟在这一点上是旗鼓相当的。

4)身体健康(安全性)

  • 血型- 编程语言

    spark的选型是scala,mapreduce的血型是java,从血型看,scala更厉害一点,scala血型的人擅长干体力活(处理数据),并且也支持其他血型(java,python,sql),尤其是对sql的支持,比mapreduce不知道强了多少倍。java血型更适合处理综合性的复杂事情,并不是很擅长干体力活,并且干活时的套路太多了(写个mr程序各种框架套着)

    Spark 更易于编程,同时也包含交互式模式;Hadoop MapReduce 不易编程但是现有的很多工具使其更易于使用。

  • 免疫能力-安全机制

    毕竟大哥就是大哥,年龄在那里摆着呢,免疫能力当然更好一点-具备所有 Hadoop 支持的安全机制,同时也整合了其它基于 Hadoop 的安全项目, 比如 Knox 网关和 Sentry。志在解决 Hadoop 安全的 Rhino 项目也只是在添加 Sentry 支持时添加了 Spark 支持。否则 Spark 开发者们只能自己去提升其安全性了。

    Spark 则略显不足。 授权验证由共享秘钥机制支持,网络用户接口则通过 servlet 过滤器和事件日志保护。Spark 可以运行在 YARN 上并配合使用 HDFS, 这也就意味着它同时还拥有 Kerberos 认证授权验证,HDFS 文件许可机制和节点间的加密机制。

Spark的优点

Spark是一个高效的分布式计算系统,相比Hadoop有以下几个优势:

性能可以比Hadoop高100倍。

Spark提供比Hadoop更上层的API,同样的算法在Spark中实现往往只有Hadoop的十分之一或者一百分之一的长度。

Spark的骨干

基于对MR的理解,回忆一下分布式计算碰到的几个典型问题

  1. 分布式情况下,资源如何分配,谁负责分配资源,资源都在哪里 ?
  2. 分布式情况下,任务如何分配,任务哪里来,谁分配任务,分给谁?
  3. 分布式情况下,任务执行的时候,如何跟踪任务进度,谁统一汇总任务执行情况,下面的人如何回报任务?
  4. 分布式情况下,任务执行的时候,如何跟踪资源动态使用情况,谁负责统计所有资源情况,各个节点怎么回报资源给统计的人?

其实分布式计算框架,就这点破事,折腾不出什么新鲜花样,基于对上面问题的思考,看看spark是怎么解决的。

  1. 资源分配问题:ClusterManager负责资源分配,怎么分配由ClusterManager自己选择分配算法,资源都在Worker上面(一帮干活的兄弟),ClusterManager首先必须知道各个兄弟有什么资源,任务一旦来了(来了就需要消耗资源),ClusterManager根据实际情况切分任务,各个兄弟都摊派出一些资源(磁盘、内存、网络)来处理任务【一级分配】
  2. 任务分配问题:任务分配可以有多种方式和策略,如基于YARN,MESOS来安排任务的分配和任务执行时对任务的监控,任务来源很明显就是Driver app提交过来的。
  3. 如何跟踪执行的任务:任务的执行最后会落实到worker上,所以任务跟踪必须是work和YARN等反馈,让yarn来统一管理任务的执行情况,任务来了之后,worker内部也要调配人马,组织以一个的executor来分解任务,从而提升任务执行的效率,能并行的并行,不能 的就串行,但是每一个executor执行的情况都要汇总起来,统一由worker的某个服务一起回报给yarn,driver app(交互界面可以看到任务执行的进度)。
  4. 如何跟踪资源的使用情况:Spark 的工作节点。对 Spark 应用程序来说,由集群管理器分配得到资源的 Worker 节点主要负责以下工作:创建 Executor ,将资源和任务进一步分配给 Executor ,同步资源信息给 Cluster Manager 。

组成

心脏 - Spark core

  • 负责与下面的人打交道:与文件系统如HDFS
  • 负责与上面的人打交道:应用程序开发
  • 管理自家财产:如内存、CPU等
  • 管理自己事物:如任务的管理等

凡是要交互的功能,都和spark core有千丝万缕的联系,没有它,全都得挂

嘴巴 - Spark sql

外界通过spark sql可以快速传达要spark做什么,并且这是一个懂得BI方言的嘴巴,很容易和传统的BI家族进行交互,是外部和spark打交道的重要入口。

一个一直张开的嘴巴-spark streaming

有时候spark sql做事有点磨叽,spark streaming 就来解决,一个一直张开的嘴巴从来就不关闭,一直吃吃吃….永不停歇。

MLLIB

SPARK的开挂技能,spark很聪明,它知道有些人的脑子不够用,写不出来那些牛逼的机器学习算法,所以他准备好了葵花宝典,写不出来不要紧,按照葵花宝典就可以写出来了,分类、回归、聚类、协同等等,可扩展的Spark机器学习库,由通用的学习算法和工具组成,包括二元分类、线性回归、聚类、协同过滤、梯度下降以及底层优化原语。用于机器学习和统计等场景

GRAPHX

开挂技能,处理图计算的宝典,直接用就可以了。GraphX是用于图计算和并行图计算的新的(alpha)Spark API。通过引入弹性分布式属性图(Resilient Distributed Property Graph),一种顶点和边都带有属性的有向多重图,扩展了Spark RDD。为了支持图计算,GraphX暴露了一个基础操作符集合(如subgraph,joinVertices和aggregateMessages)和一个经过优化的Pregel API变体。此外,GraphX还包括一个持续增长的用于简化图分析任务的图算法和构建器集合。

Spark Core

Spark Core是大规模并行计算和分布式数据处理的基础引擎。它的职责有:

内存管理和故障恢复;
调度、分发和监控集群上的作业;
与存储系统进行交互。
Spark引入了RDD(弹性分布式数据集)的概念,RDD是一个不可变的容错、分布式对象集合,支持并行操作。RDD可包含任何类型的对象,可通过加载外部数据集或通过Driver程序中的集合来完成创建。

RDD支持两种类型的操作:

  1. 转换(Transformations)指的是作用于一个RDD上并会产生包含结果的新RDD的操作(例如map, filter, join, union等)
  2. 动作(Actions)指的是作用于一个RDD之后,会触发集群计算并得到返回值的操作(例如reduce,count,first等)

Spark中的转换操作是“延迟的(lazy)”,意味着转换时它们并不立即启动计算并返回结果。相反,它们只是“记住”要执行的操作和待执行操作的数据集(例如文件)。转换操作仅当产生调用action操作时才会触发实际计算,完成后将结果返回到driver程序。这种设计使Spark能够更有效地运行,例如,如果一个大文件以不同方式进行转换操作并传递到首个action操作,此时Spark将只返回第一行的结果,而不是对整个文件执行操作。

默认情况下,每次对其触发执行action操作时,都需要重新计算前面经过转换操作的RDD,不过,你也可以使用持久化或缓存方法在内存中持久化RDD来避免这一问题,此时,Spark将在集群的内存中保留这些元素,从而在下次使用时可以加速访问。

SparkSQL

SparkSQL是Spark中支持SQL语言或者Hive查询语言查询数据的一个组件。

它起先作为Apache Hive 端口运行在Spark之上(替代MapReduce),现在已经被集成为Spark的一个重要组件。除支持各种数据源,它还可以使用代码转换来进行SQL查询,功能十分强大。下面是兼容Hive查询的示例:

1
2
3
4
5
// sc is an existing SparkContext.  
val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc)
sqlContext.sql("CREATE TABLE IF NOT EXISTS src (key INT, value STRING)")
sqlContext.sql("LOAD DATA LOCAL INPATH 'examples/src/main/resources/kv1.txt' INTO TABLE src") // Queries are expressed in HiveQL
sqlContext.sql("FROM src SELECT key, value").collect().foreach(println)

Spark Streaming

Spark Streaming支持实时处理流数据,例如生产环境中的Web服务器日志文件(例如 Apache Flume和 HDFS/S3),社交媒体数据(例如Twitter)和各种消息队列中(例如Kafka)的实时数据。在引擎内部,Spark Streaming接收输入的数据流,与此同时将数据进行切分,形成数据片段(batch),然后交由Spark引擎处理,按数据片段生成最终的结果流。

Spark Streaming API与Spark Core紧密结合,使得开发人员可以轻松地同时驾驶批处理和流数据。

MLlib

MLlib是一个提供多种算法的机器学习库,目的是使用分类,回归,聚类,协同过滤等算法能够在集群上横向扩展(可以查阅Toptal中关于机器学习的文章详细了解)。MLlib中的一些算法也能够与流数据一起使用,例如使用普通最小二乘法的线性回归算法或k均值聚类算法(以及更多其他正在开发的算法)。Apache Mahout(一个Hadoop的机器学习库)摒弃MapReduce并将所有的力量放在Spark MLlib上。

GraphX

GraphX是一个用于操作图和执行图并行操作的库。它为ETL即Extraction-Transformation-Loading、探索性分析和迭代图计算提供了统一的工具。除了内置的图操作之外,它也提供了一个通用的图算法库如PageRank。

服务介绍

Hadoop和Spark的服务

image-20220411154532022

Hadoop

  • NameNode

    管理着文件系统的Namespace

  • SecondNameNode

    定期的将Namespace镜像与操作日志文件(edit log)合并,以防止操作日志文件(edit log)变得过大,它会与NameNode进行通信,以便定期地保存HDFS元数据的 快照。由于NameNode是单点的,通过Secondary NameNode的快照功能,可以将NameNode的宕机时间和数据损失降低到最小。同时,如果NameNode发生问题,Secondary NameNode可以及时地作为备用NameNode使用。

  • DataNode

    Datanode是文件系统的工作节点,他们根据客户端或者是namenode的调度存储和检索数据,并且定期向namenode发送他们所存储的块(block)的列表

  • ResourceManager

    ResourceManager负责集群中所有资源的统一管理和分配,它接收来自各个节点(NodeManager)的资源汇报信息,并把这些信息按照一定的策略分配给各个应用程序(实际上是ApplicationManager)

  • NodeManager

    NodeManager是ResourceManager在每台机器上的代理,负责容器管理,并监控它们的资源使用情况,以及向ResourceManager/Scheduler提供资源使用报告

Spark

  • Master

    资源调度系统的Leader,管理整个集群的资源信息,类似于yarn中的ResourceManager

  • Worker

    资源调度系统的slave,管理所在结点的资源信息,类似于yarn中的NodeManager