spark零基础 到WordCount编程

1 SCALA基础

1.1 变量

var和val的区别??

scala中的返回值是执行代码块的最后一行代码,不使用return语句返回结果;如果在for或者while等循环语句中,可以使用return返回结果

if(condition){


}else{
       

}

1.2 下滑线的作用

  1. var变量初始化的时候给定默认值
  2. 在函数赋值给一个变量的时候,使用下滑线表示参数的占位
  3. 高阶函数中下滑线表示参数的占位
  4. 在模式匹配中,下划线表示匹配所有
  5. 在import导入包的时候,下划线表示导入所有子包或者包中的类,类似java的*

1.3 scala中有一个非常特殊的数字 ==> 22

  1. 匿名函数中最多支持22个输入参数
  2. case class中最多支持22个属性(在主构造函数中定义)
  3. Tuple最多支持22元组

1.4 函数

1. 4.1 定义:

​ f: T => U 表示一个函数f,输入参数列表是T,返回值类型为U

def max(x:Int, y:Int):Int = if (x > y) x else y 
1.4.2 函数的调用
val maxResult = max(5, 10)

函数赋值给一个变量

val max2 = max _

max2: (Int, Int) => Int

val a = (x:Int, y:Int) => if (x > y) x else y 
1.4.3匿名函数
(x:Int, y:Int) => if (x > y) x else y 

这个就叫做匿名函数,匿名函数一般赋值给一个变量然后再使用

val max3 = (x:Int, y:Int) => if (x > y) x else y

max3(1,3)
1.4.4高阶函数

​ 如果一个函数f接收其它函数g作为输入参数,那么函数f就叫做高阶函数

​ eg:

def f(g: Int => Int) {println(g(10))}

 def g1(a:Int) = a * 2

 def g2(a:Int) = a * 3

高阶函数调用省略过程

  1. 可以省略输入参数的类型

    f((a:Int) => a * 2)
    
  2. 如果输入参数列表中只有一个参数的话,那么可以省略输入参数的小括号

    f(a => a * 2)
    
  3. 如果左侧的参数列表中的参数在右侧的函数体中有且仅使用一次,并且使用的顺序和参数列表中的参数属性一致,那么可以使用下划线来代替参数(前提:使用下划线代替后,可以推断出数据类型)

 f(_ * 2)

mapflatMap 的区别

相同点:

都是对原始集合中的数据进行处理,然后返回一个新的集合,新集合中的元素和调用map/flatMap API的时候给定的参数函数有关;都对原始集合中的所有原始进行给定函数的处理

不同点:

map api返回的新集合中的元素就是给定参数函数的返回值

flatMap API要求给定的参数函数f必须返回一个集合,最终形成的新集合中的元素是函数f返回集合中的元素;实质是在map的基础上做了一个扁平化操作

Option

Scala中表示有值无值的一个class

Some表示有值 Some()

None表示无值

 val c = Map("a"->16,"v"->89)

c("b")

c.getOrElse("b",-1)

c.get("b") = None

c.get("a") = Some(16).get

1.5 Try

scala中表示代码块执行是否有异常的一个class

Success表示执行成功,可以获取执行成功的结果

Failure表示有异常

1.6 隐式转换
 val str:String = 123  

 //定义一个隐式转换函数即可

implicit def int2String(i:Int) = {
     println("int 2 string")
    i.toString
}

1.7 常见的符号

  • : =》 数据类型 或者函数的返回类型 在IDEA使用 alt+Enter
  • <- =》 for (i <- 0 until 9)
  • -> =》 val a = Map(“key” -> value)
  • :: =》 val a = 1::2::Nil
  • => =》 匿名函数 (a:Int) => a+2
  • +/+= ++/++= =》在变长数组ArrayBuffer ListBuffer使用 += 和++=添加元素

2、大数据的起源及发展

大数据改变世界,Spark改变大数据 大数据 大数据技术,HADOOP 2.x为主生态系统框架

*大数据起源于搜索,发展于电商/社交

数博会 人在干,数在转,云在算

腾讯 对几百台服务日志进行处理分析的技术选型的一个过程。 服务器的日志文件几百台机器,TB级别数据 分为三阶段:

第一阶段: MySQL + Python(数据清洗和ETL)

第二阶段: HADOOP + Hive 分区 涉及到一些负责业务:迭代计算,机器学习

