SQL on Hadoop
Apache Hive
Hive是原始的SQL-on-Hadoop解决方案。它是一个开源的Java项目,能够将SQL转换成一系列可以在标准的Hadoop TaskTrackers上运行的MapReduce任务。Hive通过一个metastore(本身就是一个数据库)存储表模式、分区和位置以期提供像MySQL一样的功能。它支持大部分MySQL语法,同时使用相似的 database/table/view约定组织数据集。Hive提供了以下功能:
- Hive-QL,一个类似于SQL的查询接口
- 一个命令行客户端
- 通过中央服务支持元数据共享
- JDBC 驱动
- 多语言 Apache Thrift 驱动
- 一个用于创建自定义函数和转换的Java API
Hive是一个几乎所有的Hadoop机器都安装了的实用工具。Hive环境很容易建立,不需要很多基础设施。鉴于它的使用成本很低,我们几乎没有理由将其拒之门外。但是需要注意的是,Hive的查询性能通常很低,这是因为它会把SQL转换为运行得较慢的MapReduce任务。
Hortonworks目前正在推进Apache Tez 的开发以便于将其作为新的Hive后端解决现在因为使用MapReduce而导致的响应时间慢的问题。
Hive简介
由Facebook开源,建立在Hadoop基础上的数据仓库基础架构。
将结构化数据文件映射为数据库表。
提供类似SQL的数据查询语句,转换为MapReduce任务执行。
本质是将SQL转换为MapReduce程序。
应用场景
数据汇总(每天/每周)
非实时分析
数据挖掘
Hive现状
面临的问题
–人员学习成本太高
–项目周期要求太短
–复杂查询与Join用MapReduce实现困难
为什么要使用Hive
–操作接口采用类SQL语法,提供快速开发的能力
–避免了去写MapReduce,减少开发人员的学习成本
–扩展功能很方便
–解决“即席查询”问题
兼容SQL是目前大数据产品的风向标
–降低平台转移成本,SQL应用平稳过渡
–降低Hadoop使用难度,让SQL技能良好Java技能较弱的程序员可以使用
Hive与传统数据库对比
Hive优缺点
优点
–海量结构化数据分析(500GB以上RDBMS就难以处理)
–高扩展性
•Hive可以自由的扩展集群的规模,一般情况下不需要重启服务
–高延展性
•Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数
–高容错性
•良好的容错性,节点出现问题SQL仍可完成执行
–将复杂MR任务编写为SQL语句,提高开发效率
–灵活的数据存储,支持
•JSON、CSV、RCFile、ORCFile、SequenceFile、TextFile和自定义格式
–可扩充UDF/UDAF/UDTF
缺点
–延迟较高,性能有提升空间
–索引不够完善,效率较低
–不支持事务类操作
Hive数据类型
Hive支持两种数据类型
–基本(原子)数据类型
–复杂(集合)数据类型
Hive数据模型
Database:相当于RDB里面的命名空间(namespace),它的作用是将用户和数据库的应用隔离到不同的数据块或模式中。
表(table):
Hive的表逻辑上由存储的数据和描述表格中的数据形式的相关元数据组成。
表存储的数据存放在分布式文件系统(如HDFS)里;元数据存储在关系数据库里。
Hive里的表有两种类型:
(1) 托管表,这种表的数据文件存储在hive的数据仓库里。
(2) 外部表,这种表的数据文件可以存放在hive数据仓库外部的分布式文件系统上,也可以放到hive数据仓库里。
分区:
(1) 是根据“分区列”的值对表的数据进行粗略划分的机制,在hive存储在就体现在表的主目录(hive的表实际上显示就是一个文件夹)下的一个子目录。
(2) 使用分区是为了加快数据分区的查询速度而设计的,我们在查询某个具体分区列里面的数据适合没必要进行全表扫描。
桶(bucket):
(1)table和partition都是目录级别的拆分数据,bucket则是对数据源数据文件本身来拆分数据。
(2)使用桶的表会将源数据文件按一定规律拆分成多个文件
(3)桶是更为细粒度的数据范围划分,它能使一些特定的查询效率更高
•比如对于具有相同的桶划分并且join的列刚好就是在桶里的连接查询
•还有就是示例数据,对于一个庞大的数据集需要拿出来一小部分作为样例
Hive底层文件格式
Hive有三种文件格式:
TextFile
建表时的默认格式,导入数据时会直接把数据文件copy到hdfs不进行处理。
SequenceFile
RCFile
Hive推出的一种专门面向列的数据格式。
SequenceFile,RCFile格式的表不能直接从本地文件导入数据,数据要先导入到textfile格式的表中,然后再从textfile表中用insert导入到SequenceFile,RCFile表中。
Hive文件格式的属性
TextFile和SequenceFile的存储格式都是基于行存储的,RCFile是基于行列混合的思想,先按行把数据分成N个row group,在row group中对每个列分别进行行存储。
Hive架构
Metastore:存储表,列好Partition等元数据,采用关系型数据库。
Driver:管理HiveQL执行的生命周期
-Compiler:编译HiveQL并将其转化为一些列相互依赖的Map/Reduce任务。
-Optimizer:优化器,分为逻辑优化器和物理优化器。
逻辑优化器:优化HiveQL生成的执行计划
物理优化器:优化MapReduce任务
-Executor:按照任务依赖关系执行MapReduce任务
Thrift Server:提供Thrift接口,作为jdbc和odbc的服务端,将hive与其他应用程序集成起来。
Clients:包含命令行接口(CLI)和JDBC/ODBC接口,为用户访问提供接口。
Web接口:用于监控和管理Hive的任务。
Hive元数据存储
单用户模式
–此模式连接到一个 In-memory 的数据库 Derby ,一般用于 Unit Test
•多用户模式
–通过网络连接到一个数据库中,是最经常使用到的模式
•远程服务器模式
–用于非 Java 客户端访问元数据库,在服务器端启动MetaStoreServer,客户端利用 Thrift 协议通过MetaStoreServer 访问元数据库
Hive编译器
Hive编译流程
Hive架构图
Cloudera Impala
Impala是一个针对Hadoop的开源的“交互式”SQL查询引擎。它由Cloudera构建,后者是目前市场上最大的Hadoop供应商之一。和Hive一样,Impala也提供了一种可以针对已有的Hadoop数据编写SQL查询的方法。与Hive不同的是它并没有使用MapReduce执行查询,而是使用了自己的执行守护进程集合,这些进程需要与Hadoop数据节点安装在一起。Impala提供了以下功能:
- ANSI-92 SQL语法支持
- HIVE-QL支持
- 一个命令行客户端
- ODBC 驱动
- 与Hive metastore互操作以实现跨平台的模式共享
- 一个用于创建函数和转换的C++ API
Impala的设计目标是作为Apache Hive的一个补充,因此如果你需要比Hive更快的数据访问那么它可能是一个比较好的选择,特别是当你部署了一个Cloudera、MapR或者Amazon Hadoop集群的时候。但是,为了最大限度地发挥Impala的优势你需要将自己的数据存储为特定的文件格式(Parquet),这个转变可能会比较痛苦。另外,你还需要在集群上安装Impala守护进程,这意味着它会占用一部分TaskTrackers的资源。Impala目前并不支持YARN。
Cloudera 已经开始尝试将Impala与YARN集成,这让我们在下一代Hadoop集群上做Impala开发的时候不再那么痛苦。
Presto
Presto是一个用Java语言开发的、开源的“交互式”SQL查询引擎。它由Facebook构建,即Hive最初的创建者。Presto采用的方法类似于Impala,即提供交互式体验的同时依然使用已有的存储在Hadoop上的数据集。它也需要安装在许多“节点”上,类似于Impala。Presto提供了以下功能:
- ANSI-SQL语法支持 (可能是ANSI-92)
- JDBC 驱动
- 一个用于从已有数据源中读取数据的“连接器”集合。连接器包括:HDFS、Hive和Cassandra
- 与Hive metastore交互以实现模式共享
Spark
Spark简介
由Berkeley实验室开发,使用scala语言开发。
全新的,高速的,类似Map/Reduce的分布式计算引擎。----支持将数据缓存在内存中,为迭代式查询进行了优化。
通用DAG执行和调度,支持延迟计算和高效优化。
轻量级的调度框架和多线程计算模型,极低的调度和启动开销。
比Hadoop快10x~100x
兼容Hadoop存储API。----可以读写存储在HDFS或HBase上的数据。支持其他数据源,需要实现Hadoop InputFormat。
Spark VS MapReduce
MapReduce模型的缺陷
只能Map+Reduce,不适合描述复杂数据处理过程,如Machine Learning,join
完成单个Map/Reduce后数据写到磁盘,在读出,数据不能共享,不适合循环模型
Spark优势
基于内存计算,使用RDD和DAG优化任务流程。
更低的框架开销
丰富的API支持,如Scala,Java,Python
Map端不强制sort,降低部分应用场景的时间开销。
Spark适用场景
机器学习和图应用中常用的迭代算法(每一步对数据执行相似的函数)
交互式数据挖掘工具(用户反复查询一个数据子集)
Spark原理介绍
Spark Application的运行架构由两部分组成:driverprogram(SparkContext)和executor。
Spark Application一般都是在集群中运行,比如SparkStandalone,YARN,mesos,这些集群给Spark Application提供了计算资源和这些资源管理,这些资源既可以给executor运行,也可以给driver program运行。
根据Spark Application的driver program是否在资源集群中运行,Spark Application的运行方式又可以分为Cluster模式和Client模式。
Spark 1.0.0提供了一个SparkApplication的部署工具bin/spark-sumbit.
Spark基本术语
Application:基于Spark的用户程序,包含了一个driverprogram和集群中多个的executor。
Driver Program:运行Application的main()函数并且创建SparkContext,通常用SparkContext代表DriverProgram。
Cluster Manager:在集群上获取资源的外部服务(例如:Standalone,Mesos,Yarn)
Worker Node:集群中任何可以运行Application代码的节点
Executor:是为某Application运行在Workernode上的一个进程,该进程负责运行Task,并且负责将数据存在内存或者磁盘上。每个Application都有各自独立的executors。
Task:被送到某个executor上的工作单元。
Job:包含多个Task组成的并行运算,往往由Sparkaction催生,该术语可以经常在日志中看到。
Stage:每个job会被拆分很多组task,每组任务被称为Stage,也可称为TaskSet,该术语可以经常在日志中看到。
RDD:Spark的基本计算单元,可以通过一系列算子进行操作(主要有Transformation和Action操作)。
DAG Schduler:根据Job构建基于Stage的DAG。并提交Stage给TaskScheduler。
Task Scheduler:将Taskset提交给worker(集群)运行并回报结果。
•构建Spark Application的运行环境(启动SparkContext)
•SparkContext向资源管理器(可以是Standalone、Mesos、Yarn)申请运行Executor资源,并启动StandaloneExecutorBackend,executor向SparkContext申请Task。
•SparkContext将应用程序代码发放给executor
•SparkContext构建成DAG图、将DAG图分解成Stage、将Taskset发送给TaskScheduler、最后由Task Scheduler将Task发放给Executor运行。
•Task在Executor上运行,运行完毕释放所有资源。
Spark on Standalone运行过程(client模式)
Spark on YARN运行过程(Cluster模式)
SparkContext
每个任务生成一个实例
SparkContext
每个SparkContext调度一部分Executor
Executor
应用程序的任务容器,任务在Executor内部运行。
Spark on yarn在Spark 1.0版本中比较成熟,但如果运行在线上环境中,面临很多挑战:
挑战1:应用程序日志如何获取?
Spark on yarn提供了应用程序运行的web界面,可以通过web界面查看spark作业的stage,task等详细信息。但无法获取应用程序的运行日志。这些日志通常保存在YARN的NodeManager节点上,一旦运行完成后可能会被聚集后保存到HDFS上。对于运行完成的作业,可以通过命令“bin/yarn logs -applicationId application_2323_xxxx”将日志打印出来,但是当日志量非常大时,显然不会很好地方法。因此,对于想把spark运行在yarn上的公司,第一个需要做的工作可能是为用户提供一个好的日志查看工具,可以查看正在运行的,或者运行完成(成功和失败)的spark作业的,在yarn-client和yarn-cluster模式下地日志。
挑战2:如何为spark作业设置资源需求?
YARN允许spark作业为driver和executor设置需要的cpu和内存资源量,但是到底设置多少最合适,不好确定。因此,最好能够提供一个资源获取工具,可以查看spark作业实际占用的内存和cpu资源量,以便修正用户的资源参数。
挑战3:yarn资源调度器对spark这类作业的水土不服。
对于yarn而言,spark仍然是一种比较特殊的作业,这使得spark难以与其他类型的应用程序(比如MapReduce)友好地运行在一个集群中。
(1) YARN中的资源调度器采用的是基于资源预留的调度机制,这种机制会使得大资源需求的作业获取资源非常慢,而spark正式这类大资源需求的作业。Spark采用的是多线程方案,这使得一个executor可能会占用很大资源,对于yarn而言,可能是资源利用率的灾难。
(2) YARN的这种资源预留机制在运行sparkstreaming作业时,可能产生饿死现象。如果你在yarn集群中运行了spark streaming作业,可能会产生资源无限预留但是永远得不到满足的情况,导致spark streaming作业用于得不到运行。这个在spark streaming与其他短类型的作业,比如spark和mapreduce作业共享集群时很容易发生。
Spark运行架构的特点
•每个Application获取专属的executor进程,该进程在Application期间一直驻留,并以多线程方式运行tasks。这种 Application隔离机制有其优势的,无论是从调度角度看(每个Driver调度它自己的任务),还是从运行角度看(来自不同 Application的Task运行在不同的JVM中)。当然,这也意味着Spark Application不能跨应用程序共享数据,除非将数据写入到外部存储系统。
•Spark与资源管理器无关,只要能够获取executor进程,并能保持相互通信就可以了。
•提交SparkContext的Client应该靠近Worker节点(运行Executor的节点),最好是在同一个Rack里,因为SparkApplication运行过程中SparkContext和Executor之间有大量的信息交换;如果想在远程集群中运行,最好使用RPC将 SparkContext提交给集群,不要远离Worker运行SparkContext。
•Task采用了数据本地性和推测执行的优化机制。
Spark的核心RDD
RDD,全称为ResilientDistributed Datasets
RDD代表一个被分区的只读数据集。
可以对RDD进行持久化,让用户显示地将数据存储到磁盘和内存中,并能控制数据的分区。
RDD还提供了一组丰富的操作来操作这些数据。
发生错误时可以自动重构。
RDD不需要物化。----RDD含有如何从其他RDD衍生(即计算)出本RDD的相关信息(即Lineage),据此可以从物理存储的数据计算出相应的RDD分区
RDD操作
创建操作
RDD的初始创建都是由SparkContext来负责的。将内存中的集合或者外部文件系统作为输入源。
转换操作
将一个RDD通过一定的操作变换成另外一个RDD;
转换时,只创建依赖关系Lineage,不实际执行;
Map,fileter,groupby,join等
控制操作
对RDD进行持久化,可以让RDD保存在磁盘或者内存中
行动操作
由于Spark是惰性计算(lazy computing)
对于RDD的行动操作都是触发Spark作业的运行,从而产生最终结果
Count,collect,save,cache等
RDD延迟计算
RDD分区(patitions)
RDD是一个分区的数据集
分区的多少涉及对这个RDD进行并行计算的力度
每一个RDD分区的计算操作都在一个单独的任务中被执行
对于RDD的分区多少,用户可以自行制定,如果没有指定,将采用默认值
目前Spark的分区函数:
HashPartitionser(哈希分区)
RangePartitioner(区域分区)
RDD优先位置
•RDD优先位置属性与Spark中的调度相关,返回的是此RDD的每个partition所存储的位置
•在Spark进行任务调度的时候,尽可能地将任务分配到数据块所存储的位置
–以从Hadoop中读取数据生成RDD为例,preferredLocations会返回每一个数据块所在的机器名或者IP地址
RDD依赖
•窄依赖narrowdependencies
–子RDD的每个分区依赖常数个父分区
•宽依赖wide dependencies
–子RDD的每个分区依赖所有父RDD
Spark采用哪种依赖
•从执行的角度考虑
–narrow dependencies可以支持在同一个clusternode上以管道形式执行多条命令
•例如在执行了map后,紧接着执行filter。
–wide dependencies需要所有的父分区都是可用的,可能还需要调用类似MapReduce之类的操作进行跨节点传递。
•从失败恢复的角度考虑
–narrow dependencies的失败恢复更有效,因为它只需要重新计算丢失的parent partition即可,而且可以并行地在不同节点进行重计算。
–而wide dependencies,一个节点的失败将会导致父RDD的多个分区重新计算 ,牵涉到RDD各级的多个ParentPartitions。
Spark的存储管理模块
Spark中的数据的存储和管理都由spark的存储管理模块来负责的。
从功能上看,spark的存储管理模块分为两个主要部分:
(1) RDD缓存
包括基于内存和磁盘的缓存
(2) Shuffle数据的持久化
Shuffle的中间结果由存储管理模块负责管理
Shuffle性能的好坏直接影响spark应用程序的整体性能,所有存储管理模块对于Shuffle的持久化管理有别于RDD的缓存
RDD分区与数据块
RDD分区与数据块的区别
---对于RDD的操作(如:转换,执行操作等)最终都是基于RDD中的分区进行的。
---但是在存储管理模块中,对于数据的存取是以数据块为单位的
---分区是逻辑上的概念,而数据块是物理上的数据实体
(1) 分区与数据块是一一对应的。一个RDD中的分区就对应存储管理模块中的一个数据块。
(2) 如何映射RDD的分区与数据块。Spark中每个RDD都有独立的ID号,而RDD中的每个分区也有独立的索引号,所以可以根据RDD的ID号和RDD内分区的索引号建立RDD分区与数据块的映射关系。
RDD的内存缓存
RDD基于内存的持久化缓存是由存储管理模块中的内存缓存(MemoryStore) 模块完成的。
内存缓存在其内部维护了一个以数据库明伟为键,块内容为值的哈希表。
内存缓存是由Java虚拟机进行管理的,对于内存还款可以使用的内存阈值可以进行配置。
配置参数:spark.storage.memoryFraction(默认值0.6)
如果大约60%的内存缓存空间占用,spark会:
丢弃一些数据块或将一些数据块存储到磁盘上
取决于:持久化选项,如果是磁盘缓存,则写道磁盘,否则直接删除。
RDD的磁盘缓存
•磁盘缓存的步骤:
–1、数据块放置在磁盘的特定目录下
•由spark.local.dir指定
–2、在磁盘缓存中,一个数据块对应着文件系统中的一个文件
RDD检查点
Lineage恢复故障:
Lineage链过长,恢复很耗时
宽依赖,需要冲洗计算所有父分区
检查点
–Lineage链过长和宽依赖的分区采用检查点机制
–将RDD物化到磁盘
DAG
Spark Application在遇到action操作时,SparkContext会生成job,并将构成DAG图将给DAGScheduler解析成Stage。
Dag(有向无环图)
--一个有向图无法从人一丁点触发经过若干条边回到改点,则这个图是一个有向无环图。
-- 受制于某些任务必须必另一些任务较早执行的限制,必须排序为一个队列的任务集合,可以由一个DAG图呈现
---每个顶点表示一个任务
---每条边表示一种限制约束
---Spark任务可以用DAG表示
Scheduler模块
scheduler 模块主要分为两大部分:
–TaskSchedulerListener
•TaskSchedulerListener部分的主要功能是监听用户提交的job,将job分解为不同的类型的stage以及相应的task,并向TaskScheduler提交task。
–TaskScheduler
•TaskScheduler 接收用户提交的task并执行。而TaskScheduler根据部署的不同又分为三个子模块:
–ClusterScheduler
–LocalScheduler
–MesosScheduler
Stage
Stage有两种:
–ShuffleMapStage
•这种Stage是以Shuffle为输出边界
•其输入边界可以是从外部获取数据,也可以是另一个ShuffleMapStage的输出
•其输出可以是另一个Stage的开始
•ShuffleMapStage的最后Task就是ShuffleMapTask
•在一个Job里可能有该类型的Stage,也可以能没有该类型Stage。
–ResultStage
•这种Stage是直接输出结果
•其输入边界可以是从外部获取数据,也可以是另一个ShuffleMapStage的输出
•ResultStage的最后Task就是ResultTask
•在一个Job里必定有该类型Stage。
•一个Job含有一个或多个Stage,但至少含有一个ResultStage。
Apache Spark的优势-DAG延迟计算
Spark Shuffle的流程
1. 每一个Mapper会根据Reducer的数量创建出相应的bucket。
--bucket是一个抽象概念,在实现中每个bucket可以对应一个文件,可以对应文件的一部分或者其它等
--bucket的数量是M*R。其中M是Map的个数,R是Reduce的个数。
2. Mapper产生的结果会根据设置的partitin算法填充到每个bucket中去。
--partition算法是可以自定义的。
--默认的算法是根据key哈希到不同的bucket中去。
3. 当Reducer启动时,会根据自己task的id和所依赖的Mapper的id从远端或是本地的blockmanager中取得相应的bucket作为Reducer的输入进行处理。
SparkShuffle的数据持久化
与RDD持久化的不同在于:
首先,Shuffle数据块必须是在磁盘上进行缓存,不能选择在内存中缓存。
其次,在RDD基于磁盘的持久化中,每一个数据块对应着一个文件,而在Shuffle数据块持久化中,Shuffle数据块表示的只是逻辑上的概念,不同的实现方式可以决定Shuffle数据块的不同存储方式。
Shuffle write
早期的Shuffle write有两个比较大的问题:
1. Map的输出必须先全部存储到内存中,然后写入磁盘。这对内存是一个非常大的开销,当内存不足以存储所有的Map output时就会出错OOM。
2. 每一个Mapper都会产生Reducer number个shuffle文件,如果Mapper个数是1k,Reducer个数也是1k,那么就会产生1M个shuffle文件,这对于文件系统是一个非常大的负担。同时在shuffle数据量不大而shuffle文件又非常多的情况下,随机写也会严重降低IO的性能。
问题一的解决:
在Spark 0.8版本中,shuffle write采用了与RDD block write不同的方式,同时也为shuffle write单独创建了ShuffleBlockManager,部分解决了0.6和0.7版本中遇到的问题。
在这个版本中为shuffle write添加了一个新的类ShuffleBlockManager,由ShuffleBlockManager来分配和管理bucket。同时ShuffleBlockManager为每一个bucket分配一个DiskObjectWriter,每个write handler拥有默认100KB的缓存,使用这个write handler将Map output写入文件中。可以看到现在的写入方式变为buckets.writers(bucketId).write(pair),也就是说Map output的key-valuepair是逐个写入到磁盘而不是预先把所有数据存储在内存中在整体flush到磁盘中去。
问题二的解决:
为了解决shuffle文件过多的情况,Spark 0.8.1引入了新的shuffle consolidation,以期显著减少shuffle文件的数量。
Shuffle consolidation的原理
假定该job有4个Mapper和4个Reducer,有2个core,也就是能并行运行两个task。我们可以算出Spark的shuffle write共需要16个bucket,也就有了16个write handler。在之前的Spark版本中,每一个bucket对应的是一个文件,因此在这里会产生16个shuffle文件。
•而在shuffleconsolidation中每一个bucket并非对应一个文件,而是对应文件中的一个segment,同时shuffle consolidation所产生的shuffle文件数量与Spark core的个数也有关系。
•在上面的图例中,job的4个Mapper分为两批运行,在第一批2个Mapper运行时会申请8个bucket,产生8个shuffle文件;而在第二批Mapper运行时,申请的8个bucket并不会再产生8个新的文件,而是追加写到之前的8个文件后面,这样一共就只有8个shuffle文件,而在文件内部这有16个不同的segment。因此从理论上讲shuffle consolidation所产生的shuffle文件数量为C×R,其中C是Spark集群的core number,R是Reducer的个数。
Spark是UC Berkeley AMP lab所开源的类HadoopMapReduce的通用并行架构,Spark拥有Hadoop MapReduce所具有的优点,但不同于MapReduce的是Job中间结果可以保存在内存中,从而不需要读写HDFS,因此Spark能更好地适用于数据挖掘与机器学习等需要迭代的MapReduce的算法。
Spark 是一种与 Hadoop 相似的开源集群计算环境,但是两者之间还存在一些不同之处,这些有用的不同之处使 Spark 在某些工作负载方面表现得更加优越,换句话说,Spark 启用了内存分布数据集,除了能够提供交互式查询外,它还可以优化迭代工作负载。
Spark是在Scala语言中实现的,他将Scala用作其应用程序框架。与Hadoop不同,Spark和Scala能够紧密基础,其中Scala 可以像操作本地集合对象一样轻松地操作分布式数据集。
尽管创建Spark是为了支持分布式数据集上的迭代作业,但是实际上它是对 Hadoop 的补充,可以在 Hadoop 文件系统中并行运行。通过名为 Mesos 的第三方集群框架可以支持此行为。Spark 由加州大学伯克利分校 AMP 实验室 (Algorithms, Machines, and People Lab) 开发,可用来构建大型的、低延迟的数据分析应用程序。
Spark生态系统
Shark
Shark基本上就是在Spark的框架基础上提供的和Hive一样的HiveQL命令接口,为了最大程度的保持和Hive的兼容性,Shark使用了Hive的API来实现Query Parsing和Logic Plan Generation,最后的PhysicalPlan execution阶段用Spark代替Hadoop MapReduce。通过配置Shark参数,Shark可以自动在内存中缓存特定的RDD,实现数据重用,进而加快特定数据集的检索。同时,Shark通过UDF用户自定义函数实现特定的数据分析学习算法,使得SQL数据查询和运算分析能结合在一起,最大化RDD的重复使用。
SparkR
SparkR是一个为R提供了轻量级的Spark前端的R包。SparkR提供了一个分布式的DataFrame数据结构,解决了R中的Data Frame只能在单机中使用的瓶颈,它和R中的Data Frame一样支持许多操作,比如select,filter,aggregate等等。(类似dplyr包中的功能)这很好的解决了R的大数据级瓶颈问题。 SparkR也支持分布式的机器学习算法,比如使用MLib机器学习库。 SparkR为Spark引入了R语言社区的活力,吸引了大量的数据科学家开始在Spark平台上直接开始数据分析之旅。
基本原理
Spark Streaming:构建在Spark上处理Stream数据的架构,基本的原理是将Stream数据分成小的时间片段(几秒),以类似batch批量处理的方式处理这小部分数据。Spark Streaming构架在Spark上,一方面是因为Spark的低延迟执行引擎(100ms+),虽然比不上专门的流式数据处理软件,也可以用于实时计算,另一方面相比基于Record的其它处理框架(如Storm),一部分窄依赖的RDD数据集可以从源数据重新计算达到容错处理目的。此外小批量处理的方式使得它可以同时兼容批量和实时数据处理的逻辑和算法。方便了一些需要历史数据和实时数据联合分析的特定应用场合。