Spark(这里只谈批处理)必知

1.what这个技术是什么

官方文档定义

Apache Spark™ is a unified analytics engine for large-scale data processing. 就是大数据分析引擎,至于unified(统一),应该是因为下图。

Combine SQL, streaming, and complex analytics.

Spark powers a stack of libraries including SQL and DataFramesMLlib for machine learning, GraphX, and Spark Streaming. You can combine these libraries seamlessly in the same application.

 

对比同类技术的优缺点,适用场景

MapReduce架构:

MapReduce的处理技术符合使用键值对的map、shuffle、reduce算法要求。基本处理过程包括:

从HDFS文件系统读取数据集

将数据集拆分成小块并分配给所有可用节点

针对每个节点上的数据子集进行计算(计算的中间态结果会重新写入HDFS)

重新分配中间态结果并按照键进行分组

通过对每个节点计算的结果进行汇总和组合对每个键的值进行“Reducing”

将计算而来的最终结果重新写入 HDFS

优势和局限

由于这种方法严重依赖持久存储,每个任务需要多次执行读取和写入操作,因此速度相对较慢。但另一方面由于磁盘空间通常是服务器上最丰富的资源,这意味着MapReduce可以处理非常海量的数据集。同时也意味着相比其他类似技术,Hadoop的MapReduce通常可以在廉价硬件上运行,因为该技术并不需要将一切都存储在内存中

spark架构:

Spark的数据处理工作全部在内存中进行,只在一开始将数据读入内存,以及将最终结果持久存储时需要与存储层交互。所有中间态的处理结果均存储在内存中。

Spark在处理与磁盘有关的任务时速度也有很大提升,因为通过提前对整个任务集进行分析可以实现更完善的整体式优化。为此Spark可创建代表所需执行的全部操作,需要操作的数据,以及操作和数据之间关系的Directed Acyclic Graph(有向无环图),即DAG,借此处理器可以对任务进行更智能的协调。(就是分stage,同一stage可以并发进行)

Spark会使用一种名为Resilient Distributed Dataset(弹性分布式数据集),即RDD的模型来处理数据。这是一种代表数据集,只位于内存中,永恒不变的结构。针对RDD执行的操作可生成新的RDD。每个RDD可通过世系(Lineage)回溯至父级RDD,并最终回溯至磁盘上的数据。Spark可通过RDD在无需将每个操作的结果写回磁盘的前提下实现容错

启动时延

注意,本文的多进程和多线程,指的是同一个节点上多个任务的运行模 式。无论是MapReduce和Spark,整体上看,都是多进程:MapReduce应用程序是由多个独立的Task进程组成的;Spark应用程序的 运行环境是由多个独立的Executor进程构建的临时资源池构成的。

多进程模型便于细粒度控制每个任务占用的资源,但会消耗较多的启动时间,不适合运行低延迟类型的作业,这是MapReduce广为诟病的原因之一。而多线程模型则相反,该模型使得Spark很适合运行低延迟类型的作业。总之,Spark同节点上的任务以多线程的方式运行在一个JVM进程中,可带来以下好处:

1)任务启动速度快,与之相反的是MapReduce Task进程的慢启动速度,通常需要1s左右;

2)同节点上所有任务运行在一个进程中,有利于共享内存。这非常适合内存密集型任务,尤其对于那些需要加载大量词典的应用程序,可大大节省内存。

3) 同节点上所有任务可运行在一个JVM进程(Executor)中,且Executor所占资源可连续被多批任务使用,不会在运行部分任务后释放掉,这避免 了每个任务重复申请资源带来的时间开销,对于任务数目非常多的应用,可大大降低运行时间。与之对比的是MapReduce中的Task:每个Task单独 申请资源,用完后马上释放,不能被其他任务重用,尽管1.0支持JVM重用在一定程度上弥补了该问题,但2.0尚未支持该功能。

 

尽管Spark的多线程模型带来了很多好处,但同样存在不足,主要有:

1)由于同节点上所有任务运行在一个进程中,因此,会出现严重的资源争用,难以细粒度控制每个任务占用资源。与之相 反的是MapReduce,它允许用户单独为Map Task和Reduce Task设置不同的资源,进而细粒度控制任务占用资源量,有利于大作业的正常平稳运行。

 

此技术的架构组成