第三阶段: HADOOP + Spark HDFS/Hive: 数据存储 YARN: Spark程序运行在YARN上

3、MapReduce的缺点

3.1 分布式计算框架,是Hadoop中的一个组件

InputFormat -> Mapper -> Shuffle -> Reducer -> OutputFormat

缺点:

1. 执行速度慢

​ 内存利用率不高, shuffle的时候会将大量的数据溢出到磁盘

​ 如果是一个多Job组成的MR任务的,前一个Job会将数据写出到HDFS上 ==> 有很大的网络IO、磁盘IO开销

​ Task启动比较慢,Task以进程的方式进行启动

2. 框架只提供map和reduce两个算子/API

​ 只提供了map->reducer或者map [->map]* -> reducer [->map]*】

3.2 Spark

​ 类比MapReduce框架,都是处理数据,分析数据

​ 并行计算框架

Spark 优化的快读内存迭代框架

批处理(batch procssing)交互式处理流处理
MapReduce\HiveImpala\KylinStorm\JStorm
SparkCoreSparkSQLSparkStreaming
RDDSQL\DSL

Spark 核心编程

​ Spark Core

Spark 开发核心

​ Spark SQL

​ Spark Streaming

Spark 高级分析

Spark MLlib

​ Spark GraphX

4、Spark 发展

加州大学 伯克利 分校 AMPLab 实验室

AMP(机器学习,人工智能)

  • A:算法
  • M:机器
  • P:人

Databrick金砖

5、Spark相关文档

基于内存迭代的分布式计算框架

官网:http://spark.apache.org/

文档:http://spark.apache.org/docs/2.2.1/

官方博客:https://databricks.com/blog

​ Apache Spark 2.2.0 中文文档

http://spark.apachecn.org/docs/cn/2.2.0/

6、Spark编译

官方的编译文档

http://spark.apache.org/docs/2.2.1/building-spark.html

  1. 下载

http://archive.apache.org/dist/spark/spark-2.2.1/

http://archive.apache.org/dist/spark spark-2.2.1/spark-2.2.1.tgz

  1. 将所需要的所有文件上传linux
  2. 开始编译(需要进行的信息参考ppt)
  3. apache hadoop依赖编译
./make-distribution.sh --tgz \

       -Phadoop-2.6 \

      -Dhadoop.version=2.6.0 \

       -Pyarn \

       -Phive -Phive-thriftserver
  1. cdh hadoop版本编译
./make-distribution.sh --tgz \

       -Phadoop-2.6 \

       -Dhadoop.version=2.6.0-cdh5.14.2 \

       -Pyarn \

      -Phive -Phive-thriftserver

7、将SPARK源码导入IDEA中

过程见ppt或者笔记中的图片

备注:所有的源码(包括不限于需要运行的代码)所放到的文件夹路径中不允许存在空格和中文。

备注:导入之前可以考虑将repository(Windows Linux开发环境依赖maven本地仓库).zip的内容解压到本地的maven仓库中

IDEA默认快捷键:

CTRL+N => 查找类,按两次表示查找依赖的类

CTRL+F12 => 在当前类中查找方法,按两次表示查找父类中的方法

ALT + ENTER => 万能的快捷键,主要用于异常提示、导包、类型给定等(鼠标放到异常位置或者需要给定类型的变量后面)

基本步骤:

​ 1. 解压源码(11m的那个文件)到一个非中文的目录

​ 2. 启动IDEA,在loading Project弹窗中点击canceling或者进入当前的工程界面 file -> close project

​ 3. 替换saprk2.2.1源码项目所依赖的maven的本地仓库(先删除原有的,再解压进去)

8、Spark应用的四种运行环境

bin/spark-submit

本地模式

​ 1、local => 主要用于开发(IDEA中运行)和开发的测试(spark-shell运行)

集群模式

​ 2、standalone => 将spark应用运行在spark自带的资源管理器上

​ 3、yarn => 将spark应用运行在yarn上

​ 80%的公司选择将程序运行在yarn上

​ 4、mesos => 将spark应用运行在mesos上

standalone、yarn、mesos均为集群资源管理器;mesos、standalone都是类似yarn的一种资源管理器

Spark on Local

