2024.3.25讲课 Scala数据类型、运算符分类
复习:
- 定义变量: Scala 的变量分为两种,val 和 var,其区别如下:
val : 类似于 Java 中的 final 变量,一旦初始化就不能被重新赋值;
var :类似于 Java 中的非 final 变量,在整个声明周期内 var 可以被重新赋值;
- 类型推断
没有声明 a 是 Int 类型,但是程序还是把 a 当做 Int 类型,这就是 Scala 的类型推断。在大多数情况下,你都无需指明变量的类型,程序会自动进行推断。如果你想显式的声明类型,可以在变量后面指定,如下:
scala> val c:String="hello scala"
c: String = hello scala
- 字面量
Scala 和 Java 字面量在使用上很多相似,比如都使用 F 或 f 表示浮点型,都使用 L 或 l 表示 Long 类型。下文主要介绍两者差异部分。
- 整数字面量
Scala 支持 10 进制和 16 进制,但不支持八进制字面量和以 0 开头的整数字面量。
一、数据类型
Byte 8位有符号补码整数,数值区间 -128 ~ 127
short 16位有符号补码整数,数值区间 -32768 ~ 32767
Int 32位有符号补码整数,数值区间 -2147483648 ~ 2147483647
Long 64位有符号补码整数,数值区间 -9223372036854775808 ~ 9223372036854775807
Float 32位,IEEE 754标准的单精度浮点数
Double 64位 IEEE 754标准的双精度浮点数
Char 16位无符号Unicode字符,区间值为U+0000 ~ U+FFFF
String 字符序列
Boolean true或false
AnyVal 所有基础类型的父类
Unit 表示无值,和其他语言中void等同,用作不返回任何结果的方法的结果类型
Unit只有一个实例值,写成()
Null null或空一样弄,不兼容值类型
Nothing Nothing类型在Scala的类层级的最底端,它是任何其他类型的子类型
Any Any是所有其他类型的超类
AnyRef AnyRef类是Scala里所有引用类(reference class)的基类
Tuplel~22 (1,...,22)最多22个允许不同类型元素的元组
注意:
Scala 中一切数据都是对象, 都是 Any 的子类 。
2 ) Scala 中数据类型分为两大类:数值类型( AnyVal )、 引用类型(AnyRef ), 不管是值类型还是引用类型都是 对象。
3 ) Scala 数据类型仍然遵守, 低精度的值类型向高精度值类型,自动转换 (隐式转换)
4 ) Scala 中的 StringOps 是对 Java 中的 String 增强
5 ) Unit :对应 Java 中的 void ,用于方法返回值的位置,表示方法没有返回值。 Unit 是 一个数据类型 ,只有一个对象就是 () 。 Void 不是数据类型,只是一个关键字
6 ) Null 是一个类型, 只 有一个对 象就 是 null 。 它是所有引用类型(AnyRef )的子类 。
7 ) Nothing , 是所有数据类型的子类 ,主要用在一个函数没有明确返回值时使用,因为这样我们可以把抛出的返回值,返回给任何的变量或者函数。 |
- 数值类型自动转换
当 Scala 程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数值类型,这个就是自动类型转换(隐式转换)。数据类型按精度(容量)大小排序为:
( 1 )自动提升原则:有多种类型的数据混合运算时,系统首先 自动将所有数据转换成精度大的那种数据类型 ,然后再进行计算。
( 2 ) 把精度大的数值类型赋值给精度小的数值类型时,就会报错 ,反之就会进行自动类型转换。
( 3 )( byte , short )和 char 之间不会相互自动转换。
( 4 ) byte , short , char 他们三者可以计算, 在计算时首先转换为 int 类型 。
三、强制类型转换
自动类型转换的逆过程,将精度大的数值类型转换为精度小的数值类型。使用时要加上强制转函数,但可能造成精度降低或溢出,格外要注意。
如:
Java : int num = (int)2.5
Scala : var num : Int = 2.7.toInt
四、运算符 Scala 运算符的使用和 Java 运算符的使用基本相同,只有个别细节上不同。
1. 算数运算符
|
注意:( 1 )对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。
( 2 )对一个数取模 a%b ,和 Java 的取模规则一样。
- 关系运算符
|
- 逻辑运算符
|
- 赋值运算符
赋值运算符就是将某个运算后的值,赋给指定的变量。 Scala 中没有++ 、--操作符,可以通过+=、-=来实现同样的效果;
|
- 位运算符
|
注意:运算符本质在 Scala 中其实是没有运算符的,所有运算符都是方法。
1 )当调用对象的方法时, 点. 可以省略
2 )如果函数参数只有一个,或者没有参数, () 可以省略
Eg1: object TestOpt {
def main(args: Array[String]): Unit = {
// 标准的加法运算
val i:Int = 1.+(1)
// (1)当调用对象的方法时,.可以省略
val j:Int = 1 + (1)
// (2)如果函数参数只有一个,或者没有参数,()可以省略
val k:Int = 1 + 1
println(1.toString())
println(1 toString())
println(1 toString)
- 运算符的优先级
操作符的优先级如下:优先级由上至下,逐级递减。
|
六、练习题
1. 编写scala程序,完成以下功能: 假设有整型变量x,判断x是否为偶数,若为偶数,则在控制台上打印“输入的数值是偶数”。无论x是否为偶数,最后都要在控制台上输出x的值
object EvenNumbers {
def main(args: Array[String]): Unit = {
var x = 2
if (x%2==0){
println("输入的数值是偶数")
}else{
println(x)
}
println(x)
}
}
2、有两个整型变量x,y,请在控制台上输出x与y中值较大的那个数
object CompareSize {
def main(args: Array[String]): Unit = {
var x=3
var y=5
if (x>y){
print(x)
}else{
print(y)
}
}
}
3、计算1+2+3+…+100的和
def main(args: Array[String]): Unit = {
var i = 1
var sum = 0
while (i <= 100){
sum = sum + i
i=i+1
}
print("1+2+3...+100之和为"+sum)
}
}
4、计算从1到100的所有奇数相加
object Count2 {
def main(args: Array[String]): Unit = {
var i = 1
var sum = 0
while (i <= 100){
if (i%2!=0){
sum=sum+i
}
i=i+1
}
print("1-100的奇数和为:"+sum)
}
}
5、用for循环来改写1加到100
object Count4 {
def main(args: Array[String]): Unit = {
var sum = 0
for (i <- 1 to 100) {
sum += i
}
System.out.println("1到100累加的和为:" + sum)
}
}
6、创建一个List val list0 = List(1,7,9,8,0,3,5,4,6,2)
将list0中每个元素乘以10后生成一个新的集合
object Dome1 {
def main(args: Array[String]): Unit = {
val List0 = List(1,7,9,8,0,3,5,4,6,2)
var result = for {x <- List0}yield x*10
println(result)
}
}
7、利用条件运算符的嵌套来完成此题:学习成绩》=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。
object Dome4 {
def main(args: Array[String]): Unit = {
println("请输入一个成绩:")
var s = new Scanner(System.in)
var i = s.nextInt()
if (i>=90){
println("A")
}else if(i>=60 && i<=89){
println("B")
}else if (i<60){
println("C")
}
}
}
2024.4.1讲课 Scala数组
一、数组定义、赋值
1. 数组概念
数组是一种可变的、可索引的数据集合。在scala中数组中的数据类型必须一致。在Scala中用Array[T]的形式来表示。java中的数组形式T[ ]。
2、数组定义格式 //声明一个数组对象
方法一:var numbers=new Array[String](3)
方法二:val numbers = Array(1, 2, 3, 4)
获取数组长度: 数组名.length 或数组名.size
Eg1: val first = numbers(0) // 读取第一个元素
numbers(3) = 100 // 替换第四个元素为100
val biggerNumbers = numbers.map(_ * 2) // 所有元素乘2
3、数组赋值
赋值基本格式: 数组名(下标) = 值
4、 数组的遍历输出:
for(x<-数组名){
println(x)
}
5、变长数组 ArrayBuffer
要先导包: import scala.collection.mutable.ArrayBuffer
变长数组定义格式: var 数组明 = ArrayBuffer(数组值)
例如: 定义一个具有10个元素的数组,给赋随机值,求和并输出。
Import scala.util.Random
Object Main{
def main(args:Array[String]):Unit={
var num:Array[Int] = new Array[Int](10)
var random = new Random()
var sum:Int = 0
for(i<- 0 until 10){
num(i) = random.nextInt(100)
sum += num(i)
}
println(sum)
}
}
二、数组操作
1. ++ 合并集合(并返回一个新的数组,新数组包含左右两个集合对象的内容)
Eg2: var c = Array(2,3,4,67,88)
var a = Array(56,3,32,54)
c++a
res:Array[Int] = Array(2,3,4,67,88,56,3,32,54)
2.数组常用算法
添加元素 +=
删除元素 -=
追加元素 ++= (追加一个数组到变长数组)
求和 sum
求最大值 max()
求最小值 min()
排序 sorted()
3、遍历数组:遍历数组有2种方式
使用for表达式直接遍历书中的元素;
使用索引遍历数组中的元素;
4、++:
def ++:[B >: A, That] (that: collection.Traversable[B])(implicit bf:CanBuildFrom[Array[T], B, That]): That
这个方法同上一个方法类似,两个加号后面多了一个冒号,但是不同的是右边操纵数的类型决定着返回结果的类型。下面代码中Array和LinkedList结合,返回结果的类型是LinkedList。
Eg3: var arr = Array(1,2,3,4,5,6)
var lst = LinkedList(45,34,33,22)
arr.++:lst
res:LinkedList[Int] = LinkedList(1,2,3,4,5,6,45,34,33,22)
补充:链表List https://blog.csdn.net/baidu_29609961/article/details/130987630
- 流程控制语句
https://blog.csdn.net/d905133872/article/details/129555843
- 分支语句
Scala中没有switch语句
- for循环
- 范围数据循环(Until
四、函数定义
1. 函数的概念
定义函数最通用的方法是作为某个类或者单例对象的成员,这种函数被称为方法
2、定义格式
def 方法名 (参数列表) : 结果类型 = {方法体}
例:def counter(value: Int): Int = {
value += 1
}
Eg4: 定义一个函数,比较两个数大小,输出大数
def max(x: Int, y: Int): Int = {
if (x > y)
x
else
y
}
注意问题:
- 当参数只有一个时,圆括号可以省略
- 只有存在多个参数时(不同参数之间用逗号隔开),圆括号才是必须的
六、实操练习题
1. 定义一个具有10个元素的数组,给赋随机值,并按升序输出数组元素
2. 使用scala编程实现输出等边三角形
3.使用scala编程实现菱形图案
4. 编写一个循环,将整数数组中相邻的元素置换。比如Array(1, 2, 3, 4, 5)置换后为Array(2, 1, 4, 3, 5)
5. 编写一个自定义函数,实现输出数组的最大值和最小值。
2024.4.8 元组
一、元组
1. 元组的概念
元组是用来存储多个不同类型的值。且元组的长度和元素都是不可变的。
2.定义格式
格式1:通过()来定义
var/val 元组名 = (元素1,元素2....)
格式2:通过箭头 -> 来定义(只适合于元组中只有两个元素的情况)
var/val 元组名 = 元素1->元组2
例1: 定义一个元组,包括学生的姓名和年龄
var stu1 = (“张三”,21)
var stu2 = “李四”->20
printf(stu1)
printf(stu1)
3、访问元组中元素
Scala中,可以通过元组名._编号的形式来访问元组中的元素,_1表示访问第一个元素,以此类推;也可以通过元组名.productIterator的方式,来获取该元组的迭代器,从而实现遍历元组
格式一:访问元组中的单个元组
println(元组名._1) //打印元组的第一个元素 println(元组名._2) //打印元组的第二个元素
格式二:遍历元组
val tuple1 = (值1, 值2, 值3...) //可以有多个值 val it = tuple1.productIterator //获取当前元组的迭代器对象 for(i <- it) println(i)
例2: 定义一个元组,包括姓名和性别,分别获取该学生的姓名和性别,并输出。
class ClassDemo {
def main(args: Array[String]): Unit = {
//1.
val tup1 = "张三" -> "男"
//2.
//方式一:通过_编号获取,编号是从1开始技术的
println(tup1._1)
println(tup1._2)
//方式二:通过迭代器遍历
val it = tup1.productIterator
for (i<-it) {
println(i)
}
}
}
二、列表
1. 列表是什么
列表是Scala最重要也是最常用的一种数据结构。
它存储的数据的特点是:有序,可重复。
- 有序 - 元素存入顺序和取出顺序是一致的
- 可重复 - 列表中可以添加重复元素
2、列表分类
Scala中列表分为不可变列表和可变列表。
1)不可变列表:不可表列表的元素、长度都是不可变的。
定义格式1:通过小括号直接初始化
val/var 变量名 = List(元素1, 元素2, 元素3...)
格式2:通过Nil创建一个空列表
val/var 变量名 = Nil
格式3:使用 :: 方法实现 (必须在最后添加一个Nil)
val/var 变量名 = 元素1 :: 元素2 :: Nil
例3:创建一个不可变列表,存放以下几个元素(1,2,3,4,5)
使用Nil创建一个不可变的变的空列表;
使用:: 创建列表,包含上面的2个列表
val list1 = List(1, 2, 3, 4)
val list2 = Nil
val list3 = list1::list2::Nil
//4.打印结果
println(list1)
println(list2)
println(list3)
3、可变列表
可变列表的元素、长度都是可变的。要使用可变列表,必须先导包。
import scala.collection.mutable.ListBuffer
1)创建可变列表
格式1:使用ListBuffer元素类型创建空的可变列表
val/var 变量名 = ListBuffer[数据类型]()
格式2:使用ListBuffer(元素1, 元素2, 元素3…)创建可变列表
val/var 变量名 = ListBuffer(元素1, 元素2, 元素3...)
注意:可变集合都在mutable包中,不可变集合都在immutable包中(默认导入)
例4:创建空的整形可变列表 val a = ListBuffer[Int]()
2024.6.14-期末复习
一、Spark 简介
Spark 项目包含多个紧密集成的组件。Spark 的核心是一个对由很多计算任务组成的、运行在多个工作机器或者是一个计算集群上的应用进行调度、分发以及监控的计算引擎。
1、Spark Core
Spark Core 实现了 Spark 的基本功能,包含任务调度、内存管理、错误恢复、与存储系统交互等模块。Spark Core 中还包含了对弹性分布式数据集(resilient distributed dataset,简称 RDD)的 API 定义。RDD 表示分布在多个计算节点上可以并行操作的元素集合,是Spark 主要的编程抽象。Spark Core 提供了创建和操作这些集合的多个 API。
2、Spark SQL
Spark SQL 是 Spark 用来操作结构化数据的程序包。通过 Spark SQL,我们可以使用 SQL或者 Apache Hive 版本的 SQL 方言(HQL)来查询数据。Spark SQL 支持多种数据源,比如 Hive 表、Parquet 以及 JSON 等。除了为 Spark 提供了一个 SQL 接口,Spark SQL 还支持开发者将 SQL 和传统的 RDD 编程的数据操作方式相结合,不论是使用 Python、Java 还 是 Scala,开发者都可以在单个的应用中同时使用 SQL 和复杂的数据分析。通过与 Spark所提供的丰富的计算环境进行如此紧密的结合,Spark SQL 得以从其他开源数据仓库工具中脱颖而出。Spark SQL 是在 Spark 1.0 中被引入的。
3、Spark Streaming
Spark Streaming 是 Spark 提供的对实时数据进行流式计算的组件。比如生产环境中的网页服务器日志,或是网络服务中用户提交的状态更新组成的消息队列,都是数据流。Spark Streaming 提供了用来操作数据流的 API,并且与 Spark Core 中的 RDD API 高度对应。这样一来,程序员编写应用时的学习门槛就得以降低,不论是操作内存或硬盘中的数据,还是操作实时数据流,程序员都更能应对自如。从底层设计来看,Spark Streaming 支持与Spark Core 同级别的容错性、吞吐量以及可伸缩性。
4、集群管理器
就底层而言,Spark 设计为可以高效地在一个计算节点到数千个计算节点之间伸缩计算。为了实现这样的要求,同时获得最大灵活性,Spark 支持在各种集群管理器(cluster manager)上运行,包括 Hadoop YARN、Apache Mesos,以及 Spark 自带的一个简易调度,叫作独立调度器。如果要在没有预装任何集群管理器的机器上安装 Spark,那么 Spark自带的独立调度器可以让你轻松入门;而如果已经有了一个装有 Hadoop YARN 或 Mesos的集群,通过 Spark 对这些集群管理器的支持,你的应用也同样能运行在这些集群上。
二、Scala的REPL(Read-Eval-Print Loop)
REPL环境是一个交互式的编程工具,可以让你直接在命令行中输入代码并立即执行。以下是使用Scala REPL环境进行交互式编程的步骤:
打开终端窗口,并输入命令“scala”来启动Scala的REPL环境。
输入Scala代码并按Enter键执行代码。例如,可以输入简单的数学表达式或变量赋值语句:
例1: 以下关于Scala的变量定义、赋值的代码,运行后一定会报错的是
val a = 5
val a:String = "Math”
var b:Int = 3; b = 6
val b = "Hello World!"; b = "World”
三、常见知识点
1、 元组特点:
元组(tuple)是一种不可变的序列类型。它和列表非常类似,甚至可以理解为是一种不可修改的列表。
那他和列表到底有什么区别呢?不可变性:一旦创建了一个元组,你就不能更改、添加或删除其中的任何元素。
●使用圆括号:元组使用圆括号 () 来定义,而列表使用方括号 []
●可哈希性:由于元组是不可变的,它们可以用作字典的键,而列表则不能。
●多值赋值:当你将一个元组赋值给多个变量时,这些变量将分别存储元组中的每个值。这与列表不同,列表会尝试将整个列表赋值给多个变量,这会导致类型错误。(这可以让我们想到函数的多个返回值,实际上是返回了一个元组(tuple))
例2:以下关于元组说法错误的是
元组可以包含不同类型的元素
元组是不可变的
访问元组第一个元素的方式为pair._l
元组最多有2个元素
2、Scala如何定义列表:
Scala 列表类似于数组,它们所有元素的类型都相同,
但是它们也有所不同:列表是不可变的,值一旦被定义var list1 = List(1,2,3)
list1.foreach(x => println(x))
println(list1(0),list1(2))
println("------change ele-----------")
//list1(0) = 9999 //error : value update is not a member of List[Int]
println(list1(0))
定义:
两种方法 List() 构造 使用 :: Nil 构造
例3:在Scala语言中,关于列表的定义,不正确的是
val list:List[Int] = List(l,2,3)
val list = List[Int](l,2,3)
val list = List[String]('a', 'b', 'c')
val list = List[String]()
4、类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。
在Scala中,我们必须初始化字段,方法默认是共有的,类并不声明为public,一个Scala源文件中可以有多个类。类的最简单的形式和Java或C++相似,例如用Class定义一个名为Counter的类:
class Counter {
private var value = 0
def increment() { value += 1}
def current() = value
}
能够构造对象,并按照通常的方式来调用方法,我们可以使用new关键字来创建类的对象。调用无参数的方法时,我们也可以不写()
val myCounter = new Counter() // or new Counter
myCounter.increment() // or myCounter.increment
单例对象
在Scala中没有静态方法或静态字段,但是它也为我们提供了单例模式的实现方法,那就是使用关键字object。Scala中使用单例模式时,除了定义的类之外,还要定义一个同名的object对象,它和类的区别是,object对象不能带参数。
例4:创建单例对象
// 生成一个object类,也叫单例对象
object Accounts {
// 声明私有成员变量lastNumber
private var lastNumber = 0
// 定义成员函数,其作用为将lastNumber成员变量值增加1,并输出
def newUniqueNumber() = { lastNumber += 1; println(lastNumber)}
}
// 调用单例对象的newUniqueNumber()成员变量方法
Accounts.newUniqueNumber()
总结一下:Scala中,类和单例对象的差别在于,单例对象不能带参数,而类可以。因为单例对象无法使用 new关键字实例化,也就没有办法为它传递实例
例5:以下关于Scala的类和单例对象之间的差别描述正确的是
单例对象不可以定义方法,而类可以
单例对象不可以带参数,而类可以
单例对象不可以定义私有属性,而类可以
单例对象不可以继承,而类可以
5、对于RDD1((a, 1), (b, 2), (c, 3))和 RDD2((b, 4), (b, 5), (a, 6)),使用"RDDl.join(RDD2)”,得到的结果是
三、Spark集群常见运行环境
Local 模式:
在本地模式下,Spark 将作为一个单独的 Java 进程在本地运行,不需要启动额外的集群资源。本地模式适用于开发和调试,可以快速运行 Spark 应用程序并查看结果,而不需要配置和管理集群资源。
Standalone 模式:
Standalone 模式是 Spark 提供的最简单的部署方式,也是默认的部署模式。在 Standalone 模式下,Spark 自身作为一个独立的集群运行,可以通过启动 Spark Master 和 Spark Worker 进程来启动一个完整的 Spark 集群。Standalone 模式适用于开发和测试环境,也可以用于小型生产环境。
Apache Hadoop YARN:
YARN(Yet Another Resource Negotiator)是 Hadoop 2.x 提供的资源管理器,用于在 Hadoop 集群上管理资源和调度作业。
Spark 可以作为 YARN 上的一个应用程序运行,通过 YARN 向 Hadoop 集群申请资源并执行作业。在 YARN 上运行 Spark 可以充分利用 Hadoop 集群的资源管理和调度能力,适用于大规模生产环境。
Scala是纯粹的面向对象的语言,每个值都是对象,每个操作都是方法调用
Scala是一门多范式的编程语言,一种类似java的编程语言,设计初衷是实现可伸缩的语言 、并集成面向对象编程和函数式编程的各种特性。
思考以下问题:
四、架构设计
Spark运行架构包括集群资源管理器(Cluster Manager)、运行作业任务的工作节点(Worker Node)、每个应用的任务控制节点(Driver)和每个工作节点上负责具体任务的执行进程(Executor)。其中,集群资源管理器可以是Spark自带的资源管理器,也可以是YARN或Mesos等资源管理框架。
与Hadoop MapReduce计算框架相比,Spark所采用的Executor有两个优点:一是利用多线程来执行具体的任务(Hadoop MapReduce采用的是进程模型),减少任务的启动开销;二是Executor中有一个BlockManager存储模块,会将内存和磁盘共同作为存储设备,当需要多轮迭代计算时,可以将中间结果存储到这个存储模块里,下次需要时,就可以直接读该存储模块里的数据,而不需要读写到HDFS等文件系统里,因而有效减少了IO开销;或者在交互式查询场景下,预先将表缓存到该存储系统上,从而可以提高读写IO性能。
五、Spark运行基本流程
Spark的基本运行流程如下:
(1)当一个Spark应用被提交时,首先需要为这个应用构建起基本的运行环境,即由任务控制节点(Driver)创建一个SparkContext,由SparkContext负责和资源管理器(Cluster Manager)的通信以及进行资源的申请、任务的分配和监控等。SparkContext会向资源管理器注册并申请运行Executor的资源;
(2)资源管理器为Executor分配资源,并启动Executor进程,Executor运行情况将随着“心跳”发送到资源管理器上;
(3)SparkContext根据RDD的依赖关系构建DAG图,DAG图提交给DAG调度器(DAGScheduler)进行解析,将DAG图分解成多个“阶段”(每个阶段都是一个任务集),并且计算出各个阶段之间的依赖关系,然后把一个个“任务集”提交给底层的任务调度器(TaskScheduler)进行处理;Executor向SparkContext申请任务,任务调度器将任务分发给Executor运行,同时,SparkContext将应用程序代码发放给Executor;
(4)任务在Executor上运行,把执行结果反馈给任务调度器,然后反馈给DAG调度器,运行完毕后写入数据并释放所有资源。
Spark的特点
1.运行速度迅速:
Spark基于内存进行计算(当然也有部分计算基于磁盘,比如shuffle),内存计算下,Spark 比 Hadoop 快100倍。
2.容易上手开发:Spark的基于RDD的计算模型,比Hadoop的基于Map-Reduce的计算模型要更加易于理解,更加易于上手开发,实现各种复杂功能,比如二次排序、topn等复杂操作时,更加便捷。
3.超强的通用性:Spark提供了Spark RDD、Spark SQL、Spark Streaming、Spark MLlib、Spark GraphX等技术组件,可以一站式地完成大数据领域的离线批处理、交互式查询、流式计算、机器学习、图计算等常见的任务。
4.集成Hadoop:Spark并不是要成为一个大数据领域的“独裁者”,一个人霸占大数据领域所有的“地盘”,而是与Hadoop进行了高度的集成,两者可以完美的配合使用。Hadoop的HDFS、Hive、HBase负责存储,YARN负责资源调度;Spark复杂大数据计算。实际上,Hadoop+Spark的组合,是一种“double win”的组合。
5.极高的活跃度:Spark目前是Apache基金会的顶级项目,全世界有大量的优秀工程师是Spark的committer。并且世界上很多顶级的IT公司都在大规模地使用Spark。
七、Spark架构有哪些组件
序号 | 组件名 | 功能 |
1 | Spark Core | Spark Core是Spark的核心组件,负责数据存储和计算。它提供了一个基础的分布式计算框架,可以处理批量数据和流式数据。Spark Core的主要组件包括: SparkConf:配置参数,用于设置Spark应用的一些基本参数。 SparkContext:上下文对象,用于创建RDD、提交任务等。 Resilient Distributed Datasets(RDD):RDD是Spark的核心数据结构,是一个分布式的、不可变的、有类型的数据集合。 |
2 | Spark SQL | Spark SQL是Spark的一个组件,用于处理结构化数据。它提供了一个SQL解析器,可以将SQL查询转换为RDD操作。Spark SQL支持多种数据源,如HDFS、Hive、Parquet等,并且可以与其他Spark组件进行无缝集成。 |
3 | Spark Streaming | Spark Streaming是Spark的一个组件,用于处理流式数据。它可以将流式数据转换为RDD,并且可以与其他Spark组件进行无缝集成。Spark Streaming支持多种数据源,如Kafka、Flume、Twitter等,并且可以实现实时数据处理。 |
4 | MLlib | MLlib是Spark的一个组件,用于机器学习和数据挖掘。它提供了多种机器学习算法,如梯度下降、随机梯度下降、K-Means等,并且可以与其他Spark组件进行无缝集成。 |
Spark的各个组件之间是相互联系的。Spark Core提供了一个基础的分布式计算框架,Spark SQL、Spark Streaming和MLlib都基于Spark Core进行扩展,实现了数据处理、流式数据处理和机器学习等功能。这些组件之间可以相互调用,实现无缝集成,提高开发效率。
八、画Hadoop+Spark完全分布式集群拓扑图