麻绳先生

做一些记录性的工作

spark第一次笔记

hadoop历史

2011年发布1.0版本,2012年发布稳定版,2013发布2.x版本(Yarn)

缺点

  • 基于数据集的计算,所以面向数据。从存储介质中获取数据,然后进行计算,最后将结果存储到介质中。所以主要应用于一次性计算,不适合数据挖掘和机器学习这些迭代计算和图形挖掘计算。
  • mapreduce基于文件存储介质的操作,性能差
  • mapreduce和hadoop紧密耦合

Yarn版本

ResourceManager、ApplicationMaster、Driver、NodeManager

spark历史

2013年6月正式发布,spark基于hadoop1.x架构思想设计思想。spark计算基于内存,并且基于Scala语法开发,所以天生适合迭代式计算。

HDFS-Yarn-Spark

Spark下载地址

http://spark.apache.org

重要角色

Driver(驱动器)

Executer(执行器)

Spark-Yarn运行模式简图

Spark-Yarn运行模式简图

Standalone模式

RDD

RDD(Resilient Distributed Dataset)称为弹性分布式数据集,是Spark中最基本的数据或计算抽象。代码中是一个抽象类,代表一个不可变、可分区、里面的元素可进行并行计算的集合。

RDD属性

  • 一组分区Partition,即数据集的基本组成单位
  • 一个计算每个分区的函数
  • RDD之间的依赖关系
  • 一个Partitioner,即RDD的分片函数
  • 一个列表,存储存取每个Partiton的优先位置preferred location

大数据窍门:移动数据不如移动计算

RDD特点

RDD表示只读的分区的数据集,对RDD进行改动,只能通过RDD的转换操作,由一个RDD得到一个新的RDD,新的RDD包含了从其他RDD衍生所必须的信息,RDDs之间存在依赖,RDD的执行是按照血缘关系延时计算的。如果血缘关系较长,可以通过持久化RDD来切断血缘关系。

Spark中所有RDD方法都称为算子,共分为两大类,转化算子和行动算子。

缓存

如果应用程序多次使用同一个RDD,可以将该RDD缓存起来。

RDD的创建

Spark中创建RDD的方法有三种:从集合中创建、从外部存储创建、从其他RDD创建。

集合创建

1
2
3
//前者调用后者
sc.makeRDD(List(1, 2, 3, 4))
sc.parallelize(Array(1, 2, 3, 4))

外部存储创建

1
2
3
//默认情况下,可以读取项目路径,也可以读取其他HDFS路径
val value:RDD[String] = sc.textField("in")
//涉及hadoop读取文件的分片规则

RDD的转换

Value类型

map(function)

返回一个新的RDD,该RDD由每一个输入元素经过function函数转换后组成。例如通过一个数组RDD得到一个每个元素被乘以2的新的RDD。

mapPartitions

mapPartitions效率优于map算子,减少了发送到执行器执行交互次数。但是可能会出现内存溢出OOM。一次处理一个分区的数据。

mapPartitionsWithIndex(func)

作用是,func带有一个整数参数表示分片的索引值,因此在类型为T的RDD上运行时,func的函数类型必须是(Int, Interator[T]) -> Iterator[U]。

Driver和Executor关系

Driver就是创建Spark上下文对象的应用程序,Executor就是用于提取任务并执行。

flatMap
glom

将每一个分区形成一个数组,形成新的RDD类型为RDD[Array[T]]。

groupBy & filter

分组,按照传入函数的返回值进行分组,将相同的key对应的值放入一个迭代器。

sample(withRepalcement, fraction, seed)

以指定的随机种子随机抽样出数量为fraction的数据,withReplacement表示抽出的数据是否放回,true表示有放回,seed用于指定随机数生成器种子。

distinct
coalesce
repartition & sortBy

双Value类型交互

union
cartesian

Key-Value类型

partitionBy
groupBykey
reduceBykey
aggregateBykey
foldByKey & combinByKey
sortByKey & mapValueByKey

方法不同,底层实现和代码的执行位置很不同,
是的Driver执行还是在Executor执行?

RDD的依赖

窄依赖

窄依赖指的是每一个父RDD的Partition最多被子RDD的一个Partition使用,窄依赖被比喻为独生子女。

宽依赖

宽依赖指的是每一个父RDD的Partition可以被多个子RDD的Partition使用。

DAG

任务划分