环境搭建
  1. 先安装Scala

    # 1.解压安装包
    $ tar -zxf  scala-2.11.8.tgz -C /opt/modules
    # 2.配置环境变量
    $ sudo vi /etc/profile
    
    #SCALA_HOME
    export SCALA_HOME=/opt/modules/scala-2.11.8
    
    export PATH=$PATH:$JAVA_HOME/bin:$SCALA_HOME/bin
    
    # 3.测试
    $ source /etc/profile
    $ scala -version
    
    
  2. 解压编译好的压缩包或者软件工具文件夹中的压缩包

    $ tar -zxf spark-2.2.1-bin-2.6.0-cdh5.14.2.tgz -C /opt/modules/cdh/
    
  3. 进入spark的根目录(解压目录)

    $ cd /opt/modules/cdh
    $ ln -s spark-2.2.1-bin-2.6.0-cdh5.14.2/ spark2.2.1
    $ cd spark2.2.1
    
  4. 修改配置信息(conf/spark-env.sh)

$ mv conf/spark-env.sh.template conf/spark-env.sh

JAVA_HOME=/opt/modules/java

SCALA_HOME=/opt/modules/scala

HADOOP_CONF_DIR=/opt/modules/cdh/hadoop-2.6.0-cdh5.14.2/etc/hadoop

SPARK_LOCAL_IP=[hostname]

注意:HADOOP_CONF_DIR参数的含义是指定spark连接的hadoop的相关配置信息所在的文件夹路径,当spark应用程序连接hadoop的时候,从会该路径下加载相关的配置信息 ===> 实质上就是将hdfs-site.xml、core-site.xml、yarn-site.xml配置文件添加到spark应用程序的classpath环境变量中 ===> 可以考虑不配置该参数,直接将配置文件放到${SPARK_HOME}/conf文件夹中

linux本地环境测试
    1. 启动hdfs的服务
    1. 运行run-example
$ bin/run-example  SparkPi

$ bin/run-example  SparkPi 100
    1. 官方案例测试
$  bin/spark-shell

17/10/17 11:56:09 INFO ui.SparkUI: Started SparkUI at http://192.168.187.146:4040

17/10/17 11:56:10 INFO repl.SparkILoop: Created spark context…

Spark context available as sc.

/beifeng/bc3108de-6f74-468d-b5e3-a8392e287103/_tmp_space.db

17/10/17 11:56:50 INFO repl.SparkILoop: Created sql context (with Hive support)…

SQL context available as sqlContext.

scala>  val textFile = sc.textFile("README.md")  

使用fs.defaultFS指定的文件系统进行RDD数据读取

底层的原理:

​ 如何读取HDFS数据呢???

​ 按照MapReduce读取文件的方式进行的

默认情况下MapReduce读取HDFS

一行一行的读取,将每一行的数据变为Key,Value对的形式

Key:

每行数据的所在文件的偏移量

Value

每一行的值

//明确指定读取本地磁盘的文件数据(本地磁盘该文件存在)
val textFile = sc.textFile("file:///opt/modules/cdh/spark2.2.1/spark/README.md") 

 textFile.count()

 textFile.first()

 val linesWithSpark = textFile.filter(line => line.contains("Spark"))

 textFile.map(line => line.split(" ").size).reduce((a, b) => if (a > b) a else b)

textFile: 默认形成RDD数据格式是:文件中的一行数据就是RDD中的一个元素

备注:

textFile给定的文件路径,如果没有给定schema信息的情况下,默认使用fs.defaultFS作为默认的schema;当配置好HADOOP_CONF_DIR,默认的文件系统为HDFS文件系统; 也就是说如果没有配置HADOOP_CONF_DIR配置信息,那么使用本地磁盘作为默认的文件系统

9、数据分析统计:

  • 1,清洗过滤
  • 2,分组 word count
  • 3,统计
  • 4,排序 top
  • 5,Top
row_number over(partition by col1 sort by col2 asc/dec) rank

10、WordCount

编程结构:

Step 1:

​ 读取要处理要分析的数据 -> 内存

​ 封装

​ 集合(RDD : Resilient Distributed Dataset) 数据结构

​ 分区的 - hdfs block

​ 每个分区进行数据处理,函数 - RDD

Step 2:

​ 分析处理数据

​ RDD#transformation

Step 3:

​ 将分析数据分结果进行存储

​ RDD#action

RDD的算子

​ 算子/函数(方法)

    1. 处理数据 函数

​ Transformation 转换

    1. 存储或者返回

​ Action

​ count\take(5)\saveAsTextFile(“”)\foreach(item => { })

