大数据组件
分布式存储
Zookeeper:利用分布式存储系统实现小的核心数据的存储(加紧复习)
抓紧复习
HDFS:离线大数据文件系统数据存储(加紧复习)
抓紧复习
Hive:离线数据仓库【表】
Redis:实时内存式NOSQL数据库【所有数据都在内存中】
HBASE:实时基于分布式内存的NoSQL数据库【内存+HDFS】(加紧复习)
抓紧复习
基于性能和大数据量之间做了一个平衡
解决性能与存储之间的瓶颈的思想:冷热数据的分离
冷数据:不经常被使用的数据
热数据:经常被使用的数:最新的数据
先产生的比较早的数据写入HDFS
怎么保证读HDFS也能很快?
构建数据存储的有序
读缓存:BlockCache
blockcache这个怎么实现的
列族:存储:Store 如果不划分列族的情况下所有的列都存储在一个store
设计列族的主要目的就是减少比较次数
数据被使用的概率随着时间的流逝而逐渐降低
二级索引:走两次索引,代替全表扫表
Kafka:分布式实时消息队列【传递数据】(加紧复习)
ES:分布式全文检索搜索引擎
分布式计算
数据采集
其他辅助性组件
Spark的介绍
Spark环境部署
架构
集群搭建
基本使用方式
分布式计算发展
分布式计算平台的演变
第一代:MapReduce
第二代:Tez
第三代:Spark
第四代:Flink
以实时数据流计算为主
为什么基于内存式的还没有流式的有优势?:见spark学习笔记中问题部分。
官网
介绍
Apache Spark is a lightning-fast unified analytics engine for big data and machine learning. It was originally developed at UC Berkeley in 2009.
定义:是一个分布式的统一化的计算框架;类似于前面学的MapReduce+yarn
官方对Spark的一个介绍
At a high level, every Spark application consists of a driver program
#每个Spark程序都会包含一个驱动程序:Driver
that runs the user’s main function
#这个driver运行在用户的main方法中
and executes various parallel operations on a cluster.
#并且在集群中执行各种并行化操作
The main abstraction Spark provides is a resilient distributed dataset (RDD),
#Spark中提供了一个主要的抽象:RDD【弹性分布式数据集】【SparkCore中的核心数据结构】
which is a collection of elements partitioned across the nodes of the cluster
# 被分区存储在各个节点中的一个元素的集合【类似于MapReduce中的分片的存在,所有分片构建一个RDD】
that can be operated on in parallel.
#可以被并行化的操作
RDDs are created by starting with a file in the Hadoop file system (or any other Hadoop-supported file system),
#RDD可以被创建从一个Hadoop文件系统中被创建
or an existing Scala collection in the driver program, and transforming it.
#或者从一个Scala的集合中进行创建,由driver来实现,并且对RDD进行转换
Users may also ask Spark to persist an RDD in memory,
#用户可以将RDD中的数据持久化【缓存】在内存中,
【scala中结果会存在新生成的集合中这个集合可能会被回收:后边文档已有解决方案】
allowing it to be reused efficiently across parallel operations.
#方便多次使用
Finally, RDDs automatically recover from node failures.
#最终,RDD会自动的从失败中恢复
RDD
数据处理的流程
MapReduce
需求:1 + …… + 9
Input
功能一:将数据进行分片,得到每个split
功能二:将每个分片的每条数据转换为KV结构
目的:整个MapReduce中所有的数据都以KV结构进行存储和处理
split1
(a,1)
(a,2)
(a,3)
split2
(a,4)
(a,5)
(a,6)
split3
(a,7)
(a,8)
(a,9)
Tranform
Output
问题
SparkCore
Input:读取数据
TransForm:对RDD中的数据进行转换处理
Output
Speed
快
流程设计:读取、处理、保存
保证整个流程中提高性能:积极的将数据存储在内存中
问题:内存中的数据是不稳定的,空间较小
解决
如果内存不足以存放所有数据,将部分数据持久化persist在磁盘中 disk
如果内存数据丢失,通过特殊的机制来保证数据可恢复或者可用
HDFS:副本机制
Redis:副本机制(内存、磁盘都有一份)
HBASE:WAL
WAL: Write-Ahead Logging [1] 预写日志系统;数据库中一种高效的日志算法,对于非内存数据库而言,磁盘I/O操作是数据库效率的一大瓶颈。在相同的数据量下,采用WAL日志的数据库系统在事务提交时,磁盘写操作只有传统的回滚日志的一半左右,大大提高了数据库磁盘I/O操作的效率,从而提高了数据库的性能。
Kafka:副本机制
ES:副本机制
Spark能不能选用副本机制?
Ease of Use
Generality
功能非常全面
SparkCore:Spark中最核心的组件
SparkSQL :Spark中用于实现SQL处理的组件(源自于hive)
SparkStreaming:准实时计算
SparkStructStreaming:结构化流
Spark MLlib:机器学习的算法库
Spark Graphx:图计算
Runs Everywhere
Spark支持各种数据源(内部已将封装了这些api)
运行在各种分布式资源平台中
版本
发行厂商
基于以上的问题,需要基于Cloudera公司的依赖,自己编译Spark自己编译啥意思呀?
spark-2.4.5-bin-cdh5.16.2-2.11.tgz
Deploying部署:
主从架构模式
Standalone
YARN
zookeeper解决单点故障问题,那么就自己实现了单点故障解决问题的功能
[root@node1 spark]# hadoop-daemon.sh start namenode
[root@node1 spark]# hadoop-daemon.sh start datanode
#node1:50070端口
参考附录一导入虚拟机
参考附录二安装本地环境
启动HDFS
hadoop-daemon.sh start namenode
hadoop-daemon.sh start datanode
测试
启动Spark-shell
cd /export/server/spark
bin/spark-shell --master local[2]
创建测试文件
hdfs dfs -mkdir /datas
vim wordcount.data
hadoop spark hbase
hive hive hive hive
hadoop spark spark
hdfs dfs -put wordcount.data /datas
#此文件在本地-》放到hdfs上
- 观察Spark-shell日志
```shell
Setting default log level to "WARN".
#默认日志级别为WARN级别
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
#如果你要修改日志级别,你要sc.setLogLevel(“INFO”)
Spark context Web UI available at http://node1.itcast.cn:4040
#每一个Spark程序都会自动开放一个Web监控界面,端口从4040开始,第二个程序的端口4041,依次类推
Spark context available as 'sc' (master = local[2], app id = local-1608102687971).
#创建了一个对象:sc:SparkContext
Spark session available as 'spark'.
#创建了一个对象:spark:SparkSession
测试WordCount
Input:读HDFS中/datas/wordcount.data
//调用sparkContext的方法读HDFS文件,存入RDD对象中
scala> val inputRdd = sc.textFile("/datas/wordcount.data")
inputRdd: org.apache.spark.rdd.RDD[String] = /datas/wordcount.data MapPartitionsRDD[1] at textFile at <console>:24
//查看RDD的第一行数据
scala> inputRdd.first
res0: String = hadoop spark hbase
//统计RDD的行数
scala> inputRdd.count
res1: Long = 3
- Transform:实现词频统计
- flatMap:RDD[String]
```scala
scala> inputRdd.flatMap(line => line.trim.split("\\s+"))
res2: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[2] at flatMap at :26
scala> inputRdd.flatMap(line => line.trim.split("\\s+")).foreach(println)
hadoop
spark
hbase
hive
hive
hive
hive
hadoop
spark
spark
- map:RDD[(String,Int)]
```
scala> inputRdd.flatMap(line => line.trim.split("\\s+")).map(word => (word,1)).foreach(println)
(hadoop,1)
(spark,1)
(hbase,1)
(hive,1)
(hive,1)
(hive,1)
(hive,1)
(hadoop,1)
(spark,1)
(spark,1)
```
- reduceByKey:功能 = groupByKey + reduce:RDD[(String, Int)]
```
scala> val rsRDD = inputRdd.flatMap(line => line.trim.split("\\s+")).map(word => (word,1)).reduceByKey((tmp,item)=> tmp+item)
rsRDD: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[8] at reduceByKey at :25
scala> rsRDD.foreach(println)
(hive,4)
(spark,3)
(hadoop,2)
(hbase,1)
```
rsRDD.saveAsTextFile("/datas/output/output1")
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L55rTm6D-1610365374480)(Day38_分布式计算平台Spark:基础入门.assets/image-20201216155243915.png)]
测试运行Jar包
spark-submit:用于运行Spark的jar包的
YARN语法
yarn jar xxxx.jar main_class args
Spark
spark-submit
[选项]
--class 指定运行哪个类
xxxx.jar
args
SPARK_HOME=/export/server/spark
${SPARK_HOME}/bin/spark-submit \
--master local[2] \
--class org.apache.spark.examples.SparkPi \
${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \
10
参考附录三安装集群环境
启动Spark Standalone集群
启动HDFS:第一台机器执行
start-dfs.sh
#创建一个目录,用于存储Spark程序的运行日志
hdfs dfs -mkdir -p /spark/eventLogs/
启动Master:第一台机器
/export/server/spark/sbin/start-master.sh
启动Worker:第一台机器
/export/server/spark/sbin/start-slaves.sh
查看WebUI
node1:8080
启动HistoryServer
start-dfs.sh
/export/server/spark/sbin/start-history-server.sh
访问WebUI
node1:18080
测试
SPARK_HOME=/export/server/spark
${SPARK_HOME}/bin/spark-submit \
--master spark://node1:7077 \
--class org.apache.spark.examples.SparkPi \
${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \
10
关闭所有Spark进程
/export/server/spark/sbin/stop-slaves.sh
/export/server/spark/sbin/stop-master.sh
/export/server/spark/sbin/stop-history-server.sh
修改配置文件
cd /export/server/spark/conf/
vim spark-env.sh
#注释60行
#SPARK_MASTER_HOST=node1
#添加68行
SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=node1:2181,node2:2181,node3:2181 -Dspark.deploy.zookeeper.dir=/spark-ha"
分发
cd /export/server/spark/conf
scp -r spark-env.sh node2:$PWD
scp -r spark-env.sh node3:$PWD
启动ZK
zookeeper-daemons.sh start
zookeeper-daemons.sh status
启动Master
第一台
/export/server/spark/sbin/start-master.sh
第二台
/export/server/spark/sbin/start-master.sh
启动Worker
/export/server/spark/sbin/start-slaves.sh
测试
SPARK_HOME=/export/server/spark
${SPARK_HOME}/bin/spark-submit \
--master spark://node1:7077,node2:7077 \
--class org.apache.spark.examples.SparkPi \
${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \
100
Master:主节点进程
Worker:从节点进程:计算节点
HistoryServer:历史服务进程
Executor:Task真正运行的计算的进程
Task:每个线程所处理的任务,每个线程需要1coreCPU来完成
Driver:每个Spark程序都要包含的一个进程,在代码中是:SparkContext对象
package bigdata.itcast.cn.spark.scala.wordcount
import org.apache.spark.rdd.RDD
import org.apache.spark.{
SparkConf, SparkContext}
/**
* @ClassName SparkCoreWordCount
* @Description TODO 自己开发代码来实现Wordcount
* @Date 2020/12/16 17:22
* @Create By Frank
*/
object SparkCoreWordCount {
def main(args: Array[String]): Unit = {
/**
* step1:先构建SparkContext:初始化资源对象
*/
//构建一个SparkConf:用于管理当前程序的所有配置
val conf = new SparkConf()
//给当前程序设置一个名字
.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
//设置当前程序运行的模式
.setMaster("local[2]")
//构建一个SparkContext对象
val sc = new SparkContext(conf)
//调整日志级别
sc.setLogLevel("WARN")
/**
* step2:处理数据
*/
//todo:1-读取数据
val inputRdd: RDD[String] = sc.textFile("/datas/wordcount.data")
//todo:2-处理数据
val rsRdd = inputRdd
.filter(line => null != line && line.trim.length >0)
.flatMap(line => line.trim.split("\\s+"))
.map(word => word -> 1)
.reduceByKey((tmp,item) => tmp+item)
//todo:3-保存结果
rsRdd.foreach(println)
/**
* step3:释放资源
*/
Thread.sleep(1000000L)
sc.stop()
}
}
package bigdata.itcast.cn.spark.scala.mode
import org.apache.spark.rdd.RDD
import org.apache.spark.{
SparkConf, SparkContext}
/**
* @ClassName SparkCoreMode
* @Description TODO SparkCore的基础模板
* @Date 2020/12/16 17:22
* @Create By Frank
*/
object SparkCoreMode {
def main(args: Array[String]): Unit = {
/**
* step1:先构建SparkContext:初始化资源对象
*/
//构建一个SparkConf:用于管理当前程序的所有配置
val conf = new SparkConf()
//给当前程序设置一个名字
.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
//设置当前程序运行的模式
.setMaster("local[2]")
//构建一个SparkContext对象
val sc = new SparkContext(conf)
//调整日志级别
sc.setLogLevel("WARN")
/**
* step2:处理数据
*/
//todo:1-读取数据
//todo:2-处理数据
//todo:3-保存结果
/**
* step3:释放资源
*/
Thread.sleep(1000000L)
sc.stop()
}
}
package bigdata.itcast.cn.spark.scala.topkey
import org.apache.spark.rdd.RDD
import org.apache.spark.{
SparkConf, SparkContext}
/**
* @ClassName SparkCoreWordCount
* @Description TODO 取单词最多的前3个
* @Date 2020/12/16 17:22
* @Create By Frank
*/
object SparkCoreWordCountTopWord {
def main(args: Array[String]): Unit = {
/**
* step1:先构建SparkContext:初始化资源对象
*/
//构建一个SparkConf:用于管理当前程序的所有配置
val conf = new SparkConf()
//给当前程序设置一个名字
.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
//设置当前程序运行的模式
.setMaster("local[2]")
//构建一个SparkContext对象
val sc = new SparkContext(conf)
//调整日志级别
sc.setLogLevel("WARN")
/**
* step2:处理数据
*/
//todo:1-读取数据
val inputRdd: RDD[String] = sc.textFile("/datas/wordcount.data")
//todo:2-处理数据
inputRdd
.filter(line => null != line && line.trim.length >0)
.flatMap(line => line.trim.split("\\s+"))
.map(word => word -> 1)
.reduceByKey((tmp,item) => tmp+item)
//排序方式一:sortByKey:按照Key进行排序
// .map(tuple => tuple.swap)
// .sortByKey(ascending = false)
//排序方式二:sortBy :指定按照哪个值进行排序
.sortBy(tuple => tuple._2,false)
.take(3)
.foreach(println)
//todo:3-保存结果
// rsRdd.foreach(println)
/**
* step3:释放资源
*/
Thread.sleep(1000000L)
sc.stop()
}
}
192.168.88.100 node1.itcast.cn node1
192.168.88.101 node2.itcast.cn node2
192.168.88.102 node3.itcast.cn node3
【以第一台机器为例】
解压安装
tar -zxvf /export/software/spark-2.4.5-bin-cdh5.16.2-2.11.tgz -C /export/server/
ln -s /export/server/spark-2.4.5-bin-cdh5.16.2-2.11 /export/server/spark
修改配置
spark-env.sh.template 配置环境变量的
cd /export/server/spark/conf
mv spark-env.sh.template spark-env.sh
vim spark-env.sh
#22行-23行
JAVA_HOME=/export/server/jdk
SCALA_HOME=/export/server/scala
#30行
HADOOP_CONF_DIR=/export/server/hadoop/etc/hadoop
架构:分布式主从架构
将三台机器恢复到《4、分布式环境》
解压安装
tar -zxvf /export/software/spark-2.4.5-bin-cdh5.16.2-2.11.tgz -C /export/server/
ln -s /export/server/spark-2.4.5-bin-cdh5.16.2-2.11 /export/server/spark
spark-env.sh
cd /export/server/spark/conf/
mv spark-env.sh.template spark-env.sh
vim spark-env.sh
#22行-23行
JAVA_HOME=/export/server/jdk
SCALA_HOME=/export/server/scala
#30行
HADOOP_CONF_DIR=/export/server/hadoop/etc/hadoop
#60行
#指定Master启动的地址
SPARK_MASTER_HOST=node1
#指定Master的通信端口
SPARK_MASTER_PORT=7077
#Master的Web端口
SPARK_MASTER_WEBUI_PORT=8080
#指定每个Work能使用这台机器的多少核CPU
SPARK_WORKER_CORES=1
#指定每个Work能使用这台机器的多少内存
SPARK_WORKER_MEMORY=1g
#Work的端口
SPARK_WORKER_PORT=7078
#Work的web端口
SPARK_WORKER_WEBUI_PORT=8081
#配置Spark程序日志的记录位置
SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://node1:8020/spark/eventLogs/ -Dspark.history.fs.cleaner.enabled=true"
spark-defaults.conf:类似于我们以前讲的site文件
cd /export/server/spark/conf/
hdfs dfs -mkdir -p /spark/eventLogs/
mv spark-defaults.conf.template spark-defaults.conf
vim spark-defaults.conf
#28行
#启用日志存储
spark.eventLog.enabled true
#日志存储位置
spark.eventLog.dir hdfs://node1:8020/spark/eventLogs/
#启用压缩存储日志
spark.eventLog.compress true
cd /export/server/spark/conf/
mv slaves.template slaves
vim slaves
node1
node2
node3
cd /export/server/spark/conf/
mv log4j.properties.template log4j.properties
vim log4j.properties
#修改19行
log4j.rootCategory=WARN, console
所有节点配置免秘钥登录
ssh-copy-id node1
ssh-copy-id node2
ssh-copy-id node3
分发Spark
cd /export/server/
scp -r spark-2.4.5-bin-cdh5.16.2-2.11 node2:$PWD
scp -r spark-2.4.5-bin-cdh5.16.2-2.11 node3:$PWD
第二台和第三台创建软连接
ln -s /export/server/spark-2.4.5-bin-cdh5.16.2-2.11 /export/server/spark
<repositories>
<repository>
<id>aliyunid>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
repository>
<repository>
<id>clouderaid>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/url>
repository>
<repository>
<id>jbossid>
<url>http://repository.jboss.com/nexus/content/groups/publicurl>
repository>
repositories>
<properties>
<scala.version>2.11.12scala.version>
<scala.binary.version>2.11scala.binary.version>
<spark.version>2.4.5spark.version>
<hadoop.version>2.6.0-cdh5.16.2hadoop.version>
properties>
<dependencies>
<dependency>
<groupId>org.scala-langgroupId>
<artifactId>scala-libraryartifactId>
<version>${scala.version}version>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-core_${scala.binary.version}artifactId>
<version>${spark.version}version>
dependency>
<dependency>
<groupId>org.apache.hadoopgroupId>
<artifactId>hadoop-clientartifactId>
<version>${hadoop.version}version>
dependency>
dependencies>
<build>
<outputDirectory>target/classesoutputDirectory>
<testOutputDirectory>target/test-classestestOutputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resourcesdirectory>
resource>
resources>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.0version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
configuration>
plugin>
<plugin>
<groupId>net.alchim31.mavengroupId>
<artifactId>scala-maven-pluginartifactId>
<version>3.2.0version>
<executions>
<execution>
<goals>
<goal>compilegoal>
<goal>testCompilegoal>
goals>
execution>
executions>
plugin>
plugins>
build>