宽依赖放在不同的stage,窄依赖放在同一个stage。

  1. Application:初始化一个SparkContext即生成一个Application;
  2. Job:一个Action算子就会生成一个Job;
  3. Stage:根据RDD依赖关系,将Job划分成不同的Stage,一个宽依赖就划分一个新的Stage;
  4. Task:Stage是一个TaskSet,将Stage划分的结果发送到不同Executor执行即为一个Task;
  5. 上述四者每一层都是一对n的关系;

RDD的缓存

通过persist方法或cache方法可以将前面的计算结果缓存,默认情况下persist()会把数据以序列化的形式缓存在JVM的堆空间中。但是并不是这两个方法调用时立刻缓存,而是触发后面的action时,该RDD将会被缓存在计算节点的内存中,供后面重用。

此外还有checkpoint功能,通过函数setCheckpointDir(dir)设置。

一般在血缘关系比较长的时候使用。

RDD分区器

Spark三大数据结构

  • RDD:分布式数据集
  • 广播变量:分布式只读共享变量 broadcast,调优策略
  • 累加器:分布式只写共享变量,LongAccumulator

Spark中的数量

  • Executor:默认有2个;可以通过提交参数设置;
  • partition:默认情况,读取文件采用Hadoop的切片规则,如果读取内存中的数据,可以根据特定的算法设定,可以通过其他算子进行改变;多个阶段的场合,下一个阶段分区的数量受到上一个阶段分区的影响;
  • Stage:ResultStage + Shuffle依赖的数量,划分阶段的目的就是为了任务执行的等待,因为Shuffle的过程需要落盘;
  • Task:原则上一个分区就是一个任务,但实际中,可以动态调整;

javaCV初步使用之rtmp推流和在线播放

从设备获取视频流

参考链接
https://blog.csdn.net/eguid_1/article/details/52678775

这块内容主要是javaCV基本API的使用,代码非常简单,我将其写在了一个类中,位于
src/main/java/com/zkalan/capture下,然后再demo类中调用测试;需要注意的是,网
上的很多代码将画板canvas的销毁方式设置为EXIT_ON_CLOSE,这会导致java虚拟机直接
推出,资源无法释放。我认为正确的写法应该是DISPOSED_ON_CLOSE。

1
canvas.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

搭建rtmp推流服务器

通过nginx服务器和nginx-rtmp-module可以简单的搭建一个rtmp服务器,我将使用的nginx
编译版本放在了这里
,这是已经包含了nginx-rtmp-module的版本,使用非常简单,首先在配置文件,例如
nginx-win-rtmp.conf中,添加一段rtmp配置项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
rtmp {
server {
listen 1935;
chunk_size 4000;
#mylive就是直播项目名
application mylive {
live on;

# record first 1K of stream
record all;
record_path /tmp/av;
record_max_size 1K;

# append current timestamp to each flv
record_unique on;

# publish only from localhost
#allow publish 127.0.0.1;
#deny publish all;

#allow play all;
}
}
}

然后在命令行中启动nginx服务器,例如命令

1
start nginx.exe -c conf\nginx-win-rtmp.conf

最后,启动第一部分写好的demo程序,注意publish address应该是这样的格式
rtmp://localhost:port/mylive/,使用potplayer或者vlc访问该链接,测试推流是否成功。

在网页播放rtmp流

参考链接
https://blog.csdn.net/qq_30152271/article/details/84334734

操作起来很简单,就是创建一个静态网页,放到服务器目录下,启动任何一个静态服务器,例如
上文的nginx,访问该静态网页,只要地址填写正确,就可以观看推流内容了。

然而需要注意的是,videojs虽然声称是一个html5播放器,但它的5.x版本播放rtmp流时依然需要flash 支持,并且6.x及以后版本不支持rtmp播放,也许是为了真正的叫做“html5播放器”?

Demo地址

javaCV-rtmp-demo

浏览器效果图

Mybatis第一节

持久层技术解决方案有JDBC技术、Sping中对JDBC的简单封装、Apache的DBUtils等,这些都不是框架技术,后两者只是工具类。Mybatis是一个持久层框架,使用ORM思想实现了结果集的封装。ORM就是把数据库表和实体类及其实体类的属性对应起来。

环境搭建

  1. 创建maven工程并导入坐标;
  2. 创建实体类和dao的接口;
  3. 创建Mybatis的主配置文件SqlMapConfig.xml
  4. 创建映射配置文件;

注意事项

  1. 在Mybatis中把持久层的接口名称和映射文件也叫做Mapper;
  2. Mybatis的映射配置文件位置必须和dao接口的包结构相同;
  3. 映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名;
  4. 映射配置文件的操作配置,id属性的取值必须是dao接口的方法名;
  5. 遵守3、4和5,不需要自己写dao接口实现类;