Wordcount案例详解

  1. 将word.txt上传到hdfs上
  2. WordCount案例实现
// 修改当前应用的日志级别
sc.setLogLevel("ERROR") 
  1. 编码
  • 3.1 读取文件形成RDD
//基于输入数据构建RDD; textFile API是读取HDFS上的文件形成RDD,其中第一个参数给定HDFS上的文件路径,第二个参数给定形成RDD的最少分区数量;默认分区数为2

val rdd = sc.textFile("/beifeng/spark/data/word.txt")

// rdd: org.apache.spark.rdd.RDD[String] = /beifeng/spark/data/word.txt MapPartitionsRDD[9] at textFile at <console>:27
  • 3.2 调用Transformation算子,实现业务功能
val rdd0 = rdd.flatMap(line => line.split(" "))

val rdd1 = rdd0.filter(word => word.nonEmpty)

val rdd2 = rdd1.map(word => (word,1))

val rdd3 = rdd2.groupBy(t => t._1)

val resultRDD1 = rdd3.map(t => {

  // rdd3中的数据类型是一个二元组,第一个元素是进行分组的数据, 也就是单词,第二个数据,分组后,相同数据的value形成的一个迭代器; value本身的数据类型是一个(String,Int)的二元组

(hive,iter((hive,1),(hive,1),(hive,1))

  val word = t._1

  val iter = t._2

  val sum = iter.map(tt => tt._2).sum

  (word, sum)

})


val rdd4 = rdd2.groupByKey()

val resultRDD2 = rdd4.map(t => {

  // rdd4中的数据类型是一个二元组,第一个元素是进行分组的数据, 也就是单词,第二个数据,分组后,相同数据的value形成的一个迭代器;value的原始数据类型是Int

ive,iter(111))

  val word = t._1

  val iter = t._2

  val sum = iter.sum

  (word, sum)

})

// aggregateByKey和reduceByKey的性能比groupByKey的性能高,在实际的工作中,优先考虑前两个API;性能高的原因是:前两个API在进行shuffle之前会对每个分区的数据进行聚会的聚合操作,可以降低shuffle传输量 ==> 类似MapReduce的combiner的作用

val resultRDD3 = rdd2.reduceByKey((a,b) => a + b)
  • 3.3将结果数据输
// 输出到控制台

resultRDD3.collect.foreach(i => println(i))

resultRDD3.first

resultRDD3.take(10)

// 输出到HDFS文件中

resultRDD3.saveAsTextFile("/beifeng/spark/core/wc")

11 、TopN的程序

含义:获取出现次数最多的前N个元素的值 (对于wrodcount而言)

resultRDD3.map(t => (t._2, t._1)).sortByKey(ascending = false).take(5).map(t => t.swap)

// 默认的排序器对于元组的数据来讲,是先对第一个元素进行比较,如果第一个相同,再比较第二个、第三个....

resultRDD3.map(_.swap).top(5).map(_.swap)

 
resultRDD3.top(5)(ord = new scala.math.Ordering[(String,Int)](){

  override def compare(x: (String,Int), y: (String,Int)): Int = {
   // 返回0表示相等,-1表示x<y(负数),1表示x>y(正数)
      val tmp = x._2.compare(y._2)
      if (tmp != 0) {
        tmp
      } else {
        x._1.compare(y._1)
      }

  }

})

12、Spark Standalone(独立运行)

Spark的运行架构

Standalone属于Spark自身自带的分布式资源管理和任务调度框架(Spark Application), 是一种类似Yarn的spark自带的资源管理框架

​ 主节点 YARN

​ Master ResourceManager

​ 从节点

​ Works NodeManagers

Yarn架构


​ ResourceManager

​ 负责集群资源的管理

​ NodeManager

​ 负责当前节点上的资源管理

Standalone架构


​ Master

​ 负责管理集群的所有资源

​ Worker

​ 负责当前进程的所有资源

​ 资源:CPU和内存

资源:CPU Cores + 内存


假设单个节点的为2颗CPU,每颗12核,内存128G

​ CPU指的是逻辑CPU、内存也是逻辑内存CPU是参数yarn.nodemanager.resource.cpu-vcores(默认为8) 控制,默认情况下表示一个NodeManager管理8核的CPU //18核

​ 内存是参数yarn.nodemanager.resource.memory-mb(默认8192)控制,

​ 默认情况下表示一个NodeManger管理8g的内存 //100G

