这两天按照慕课网视频,跟着老师打了一遍代码,走了一下SparkSQL的离线数据处理流程,为此做一下整理和小结
> 项目源码参见:https://github.com/pontsh/ImoocSparkSQLProject
### 一、离线处理架构(基于上述日志分析项目)
- (一)数据采集:在线/离线搬运(如Flume)
- (二)数据清洗:Spark(或其他分布式计算框架)处理,放到HDFS上(如hive数据库或其他sparkSQL数据)
- (三)数据处理:Spark(或其他分布式计算框架)处理
- (四)结果入库:计算框架调用api,结果存于RDBMS
- (五)结果可视化:可用ECharts、Zeppelin等
### 二、项目实施流程
> 未包含部署于YARN,性能调优,待日后补充
- (一)需求分析
> 事实上,本项目只实现了一个“根据日志统计主站访问TopN的资源”的统计,其他TopN类型应举一反三
- (二)数据清洗
> 清洗可分为两个阶段:1.日志整理:按需求提取日志文件字段并整理各字段格式,生成clean1.log;
2.日志解析:按需求解析clean1.log中字段为所需信息,生成最后的待处理clean2.log
> Tips:日志解析阶段可能需要调用其它人的maven项目,注意事项及操作见 四、更多
- (三)数据处理
> Tips:本项目中数据处理较简单,方式有两种:1.DF API;2.spark.sql()。这两种方式结果应完全一致,可相互检验。
- (四)结果入库
> 主要过程为:拿到连接实例 => 统计结果转为DAO实体类 => 通过DAO操作将结果入库
> 本项目采用了JAVA中DAO的编程模式,该模式可类比MVC架构理解,详见 四、更多
- (五)结果可视化
> Tips:我尝试用虚拟机上zeppelin获取本地mysql数据,遇到 Host 'XXX' is not allowed to connect to this MySQL server
因调试比较顺利,个人觉得是思路较清晰的原因,故大致做下记录:
1.服务本身:能够访问zeppelin页面或运行jps命令发现输出中有zeppelinserver,确认服务正常启动;
(页面访问注意防火墙策略,用jps最方便直接)
2.连接的网络问题:再测试本地与虚拟机的网络连通性,确认可ping通
3.连接的配置问题:先测试能否连接localhost的mysql数据库,确认jdbc类型的interpreter没问题
(此处一般问题会有ConnectionURL不对、用户密码不对、驱动路径不对的问题)
4.连接的权限问题:查阅资料,通过GRANT为虚拟机IP授权远程连接,重启本地服务,解决
> Tips:Notebook中,使用一个%interpreter_name就会申请一个资源,但zeppelinserver只有一个,最后记得关闭资源。
### 三、调优点简记(原理未明)
- (一)数据清洗阶段:可在最后clean2.log中增设分区字段,并权衡读取小文件和处理大文件造成性能上的降低,应视日志规模设置按天/时/5分钟进行分区,在数据写入时设置分区个数(调用DF相关API,参见github代码)
- (二)数据处理阶段:1.spark.sql.sources.partitionColumnTypeInference.enabled设置为false(禁用自动转化数据类型?)
2.JDBC编程模式中,DAO操作类考虑采用Batch。具体而言,就是先prepare好sql,把它们添加到批次中(pstmt.addBatch()),再批量执行(pstmt.executeBatch()),最后一次性commit(须实现配置关闭AutoCommit)
### 四、更多
#### (一)如何使用github已有的maven项目
- 1.找到remote repository,git clone之
- 2.mvn工具编译之(mvn clean package -DskipTests),生成jar包A
- 3.安装A至maven的local repository
> 如本项目中
mvn install:install-file -Dfile=<jar_path> -DgroupId=com.ggstar -DartifactId=ipdatabase -Dversion=1.0 -Dpackaging=jar
> Tips:本例groupId采用了源码中main目录下的结构,事实上groupId和artifactId可自己指定(mavenGAV管理机制)
> Tips:若success,应看到jar和pom文件的[INFO],若拷贝到的本地仓库非IDEA中设置的,需调整一致,我采用修改MAVEN_HOME/conf/setting.xml中<LocalRepository>方式
- 4.在自己项目的pom.xml中添加该依赖
- 5.测试使用
> Tips:常见报错及原因(1)NoClassDefFoundError:一般而言,是依赖项目pom.xml的依赖未在自己项目中导入
(2)FileNotFoundException:一般而言,是依赖项目的resource目录或其中文件在自己项目中缺失
#### (二)JAVA的DAO模式
> 可类比php中MVC架构
> 注意:因为需要JDBC,所以需要JAVA_HOME/jre/lib/ext/下放置驱动jar包,否则No suitable driver
- 1.定义连接实例化和资源释放操作类
- 2.定义DAO实体类
> 类比MVC中Model,即数据模型
> scala中常用case class指定
- 3.定义DAO操作类
> 类比MVC中Controller,即控制器
#### (三)关于"value foreach is not a member of Object"的debug
> 我应该抓住一点,报错信息是毋庸置疑的,首先不要尝试自己做各种假设……按字面意思理解,就是该对象没有foreach方法,很显然,就是对象类型上出了问题,可尝试直接println对象的type、转化对象的type(这次就是折腾了好久没有用这个,源码可信度当然大于视频教程,何况我当时一直很没发现视频中scala源码跟自己的不一样!看源码要注意看注释和对象类型)、改用其他迭代方法(适可而止!这次栽在这个死胡同里了。一个思路行不通,应适时重新审视报错信息)
> 再见下图,心中百感交集 —— 回去好好学学RDD