Flink项目之电商实时数据分析(一)
一:项目介绍
-
背景
本项⽬目主要⽤用于互联⽹网电商企业中,使⽤用Flink技术开发的⼤大数据统计分析平台,对电商⽹网站的各种⽤用户⾏行行为(访问⾏行行为、购物⾏行行为、点击⾏行行为等)进⾏行行复杂的分析,⽤用统计分析出来的数据,辅助公司中的PM(产品经理理)、数据分析师以及管理理⼈人员分析现有产品的情况,并根据⽤用户⾏行行为分析结果持续改进产品的设计,以及调整公司的战略略和业务。最终达到⽤用⼤大数据技术来帮助提升公司的业绩、营业额以及市场占有率的⽬目标。
- 项目架构
- 项目架构
-
项目技术选型
-
存储层定位
HBase是根据⾕谷歌的BigTable设计的。典型的应⽤用场景就是不不断插⼊入新的信息(⾕谷歌的情况下就是互联⽹网上新⽣生成的⽹网⻚页),⽽而不不怎么修改。⽐比如现在Facebook的messenger就是⽤用HBase实现的。这里要提到HBase是按列列存储的,所以特点就是插⼊入快,读取快
-
计算层定位
这几年年大数据的⻜飞速发展,出现了了很多热门的开源社区,其中著名的有 Hadoop、 Storm,以及后来的 Spark,他们都有着各自专注的应用场景。 Spark 掀开了了内存计算的先河,也以内存为赌注,赢得了了内存计算的⻜飞速发展。 Spark 的⽕火热或多或少的掩盖了了其他分布式计算的系统身影。就像 Flink,也就在这个时候默默的发展着。
⾸首先第⼀一代的计算引擎,⽆无疑就是 Hadoop 承载的MapReduce。这里⼤大家应该都不会对MapReduce 陌⽣生,它将计算分为两个阶段,分别为 Map 和 Reduce。对于上层应⽤用来说,就不不得不不想⽅方设法去拆分算法,甚至于不得不在上层应⽤用实现多个 Job 的串联,以完成一个完整的算法,例如迭代计算。
由于这样的弊端,催生了支持 DAG 框架的产生。因此,支持 DAG 的框架被划分为第二代计算引擎。如 Tez 以及更上层的 Oozie。这里我们不去细究各种 DAG 实现之间的区别,不过对于当时的 Tez 和Oozie 来说,大多还是批处理的任务。
接下来就是以 Spark 为代表的第三代的计算引擎。第三代计算引擎的特点主要是 Job 内部的 DAG ⽀支持(不跨越 Job),以及强调的实时计算。在这里,很多⼈人也会认为第三代计算引擎也能够很好的运行批处理的Job。
随着第三代计算引擎的出现,促进了了上层应用快速发展,例如各种迭代计算的性能以及对流计算和SQL 等的支持。 Flink 的诞生就被归在了第四代。这应该主要表现在 Flink 对流计算的支持,以及更一步的实时性上面。当然 Flink 也可以支持 Batch 的任务,以及 DAG 的运算。
首先,我们可以通过下面的性能测试初步了解两个框架的性能区别,它们都可以基于内存计算框架进行实时计算,所以都拥有非常好的计算性能。经过测试, Flink计算性能上略好。
Spark和Flink全部都运行在Hadoop YARN上,性能为Flink > Spark > Hadoop(MR),迭代次数越多越明显,性能上, Flink优于Spark和Hadoop最主要的原因是Flink⽀支持增量迭代,具有对迭代自动优化的功能 -
中间层-消息队列定位
Kafka是由LinkedIn开发的⼀一个分布式的消息系统,同时⽀支持离线和在线⽇日志处理理。Kafka框架本身使⽤用Scala编写,因其可⽔水平扩展和⾼高吞吐率⽽而被⼴广泛使⽤用。⽬目前,越来越多的开源分布式处理理系统如Cloudera、 Apache Storm、 Spark都⽀支持与Kafka集成。Kafka的持久化⽅方案是写⼊入磁盘,虽然内存读写速度明显快过磁盘读写速度,但Kafka却通过线性读写的⽅方式实现快速读写。
kafka的优点
1、解耦和扩展性:
消息队列列中间件都有着解耦的功能,解耦也意味着扩展性。将复杂的代码逻辑移至到远端程序上,而源程序本身只需要发送⼀个消息,通知远端程序消费。两边的程序可以独立扩展、修改,不相互影响。
2、冗余:
Kafka会将partition中的消息存储一段时间,消息即使被消费了,也不会被立即删除,通过这一⽅方式规避了数据丢失风险。
3、削峰填⾕谷
我们不能以一个应用系统峰值流量所需要的资源来部署服务,因为这样的突发流量量并不常见,所以这会是巨大的浪费。那么,系统具有削峰填谷”的能力是至关重要的。使用消息队列将峰值时的流量请求持久化,待稍后流量正常或低谷时再取出消费。
4、容错性
当消费者组中的其中⼀台或几台消费者实例挂掉,它们消费的partition消息会被转移到同组的其它存活着的消费者实例。系统的⼀部分组件失效时,不会影响到整个系统。
5、顺序保证
Kafka保证⼀一个Partition内的消息的有序性。 -
数据库同步定位
企业运维的数据库最常⻅见的是mysql;但是mysql有个缺陷:当数据量量达到千万条的时候, mysql的相关操作会变的⾮非常迟缓;如果这个时候有需求需要实时展示数据;对于mysql来说是⼀一种灾难;⽽而且对于mysql来说,同⼀一时间还要给多个开发⼈人员和⽤用户操作;所以经过调研,将mysql数据实时同步到hbase中;
最开始使⽤用的架构⽅方案:
Mysql—logstash—kafka—flink—hbase—web
Mysql—sqoop—hbase—web
但是⽆无论使⽤用logsatsh还是使⽤用kafka,都避免不不了了⼀一个尴尬的问题:他们在导数据过程中需要去mysql中做查询操作: -
二:工程创建
-
创建一个maven项目flinkCase
-
创建子项目Flink实时i业务处理模块realProcess
-
创建数据库同步模块
-
创建上报服务模块
1、注意将spring-boot-starter-parent版本修改成1.5.13.RELEASE,高版本不支持
2、将上报服务作为WEB服务
如果将springCloud作为web服务,需要导⼊入⼏几个必须包: 2.4.3:验证springBoot⼯工程是否创建成功 编写ReportApplication,⽤用来收发数据 <!--web需要包spring-boot-starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina - -> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina</artifactId> <version>8.5.35</version> </dependency>
3、验证SpringBoot工程是
1、编写ReportApplication,⽤用来收发数据 <!--web需要包spring-boot-starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina - -> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina</artifactId> <version>8.5.35</version> </dependency> 2、编写APP,作为⽤用来启动springBoot的⼊入⼝口 package com.ityouxin.report.Controller; import app.App; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SpringBootApplication @Controller @RequestMapping("ReportApplication") public class ReportApplication { /** * @param json 接收的数据 * @param request * @param response * */ @RequestMapping(value = "retrieveData") public void retrieveData(String json , HttpServletRequest request , HttpServletResponse response){ System.out.println("验证⼦子⼯工程创建成功" + json); } } package com.ityouxin.report.Controller; import com.ityouxin.report.Controller.ReportApplication; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Created by ityouxin */ @SpringBootApplication public