​ 默认情况下,一个MapReduce的task(map task\reduce task)需要1核cpu+1g内存

Standalone的环境配置:

  1. 前提:spark的本地执行环境已经搭建好了
  2. 修改conf/spark-env.sh文件内容
SPARK_MASTER_IP=[hostname]

SPARK_MASTER_PORT=7070

SPARK_MASTER_WEBUI_PORT=8080
# 给定当前的机器上的一个worker进程允许分配/管理的cpu核数
SPARK_WORKER_CORES=2  
# 给定当前机器上的一个worker进程允许分配/管理的内存大小
SPARK_WORKER_MEMORY=2g 
SPARK_WORKER_PORT=7071
SPARK_WORKER_WEBUI_PORT=8081

## 给定当前机器上允许存在多少个worker进程(spark1.6),当前版本中不要配置
SPARK_WORKER_INSTANCES=2 
  1. 配置worker机器列表(slave列表)
$ mv conf/slaves.template conf/slaves
  1. 启动standalone的服务
sbin/start-master.sh 

sbin/start-slaves.sh

sbin/start-slave.sh  spark://[hostname]:7070

#关闭所有
sbin/stop-all.sh 

# 开启所有
sbin/start-all.sh 

Standalone的测试

–master MASTER_URL spark://host:port, mesos://host:port, yarn, or local. ==> 指定spark应用的运行环境

$  bin/spark-shell --master spark://[hostname]:7070
val rdd = sc.textFile("/beifeng/spark/data/word.txt")

val rdd0 = rdd.flatMap(line => line.split(" "))

val rdd1 = rdd0.filter(word => word.nonEmpty)

val rdd2 = rdd1.map(word => (word,1))

val resultRDD3 = rdd2.reduceByKey((a,b) => a + b)

resultRDD3.collect.foreach(println)

问题:

  1. bin/spark-shell --master local[2] bin/spark-shell --master spark://bigdata.server1:7070 不要两个同时起
  2. 不相关的进程最好不要启动, 目前仅需要启动 hdfs相关的进程
  3. 配置文件要生效,master 和 worker进程必须先停止,再启动
  4. 在standalone模式下,提交应用程序或者运行spark-shell,必须使用 --master spark://bigdata.server1:7070 表式应用程序运行所需的资源需要通过master节点来分配

历史日志聚合

  1. 生成历史日志聚合配置文件
$ cp conf/spark-defaults.conf.template conf/spark-defaults.conf
  1. 在conf/spark-defaluts.conf中拷贝以下两个参数并修改

注意:spark.eventLog.dir在hdfs对应的目录需要手动创建

spark.eventLog.enabled           true
spark.eventLog.dir               hdfs://linux01:8020/spark/history
  1. 在conf/spark-env. sh中配置中已有的参数下方增加以下参数

注意:1.“=”左右两侧不能有空格;2.右侧的配置信息是一行内容,并且 –D后面也没有空格

SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://linux01:8020/spark/history -Dspark.history.ui.port=18080"

13、Standalone分布式配置

1.完全分布式(没有HA)

  1. 所有机器之间的免密码登录完全做好了
  2. 选取一台配置进行配置spark,修改spark-env.sh中对应的IP地址信息以及路径信息(eg: JAVA_HOME\SCALA_HOME…)
  3. 在master机器上修改slaves文件内容,将所有的worker机器ip地址添加到文件中,一行一个
  4. 将一台配置好的机器上的spark的目录ssh-copy到其它机器上

2.Standalone Master HA配置

http://spark.apache.org/docs/2.2.1/spark-standalone.html#high-availability

1. Single-Node Recovery with Local File System

​ 基于文件的单节点master恢复机制

​ 修改conf/spark-env.sh文件内容添加一个环境变量

SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=FILESYSTEM -Dspark.deploy.recoveryDirectory=/tmp"
2. Standby Masters with ZooKeeper

​ 基于zk的active、standby模式的HA热备机制

​ 修改conf/spark-env.sh文件内容添加一个环境变量

SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=hadoop01:2181,hadoop02:2181,hadoop03:2181 -Dspark.deploy.zookeeper.dir=/spark"
3.(基于zookeeper的多节点HA)在spark-env.sh文件中将之前的关于master配置信息全注释掉
#SPARK_MASTER_IP
#SPARK_MASTER_PORT
#SPARK_MASTER_WEBUI_PORT
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值