宏观

  1. 构建Spark Application的运行环境,启动SparkContext
  2. SparkContext向资源管理器(可以是Standalone,Mesos,Yarn)申请运行Executor资源,并启动StandaloneExecutorbackend,
  3. Executor向SparkContext申请Task
  4. SparkContext将应用程序分发给Executor
  5. SparkContext构建成DAG图,将DAG图分解成Stage、将Taskset发送给Task Scheduler,最后由Task Scheduler将Task发送给Executor运行
  6. Task在Executor上运行,运行完释放所有资源

微观dag

1.RDD的操作排列,每个操作(transform或者action)都会生成新RDD,也就是有依赖的RDD之间的关系,比如RDD1------->RDD2(RDD1生成RDD2),RDD2依赖于RDD1。

2.区分依赖

 

3.用依赖区分stage(同一个stage里面的task是可以并发执行的,下一个stage要等前一个stage ready)

https://blog.csdn.net/abcd1101/article/details/86562880

 

2.why为什么有这个技术

此技术解决什么问题

Spark可以将Hadoop集群中的应用在内存中的运行速度提升100倍。

 1. Spark是基于内存的迭代计算框架,适用于需要多次操作特定数据集的应用场合。需要反复操作的次数越多,所需读取的数据量越大,受益越大,数据量小但是计算密集度较大的场合,受益就相对较小;

  2. 由于RDD的特性,Spark不适用那种异步细粒度更新状态的应用,例如web服务的存储或者是增量的web爬虫和索引。就是对于那种增量修改的应用模型不适合:

  3. 数据量不是特别大,但是要求实时统计分析需求。(海量用mapreduce,大量用spark,实时用flink?)

  满足以上条件的均可采用Spark技术进行处理,在实际应用中,目前大数据在互联网公司主要应用在广告、报表、推荐系统等业务上,在广告业务方面需要大数据做应用分析、效果分析、定向优化等,在推荐系统方面则需要大数据优化相关排名、个性化推荐以及热点点击分析等。

  这些应用场景的普遍特点是计算量大、效率要求高,Spark恰恰可以满足这些要求,该项目一经推出便受到开源社区的广泛关注和好评,并在近两年内发展成为大数据处理领域炙手可热的开源项目。

 

3.how怎么学这个技术

quickstart

https://blog.csdn.net/abcd1101/article/details/86562778

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你想在离线的Spark作业中将数据写入Kafka,你可以使用`foreachPartition`函数来实现。这将允许你对数据分区进行迭代,并在每个分区上创建一个Kafka生产者来写入数据。 下面是一个使用离线Spark批处理来将数据写入Kafka的示例代码: ```scala import org.apache.kafka.clients.producer.{KafkaProducer, ProducerRecord} import org.apache.spark.sql.{SparkSession, DataFrame} object KafkaWriter { def main(args: Array[String]): Unit = { val spark = SparkSession.builder() .appName("KafkaWriter") .master("local[*]") // 替换为你的Spark Master URL .getOrCreate() // 读取表数据 val tableDF = spark.read .format("jdbc") .option("url", "jdbc:mysql://localhost:3306/database") // 替换为你的数据库连接URL .option("dbtable", "table_name") // 替换为你要读取的表名 .option("user", "username") // 替换为你的数据库用户名 .option("password", "password") // 替换为你的数据库密码 .load() // 写入Kafka writeToKafka(tableDF, "your_kafka_topic") // 替换为你的Kafka主题名 spark.stop() } def writeToKafka(df: DataFrame, topic: String): Unit = { df.foreachPartition { partition => val kafkaProps = new java.util.Properties() kafkaProps.put("bootstrap.servers", "localhost:9092") // 替换为你的Kafka broker地址 kafkaProps.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer") kafkaProps.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer") val producer = new KafkaProducer[String, String](kafkaProps) partition.foreach { row => val key = row.getAs[String]("key") val value = row.getAs[String]("value") val record = new ProducerRecord[String, String](topic, key, value) producer.send(record) } producer.close() } } } ``` 在上述代码中,你需要替换以下内容: - Spark的Master URL (`master`),例如 `local[*]`。 - 数据库连接URL (`url`),例如 `jdbc:mysql://localhost:3306/database`,其中 `localhost:3306` 是你的数据库主机和端口,`database` 是你的数据库名。 - 要读取的表名 (`dbtable`)。 - 数据库用户名 (`user`) 和密码 (`password`)。 - Kafka broker地址 (`bootstrap.servers`),例如 `localhost:9092`。 - 要写入的Kafka主题名 (`topic`)。 请确保你已经正确配置了Kafka和表的连接信息,以及相关依赖库。运行代码后,它将使用离线Spark作业读取表数据,并将数据写入到指定的Kafka主题中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值