开发者学堂课程【大数据分析之企业级网站流量运营分析系统开发实战(第二阶段):网站流量日志分析--数据预处理--实现思路详解】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/694/detail/12188
网站流量日志分析--数据预处理--实现思路详解
内容介绍
一、 第一个阶段,map阶段
二、 第二个阶段,reeduce阶段
一、 第一个阶段,map阶段
打开画图板, m 码在进行设计的过程当中,重点考虑的就是每个阶段的 k 和 v。接下来画图看一下,比如左边这里有输入数据的目录,就是待处理数据,这个数据交给m码来处理,m码的第一个阶段叫做 map 阶段,在 map 阶段运行的 task 称之为maptask。比如说数据被分为多少个,这是第一个阶段,叫做 maptask。
有了 maptask 之后,接下来就要确定 maptask 的输入和输出分别是什么?首先来考虑一下它的思路,maptask 的输入默认由读数据组件来确定,而m码当中默认读数据是读一行返回一行的kv对,确定一下输入的k1和v1, k1很简单,叫做每行的起始偏移量,就是光标所在开始的位置;v1比较重要,代表的是该行的内容,这样一行内容传进来之后变成一个 kv 对交给 maptask 进行处理,这一行内容就是数据当中的这一条日志。因为它是默认按照行来切割,读一行传一个kv对,在这一行传递时候,就可以进行相关的数据处理,比如拿到字段开始切割,该过滤的过滤,不合法的删除掉,需要转换的转换,该需要编码的进行编码。任何操作都可以进行,也就是说在map当中,要进行读取数据进行预处理。
二、 第二个阶段,reeduce 阶段
maptest 出来之后就涉及到下一个阶段叫做 reduce 阶段,叫做 reducetask,这时就会产生一个问题,如果有 reducetask 的话,maptask 的输出就是它的输入,那就要考虑处理完这一行记录之后该以k还是v作为输出,k有很多默认的属性,以什么作为k那么相同的就会聚集到 reduce 来进行处理,这时候看一下数据,有好多个字段属性,关于这个日记日志当中具体属性的描述的在讲义当中,在采集这里有数据内容压力,当中一条日志大概会有这些字段属性信息有访客的IP,接下来是访客的用户信息,然后是请求的时间、请求的方式、请求资源的路径,按照使用的IP协议版本,后面304是响应码,再后面是发送的数据量,就是向服务器发送请求会返回多少数据量,接下来是访客的来源,最后一个叫做终端信息,大概一条记录有这么多字段信息,应该把这里面哪个字段作为k,究竟把谁作为k相同的就会聚合聚到一起。
这时候就产生一个问题:在的预处理的过程中需不需要聚合的操作,如果需要聚合操作的话,就把对应的那个聚合操作的那个需求作为k就能聚合到一起。
读取一行日子经过处理,处理完之后再输出一行,这里没有任何聚合的需求,所以可以得到结论,本项目中没有聚合的需求,既然没有许可的需求,翻译成m码程序也就意味着没有 reduce 阶段也就是操作的需求。
这个时候就会产生一个问题,在默认情况下,m 码程序有 reduce 阶段,而且默认是有一个 reducetask。这时候产生下一个问题:m码程序可不可以没有 reduce 阶段,答案是可以的,既然可以没有reduce阶段,意味着 reducetask 为零,默认是一,怎么能没有 reduce 阶段呢,在代码当中,通过设置 reducetask 个数apr,叫做iob.setNUMReducetasks
,把这个参数设置零就可以了。这样就是一个reduce阶段的输出,这时候m码的输出作为最终的输出,所以在这个图当中没有reduce阶段,因为没有聚合需求,没有 reduce 阶段意味着 map 阶段的输出就是最终的输出,来到默认的输入数据的组件进行输出即可,但是哪怕没有reduce阶段还要进行数据输出,输出还是需要确定k和v是什么。这时候k和v是什么呢?回到数据当中,读取一行数据进行切割处理当中的一些字段属性,判断字段是否有效,字段个数有没有丢失,处理完之后还需要原封不动的把这条记录写出去,这时候会涉及到一些m码的编程技巧。
一条记录大概有IP、时间、请求等好几个字段,好几个属性,那么涉及多属性传递,怎样去传递,以什么类型来携带数据。第一种方式,定义字符串string buff把这些属性做一个拼接,拼接成一个字符串写出去,;第二个,在JAVA当中通常会建立javabean的概念,里面设置相关的私有属性来表明各个字段提供标准的方法就可以传递数据了,所以这里有很多的m码编程技巧。
1. mapreduce编程技巧
(1) 第一个叫做涉及多属性数据传递。通常建立javabean携带数
据,这是最高效的,既然使用加密器的数据,就要想到一点比如数据叫做weblog,这里写一个对象叫做weblogbean,这样就测得这个对象,但是设置的这个对象需要在m码框架中跨网络进行传递,还需要持久化写到文件当中,这时候涉及到一个自定义对象的网络传递持久化,写一个序列化机制,不要忘记实现hadoop序列化机制,而不是java的,所以携带数据并且需要实现hadoop的序列化机制,它的序列的话其实是一个接口叫做writable,要实现这个接口,里面实现两个方法就可以了。
用weblogbean来作为k,那么这个k这个对象写的时候,如果不去修改任何方法,直接输出的是对象的地址,那通常就要用默认方法,去写对象,去打印对象,这里又产生第二问题,为了让对象的属性看起来更加的方便,有利于后面的处理是不是有意识的把对象的初始对方法当中的字段以/001进行分割。
后面roothave仓库处理have当中默认的分割符就是/001,在输出对象的时候,底层默认会掉对象的叫做tostring方法。
(2) 第二个编程技巧,有意识的重写对象的tostring方法,并且
以/001进行字段的切割,便于后续的数据入库操作。k确定之后,接下来还有一个问题v是什么呢。要把这一条记录所有的字段封装成一个对象之后,已经没有其他数据来进行输出,hadoop提供了一个非常暴力的类型,叫做空类型nullwritable,这时候类型确定非常方便。这个类型就是作为v,nullwrutable最后的输出等于默认不输出,核心的数据还是在对象当中就要把属性写出来。
这就是整个m码处理数据当中的一个编程思路和思想,具体怎么处理是业务问题。
需要对时间日期做转换,字段缺失的进行删除,逻辑删除,表明它是一个张数据。但整个技术层面需要有这些思路,才可以保证接下来可以写代码完成数据的预处理操作。