Mybatis连接池

提供了三种配置方式。
配置的位置:主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用哪种连接池。

  • POOLED:采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现。
  • UNPOOLED:采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用赤的思想。
  • JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器能拿到的DataSource不同。web和maven的war工程才可使用。tomcat服务器采用的连接池是dbcp连接池。

Mybatis中的事务

通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚。

SpringMVC第一节

SpringMVC是一种基于Java的实现MVC设计模型的请求驱动类型的轻量级web框架,属于Spring FrameWork的后续产品,以及融合在Spring Web Flow里面。Spring框架提供了构建Web应用程序的全部功能MVC模块,使用Spring可插入的MVC框架,从而在进行Web开发时,选择使用Spring MVC框架或集成其他MVC开发框架,如Struts2等。支持RESTful编程风格的请求。

  • 清晰的角色划分;
  • 分工明确,扩展灵活;

基本组件

DispatcherServlet前端控制器

用户i请求到达前端控制器,相当于MVC模式中的C,DispatcherServlet是整个流程控制的中心,由它调用其他组件处理用户的请求,DispatcherServlet降低了组件之间的耦合。

HandlerMapping处理器映射器*

HandlerMapping负责根据用户请求找到Handler,SpingMVC提供了不同的映射器实现不同的映射方式,例如配置文件方式、实现接口方式、注解方式等。

Handler处理器

开发中需要编写的具体业务控制器,由DispatcherServlet把用户的请求转发到Handler,由Handler对具体的用户请求进行处理。

HandlerAdapter处理器适配器*

通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

View Resolver视图解析器*

View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。

View视图

SpringMVC框架提供了很多的View视图类型的支持,包括jstlView, freemarkerView, pdfView等。最常用的是jsp。一般情况下需要通过页面标签或页面模板技术将模型数据通过页面展示给用户。

RequestMapping

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

//可以作用于类和方法,支持分级映射
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {

String name() default "";

//别名path和value通用,用于指定url
@AliasFor("path")
String[] value() default {};

@AliasFor("value")
String[] path() default {};


//public enum RequestMethod {
// GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
//}
RequestMethod[] method() default {};

//限定传递的请求参数
String[] params() default {};

//用于指定限制请求的头条件
String[] headers() default {};

String[] consumes() default {};

String[] produces() default {};
}

请求参数的绑定

支持简单数据类型、对象、列表等。@RequestMapping(param={username=””})

自定义类型转换器

  1. 首先实现Converter接口;
  2. 在spring配置文件中配置自定义类型转换器;

Servlet原生API

HttpServletRequest、HttpServletResponse、HttpSession、ServletContext。

常用注解

  1. @RequestParam
  2. @RequestBody get方法不适用
  3. @PathVariable RESTful风格 WebClient模拟发送请求
  4. @RequestHeader
  5. @CookieValue 获取cookie的值
  6. @ModelAttribute
  7. @SessionAttributes 用于多次执行控制器方法间的参数共享

ResponseBody相应json数据

DispatcherServlet会拦截所有资源,导致静态资源,如image、css、js等也会被拦截,解决方法就是需要配置静态资源不拦截。

Docker

Docker是一个开源的应用容器引擎;支持将软件编译成一个镜像,然后在镜像中做好各种软件的配置工作,随后将镜像发不出去,其他使用者可以直接使用该镜像;运行中的这个镜像成为容器,其优点在于启动速度。

Docker核心概念

Docker主机Host

一个物理或虚拟的机器,用于执行Docker守护进程和容器;

Docker镜像Images

Docker镜像是用于创建Docker容器的模板;

Docker容器Container

容器是独立运行的一个或一组应用;

Docker客户端Client

客户端通过命令行或者其他工具使用Docker API和Docker的守护进程通信;

Docker仓库Registry

Docker仓库用来保存镜像,可以理解为代码控制中的代码仓库,Docker Hub提供了庞大的镜像集合使用;

使用Docker

基本命令

script
1
2
3
4
yum install docker
docker -v
systemctl start docker
systemctl enable docker
script
1
2
3
4
docker search mysql #搜索mysql image
docker pull mysql #拉取镜像
docker images #查看镜像列表
docker rmi images-id #移除镜像

容器操作

script
1
2
3
4
5
6
7
docker run --name mymysql -d mysql:TAG #启动容器
docker ps #查看运行中的容器
docker ps -a #查看所有容器
docker stop container-id #停止容器
docker rm -a # 删除所有容器
docker run --name container-name iamge-name -d -p 1008:8080 #-p进行端口映射
docker logs container-id/container-name

其他命令