(二)真实项目-总体架构

整体架构

在这里插入图片描述

项目展示

用户数据:
在这里插入图片描述

订单监控:

在这里插入图片描述

1、项目架构及解决方案论述

在这里插入图片描述

1.1 通过binlog方式实时梳理业务库高QPS压力

QPS:Queries Per Second意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。

官网binlog介绍

MySQL中通常有以下几种类型的文件:

日志类型写入日志的信息
错误日志记录在启动,运行或停止mysqld时遇到的问题
通用查询日志记录建立的客户端连接和执行的语句
二进制日志记录更改数据的语句
中继日志从复制主服务器接收的数据更改
慢查询日志记录所有执行时间超过 long_query_time 秒的所有查询或不使用索引的查询
DDL日志(元数据日志)元数据操作由DDL语句执行

业务背景:

​ 通常我们在进行业务系统开发是开始都会采用关系型数据库(Mysql,Oracle),随着业务量的增大导致数据量增大,我们需要对架构进行调整演进出来主从架构(主库负责写,从库负责读),随着业务量的持续增大我们需要进行分库分表来降低单个表中的数据存储,但是单个表中数据量达到400w~500w性能比较底下,让人无法接受,如果我们按照分库分表的策略进行操作会随着业务量的不断增长导致数据库集群的维护工作变得更加复杂,同时会带来更多的问题:

  • 辅助索引只能局部有效;
  • 由于分库,无法使用join等函数;由于分表count、order、group等聚合函数也无法做了;
  • 扩容:需要再次水平拆分的:迁移数据……

在这里插入图片描述

当我们遇到如下业务场景时:

1.业务更新数据写到数据库中

2.业务更新数据需要实时传递给下游业务依赖处理

处理架构如下:

在这里插入图片描述

但这个架构也存在着不少弊端:我们需要在项目中维护很多发送消息的代码。新增或者更新消息都会带来不少维护成本。所以,更好的处理方式应该是直接将数据库的数据接入到流式系统中,使用大数据生态圈中的相关技术来剥离业务数据的后续处理以及最大化优化读数据的能力从而减少业务库的压力,业务库只关心数据的写入即可,新的设计架构如下图:

在这里插入图片描述

使用maxwell拉取的方式实时监听mysql数据库的binlog文件

1.2 内置源码模块,细粒度监控Spark作业,失败及时邮件报警

业务背景:
通常我们在使用Spark进行数据分析时,需要对Spark应用程序进行性能的优化,此时我们就需要知道Spark应用程度内部涉及到的Job,stage,task的运行情况,虽然Spark UI中已经有了可以查看Job,stage,task运行时的一些信息,但是都是粗粒度的,如果业务中需要更细粒度的监控时就需要开发代码,同时,可以进行自定义一些任务失败时通过邮件通知运维人员及时关注业务运行情况和集群资源使用情况.

监控整个application开始执行状态
监控整个application结束的状态
监控整个Job开始执行状态
监控整个Job结束状态
监控Spark stage提交时状态
监控Spark stage完成时状态
监控Spark task开始时状态
监控Spark task完成时状态
监控整个作业的内存和磁盘变化
监控整个job上下文环境
监控rdd缓存变化状态
监控executor状态

通过实现SparkListener(离线Spark应用监听器)和StreamingListener(实时流Spark应用监听器)来达到对多Spark应用运行时状态的细粒度监控

1.2.1 spark离线任务监控

com.cartravel.programApp.ReadController //启动SparkEngine引擎
com.cartravel.spark.SparkEngine //主要用于把自定义的SparkAppListener的监听器给调用起来
com.cartravel.spark.SparkAppListener //离线监听Spark应用运行状况

1.2.2 sparkstreaming实时任务监控

com.cartravel.programApp.App  //创建KafkaManager实例
com.cartravel.spark.StreamingMonitor //监控Spark实时作业状况
com.cartravel.kafka.KafkaManager //启动StreamingMonitor

com.cartravel.kafka.KafkaManager类中启动StreamingMonitor

val endTime = System.currentTimeMillis()
            Logger.getLogger("处理事务").info(s"插入数据需要的时间:${(endTime - startTime)}")
            ssc.addStreamingListener(new StreamingMonitor(ssc , sparkConf , batchDuration.toInt , "query" , rdd , kafkaManager))

1.3 覆盖源码自定义数据源实现数据加载,从源头进行列剪枝

业务背景:

​ 目前Spark框架是大数据开源技术中比较流行的分布式计算框架,而HBase是基于HDFS之上的分布式列式存储数据库,使用Spark作为实时和离线数据分析的也越来越多,最后把处理的结果保存到HBase中做实时的查询。或者现在越来越多的企业针对用户的行为数据建设用户画像和推荐系统都在使用HBase作为存储媒介,供客户端使用,然儿往往HBase中存储的用户和物品的数据性比较多,我们使用到的属性列比较少,这时我们就需要按需(也就是按照列)查询HBase中的数据,Spark和Hbase集成时默认进行的是全表扫描,这样会代码一个问题,如果表中有几十个G的数据时就会一次性扫描放到内存中,然后在内存中进行按列过滤,这样就会造成内存,磁盘,网络IO的压力,如果按照列进行扫描数据的话,压力会大大减少数十倍或者数百倍之多.

实现方案:

在这里插入图片描述

1.4 自定义维护Kafka的偏移量管理,实现exactly once

业务背景:

​ 通常项目开发过程中,我们使用SparkStreaming和Kafka集成处理,Kafka的自动管理offset就能够满足大部分需求,但有些场景我们要保证主体中的消息只能被处理一次,不能出现重复消费的问题,这时我们就需要使用Kafka提供的手动维护offset的功能。

实现方案:

1.业务处理的地方禁用到kafka自动提交offset的配置项.

2.把偏移量手动保存到zookeeper(或hbase)中的一个数据节点中.

3.业务处理时首先获取zookeeper(或bhase)中的偏移量,如果能获取到那就从获取到的offset处进行消费,如果获取不到那就从latest处进行消费,然后把消费掉的offset保存到zookeeper中的数据节点中.

1.5 实现前后端rest接口的开发规范

[参考rest设计文档]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值