00:00
首先我们来先看一下整体的项目框架,那我们这个项目框架是一个ma项目,然后大家会想到,那平常我们写项目的时候,是不是就是诶一个一个大的项目,然后所有的类都往里面填,是是不是这样写的啊?呃,我们这里边给大家做一个整个项目结构的一个划分,一个安排,我们准备创建一个父子项目,这个之前大家应该也讲过,对吧?呃,所以我们的想法是什么呢?我们在最外层可能创建一个叫做movie recommend system的一个main项目。然后在这个大的项目里边会包含我们的推荐系统所有的代码,另外还会啊,到时候为了我们方便这个后期的测试联调,我们要把那个业务系统,就是spring写的那一套东西也加进来,也放在这里边来,那么大家就会想到,那我是不是应该业务系统和推荐应该是两大块儿啊,诶,所以我们就分成我们在创建一个叫recommend recommender的一个子项目。
01:05
所以在recommend里边,我们可能又要再分成多个子项目来搭建我们不同的推荐模块,对不对?哎,这是我们整体的一个想法,用父子项目的这个框架去打好,那接下来我们就来操作吧,启动idea之后我去create一个new project,对吧?啊,当然idea可能相对会比较慢一点啊,好,我这个是可能刷不出来,没关系,我们直接去创建一个group ID,我们就叫com.at硅谷就一般情况都是公司名称域名的那个道置,这个大家都熟啊,然后我们这个项目叫做movie re band system。我们创建这个项目之后,接下来就是要在里边去创建子项目了,对不对啊,大家想到这样一个过程就可以这里报错了啊。
02:08
我先把这个先,呃,那么我们进来之后可以看到已经有这样的一个po文件,那我这里边可以把这个enable auto import打开,对吧?然后我们可以看到在这边已经创建好了这样的一个ma项目,有一个po文件,呃,然后我们要做的是不是在这个里边要去新建一个模块啊,一个子模块对不对,那当然了,这个子模块还是一个maven项目,这是一个子项目,我们这个模块叫做recommender。好,大家看,我们接下来在这里就有了一个叫做recommendmannder的一个子项目,又又又有了一个这个po文件,对不对?那大家会看到这个我们之前的movie,就是最外面的副项目,它的po文件有什么变化呢?是不是会多加一个叫做modus这样的一个标签,然后里边是不是又把recommender加进来了啊,当然了,前面还加了一个package packageing poem,对吧?加入了这样一条数据,那recommender里边我们看到它是不是有一个parent啊,这是不是代表他们互相之间的一个父子项目这样一个耦合关系啊,大家如果就是熟悉的话,我们之前已经做过这些东西,应该很熟悉啊。然后我们今天要做的是什么呢?是在recommender下面是不是还有不同的模块啊,所以我们是不是再去新建new一个啊,大家看现在这个都刷出来了啊,我们这里可以去新建一个,比方说我们一开始是不是数据加载啊。
03:38
还不是推荐模块,但是数据加载也是第一个模块,对不对,我们创建一个叫做data loader的一个模块啊,这里大家稍微注意一下,我这里不能直接回车,这个name应该放在recommend的后边,对不对?好,那现在大家就看到我是不是在。Recommender下边又多创建了一个叫做data loader的一个子项目,啊啊好,那大大家会想到就是把这些这个目录结构已经创建出来之后,我们到时候写代码要写在哪里去呢?对,是不是就在data loader的source下面去写就可以了,那大家会想到我们外层的副项目是不是只是用作这个依赖管理就可以,不需要在下面直接写写一些代码,所以我们可以把这个删掉。
04:29
直接delete掉好。呃,那大家看,现在就是我们整个的这个父子项目的结构就已经建好了,然后接下来我们是不是要做这个项目管理项目的依赖管理了,对吧?大家会想到这个既然有这么几个POM文件在这里边是不是要添加很多dependency啊啊,这是大家习惯的这种写法,诶大家之前自己会手写po文件吗?不,不会手写都都是直接copy是吗?啊,当然这个我觉得copy是没问题的,因为这个手写起来还是太麻烦了一点,对吧?但是大家是看会看po文件吗?不看是吗?不看啊,那那我们还是跟大家过一下吧,我我这个就如果大家说之前没有这个经验的话,我们还是过眼啊,大家看接下来我们在po文件里边是不是应该去加一些配置项啊,首先我们要加的是什么呢?大家看,加了一堆properties properties相。
05:33
相当于是我们的一个版本信息的配置对不对?大家看这里边的所有的这个参数都是版本对吧?那本身properties相当于是在我们的泡沫文件里边定义了这样的一个变量,大家可以认为它是个变量,然后在这里定义出来,是不是就相当于我们统一的一个常量定义了对吧?在外外层直接把它定义出来,好,那么我在这里直接把它copy过来,大家看一下我们到底用到了哪些东西呢?首先love for g,这个大家很熟了,对吧?这是不是我们的一个,呃,一个具体的日志框架对不对?呃,在Java项目里边,还有这个SKY项目里边,我们经常用到的都是这样一个love for g,然后下边还有一个叫self for g的一个一个东西,这是什么呢?大家之前用过吗?没用过啊,大家一看这个名字跟log for这是不是很像啊,啊,它也是跟日志框架相关。
06:33
嗯,它是叫做简单日志门门面,它可以认为是什么呢?可以认为是日志框架的一个接口,所以就是说大家可以认为在我们的这个log for g基础上,它相当于又包了一层,然后我们调用的时候呢,就可以跟具体的log for g这个日志框架结耦了,我不需要把这个代码直接嵌入进去,对吧?啊,那我到时候要更改的时候,我直接在上层这个接口把它更改一下就可以了,所以这是这样一个简单日志门面的一个应用,然后接下来大家看,呃,我还定义了什么monggo Spark。
07:12
Mongo DB Spark,这是不是monggo和Spark之间的一个连接的组件啊,对吧,就是mongo DB和Spark的那个connector,然后大家看下面还有一个叫CASPACASPA是什么东西,大家之前用过吗?啊,大家没用过啊,这个是就是mongo,呃,大家没想没想过mongo,当然这个东西应该是没用过对吧?呃,它是go在这个skyla上的一个驱动驱动器,一个driver,当然了,这个kasar是以前经常会用到的一个东西,现在的话应该是mongo官方出了一个就是skyla driver,大家如果想要把它更新成这个官方的那个driver也是可以的,我们这里就还用以前的习惯用这个开bar,只要能跑起来就可以,对吧?啊,这个其实工具类的东西不重要,然后接下来大家看还有什么对,大家想到我们这个项目里面是不是要用到ES啊,所以ES是不是也要。
08:12
哦,我们当时提到就是data loader里边用这个Spark session要往里面写数啊,要要把数据写进去对不对,所以大家看也要有ES Spark的这个连接工具,对吧,然后是不是还有。Elastic search,这是不是?呃,在skyla里面的driver啊,也对应于我们这个kasar mongo的driver对不对,这是ES的一个driver,我们在SC里面要去调用它,那接下来还有什么啊,大家看到有red对不对,Red这个就简单一些,我们如果不涉及到用Spark跟他去做交互,往里边写数的话,我们就不用别的东西了,直接有这个就可以,对不对?然后下边大家看到还有什么呢?诶,实时的部分,那是不是需要用卡夫卡啊?呃,然后下边还应该有什么啊,对,Spark这肯定要,对不对啊,Spark version我们就统一定义了,Spark里边的几大组件是不是都按照这个版本来来用啊,这里定义好了之后,之后所有地方都一致,这就方便我们做这个版本管理,要不然大家如果po文件写乱的话,到处去就是都是写死的版本,那很有可能就在很多你新引入的组件里边,那个版本不一致就会有冲突对不?
09:29
不对啊,这个版本管理我们一般都是把它提出来啊,当然了还有SKY的版本,版本我们这里是02:11点八啊,Spark是2.1.1,这个就是这个是大家为了实现我们这个统一的话,就直接用这个版本就可以,因为这里都是我们加载的一些模块,对不对?呃,跟大家那个本身安装的系统环境里边的这个版本不一样啊,然后最后还有一个叫j plus,这这是什么东西?大家之前可能也没接触过啊,这是Java里边的一个线性代数相关的库,所以我们如果要是用一些矩阵运算的时候会用到它,大家可能会想到什么地方可能会用到呢?我们是不是要算什么余弦相似度对吧,然后后面做什么这个呃,相似度矩阵这些东西是不是有可能用到啊,所以我们把它直接引入进来,好先给大家过一下,到底用到什么东西,接下来是不是就是该添加依赖了。
10:30
那大家想一下,我们最外层的,最外层的这个负项目,它应该添加什么依赖呢?它应该添加的是里边所有子项目都用到的依赖,对不对啊,你不应该把这个就是只有某一个项目会用到依赖,你全放在这里,大家知道这放在这里的依赖是不是子项目全部都会引入啊,所以你不能在这里随便随便对吧?大家会想一想,什么东西到底是公用的呢?
11:03
我们除了这个,哎,大家想到skyla,那前面我讲到了,除了这个recommend这个子项目是不是还会有一个业务系统啊,那个业务系统是spring写的Java代码,对不对?那大家想,那skyla我在这里引入,其实那个业务系统是不是不需要啊,所以我们这里其实就剩下什么了,大家看看这里边有可能就剩下什么了。是不是就剩下日志管理可能是全部都需要的啊,啊,所以大家看我们这里在最外层的子项目添加的依赖dependencecs,就是共同的日志管理工具,呃,这里添加的是什么呢?啊,For g里边它的组件j clo,然后API还有这个log for g 12还有log g,对不对,把self for g和log for g相关的组件都加入进来啊,这就是我们这个。要用的依赖,那大大家知道这些这些东西就是要引入这个依赖,依赖包这个到哪里去查吗?诶,这里有个错啊,可能是这个copy过来的那个不太一致对吧?好呃,大家想一下,就是这些东西一般都是到哪里去找的,如果我们之前要全是copy的话,那可能大家不太熟对吧?是不是可以到那个maven官方的这个仓库里边去找啊,对吧?Maven reposity呃,在这个里边大家会看到,如果我要去,哎,大家看我搜一下这个self for g,那其实可以看到相对应的这些模块的对不对?比方说我要这个self for g API的话,我们要用的版本如果是1.7.22,那是不是点开之后就把这一块代码,大家看may文的这个,呃,依赖管理对吧?把这个复制过去就可以了,呃,所以这个是比较简单的一些操作。
12:58
大家如果以前讲过的话,回忆一下。
13:02
好,那么这里边外层副项目我们要引入的依赖主要就是共同的日志管理工具,然后大家看到除了这个依赖之外还需要什么呢?我们下面还给了一个build的标签,这是干什么?对,大家会想到我们在构建和这个打包过程当中,就是ma项目的不同的生命周期对不对?它在不同的生命周期里边是不是可以指定不同的插件去做相对应的事情啊?因为我们这里边还涉及到scla的相关的一些代码,大家会想到,呃,不同的生命周期可能会用到不同的编译工具,对吧?呃,打包工具可能也用的不一样,那我们在最外层声明什么样的东西呢?诶,大家看,首先声明了,声明了一个plug in一个插件,对吧,这个插件大家想到它声明出来是个什么东西,这里是不是相相对应的就是我们整个maven项目它的编译插件啊,那大家会看到这里边的maven compiler plug in,它对应到的是不是就是我们整个的Java代码。
14:16
所有的就是在做这个字解码,呃,编译转换的时候所要用到的这个编译工具啊,啊,所以这是我们这里要引入的它的版本,我们用的是3.6.1对吧?啊,这里给大家可以先看一眼,大家平常会点开这个ma project去看是是不是啊,这里边我们可以看到这个ma项目,大家看到这里边有这个life cycle对不对,有每一个不同的生命周期,那在这个对应的生命周期里边是不是可以添加它对应的这个插件啊,那我们在一开始什么都没有添加的时候,插件是不是只有clean deploy install和set这四个生命周期有对应的插件。别的是不是都没有定义,比方说编译是不是就没有插件用啊,那如果我们这里要去指定的话,我们把这个指定啊。
15:07
呃,我直接先考考过来吧。大家看我在这里指定了这个插件之后,诶,大家看这里刚才已经跳变了一下,对不对,多了一个是不是编译编译这个生命周期里边的编译插件,呃,所以这就已经添加在这里了,那大家知道我这里的plug in如果引入的话,是不是在每一个子项目里边都会引入啊。啊,因为它下边都会用到这样的一个编译环节,对不对啊,所以这一步就全部都引入了,好,那接下来大家看我们还有什么样的这个标签设置呢?还有一个plug in management,这是什么东西啊?Plug in management指的是跟plugin其实很像,它也是要声明对应的这个插件对不对,但是它跟这个直接plugins下面这个标签定义的不一样,是plugins标签下面声明的这些是直接就引入了,对不对?而且在下面子项目里面是不是全部都会引入啊,而我们这里plug in management下面的这个插件是不是它只是声明对应的一些配置版本之类的一些信息,而不直接引入啊,大家看到我这里声明的这个插件是不是在这里都看不到啊,好像没有看到,对不对,这里只多了一个compiler,就是前面指。
16:37
In的这个plug in,所以下面这里指定的都没有引入,它表示什么呢?就是我这里只做一个管理对吧,我先声明了,那它里边的版本是什么,我定义好了,需要什么东西,诶对应的这些配置我都定义好了,那至于子项目里边谁需要谁直接引入就可以了。
17:00
别的这些信息就不需要配了,对不对,然后你要的这些的东西,呃,要这些东西的时候,统一按这个引入版本什么的都是一致的啊,这就是这部分内容,然后大家看我们引入了两个plug in什么呢?是不是这里有一个main assembly plug in打包插件对不对啊,有可能我们打包环节会用到的,然后下面这个比较关键,大家会想到这是什么啊。Scalela plug in,这是不是要把skyla代码做编译的过程需要用到的这个插件啊?那大家会想到我们是不是在下面recommender里边就应该得引入这个插件啊,啊,所以我们现在把这个最外层负项目的po文件,如果已经搞定的话,接下来我们看到这个recommend文件里边,呃,这个po文件里边需要去做什么样的声明,好,那首先大家想到是不是这里边build里边,我是不是就应该把。Scalela ma plug in引入进来啊,啊,这个是不是必须的,因为下面本来这里边就都是skyla代码对吧,所以应该下面的子项目都需要这个东西,我们就把它引入好,那大家会看到就是我们把这个引入之后,这里是不是就多了一个啊,看到了吗?
18:20
Skyla maven plug in是不是已经引入进来了,它引入进来之后,是不是它的子项目就会多一个skyla maven plug in啊,就是这样的啊,当然了,在这个它的副项目里边当然就没有,对不对啊,这就是这一部分,那我们定义了这个scalela编译环节的插件之后,另外还要定义一些dependency,对不对,在我们的这个recommend模块里边,大家看我这里就没有用dependency。Dependcies直接定义所有的依赖,而是用了dependency management,为什么呢?
19:00
大家会想到这是不是也是只声明还不引入啊,然后我先规定了所有的这些版本啊,配置一些相关的信息,子项目里边你们如果需要的话,就直接声明声,呃,就直接引用一下,引入就可以了,版本就不需要再定义了,我这里统一管理对不对?诶,这是这样的一个考量,因为大家想到我们下面的子项目是不是有一些模块不一定都要引入啊。好,我们首先看一下这里边引入的都是什么,我们这里引入的是什么呢?是不是跟Spark相关的都要放进来啊,推荐模块是不是核心就是用到了这个Spark相关的东西,呃,那我们Spark相关引入什么呢?Spark car要不要啊,这肯定要,对不对?然后下边大家会想到Spark star组件,Sparkq Spark streaming Spark ML lab Spark graphics,是不是我们这里就先不管用不用先都声明出来对不对啊,有可能我们在推荐的模块里面都要去有,最后还有一个声明了一个什么skyla library,这是不是也是都有可能用到的啊?当然大家如果认为我们就里边就全部都是SC代码的话,那应该这个就直接直接声明出来,引入声明并引入就对了,对吧?我们这里是考虑到下面可能还会涉及到一点点的Java代码,所以说我们这里就只是只声明不引入好。
20:27
那这个recommend,这个依赖也都已经搞定了,接下来最后我们今天要写的data loader,大家要想一下到底要什么了,对吧?Data loader我们要做什么事情呢?我们想要做的是从已有的文件里边,然后用Spark Spark session,呃,Spark c,对吧?然后把这个数据读出来,做一些处理之后,是不是要写入到mango和ES里面去啊?
21:01
那大家会想到这个过程里边Spark是不是相关的东西肯定要啊。那Spark里边是所有的组件都要吗?大家想一下,好,我们继续看啊,来看Spark空要不要,Sparkq要不要啊,这两个肯定要,对不对,然后ML lab要不要。ML lab是做机器学习对吧,我们现在这个data loader加载加载数据的时候,哎,这个小模块是不是就不需要啊对,然后最后graphics要不要图计算处理streaming需不需要。实时data loader加载数据写到数据库里边,好像不需要实时对吧,没有任何实时的这个日志啊,对吧,这个卡夫卡那边东西过来,所以说我们这里边的东西其实很简单,这其实就是一个离线程序,对不对,所以大家会看到我们这里引入的Spark相关的就是Spark和Spark c。
22:08
然后接下来那skyla library要吗?这个是不是肯定要啊?呃,既然你跟这个,呃,我们这个skyla相关东西都需要,那肯定这个是需要的,接下来我内容是不是要写到mongo和ES里啊,那是不是跟mongo ES相关的东西都得加入进来啊,大家看到这里我们就加入了mongo的驱动是不是开SPA啊,它的版本是不是就用这个Dollar,然后加上大括号括起来,这是不是就是我们一开始定义在负项目里边。定义在properties里边的那个内容啊,就相当于一个变量一样引入了对吧?那接下来mongo是不是还有一个叫做mongo DB Spark connector啊这样一个东西,对不对啊,把这个东西也引入,呃,当然了,就是说为什么要引入这些东西呢?大家可以就是到官网上去搜一下,就看看它的那个事例是怎么用的,其实也就知道了,对吧?这里我们就给大家一个例子就好,同样的是不是还应该有ES相关的驱动和它的这个跟Spark连接器啊呃,大家看这里边引入的是ES client下面的一个transport这个这个模块,然后还有一个ESSPA这个连接器,这是我们想要用的东西,当然这里边还写了一个这个exclusions,这代表什么?就是把不需要的依赖的东西从路径里边除去,对不对,那这里边大家看到它里边是有一个have的相关的service的,我们这里边跟have没关系,所以就可以把它直接除去,除去对吧?啊这个其实是大家一看就能。
23:42
能够理解的,我把这一部分直接copy过来。大家觉得有问题吗?没问题是吧?呃,我希望大家就是说,像这个POM文件确实不需要每一次我们都去手敲,但是大家即使是把它直接这个就是抄过来,你也得知道为什么抄,对吧?到底我到底是需要哪些东西,我的这个项目架构为什么会这么设置,负项目里边用什么,子项目里面用什么,大家应该还是有一个概念的。
我来说两句