Apache Kylin在OA日志结构化中的应用

1、生产场景

OA非结构化日志通过kafka传来,已有一程序实现将其结构化并存放至Hdfs上,并且在Hive中之于这个文件做了外表关联。需要通过对kylin 的二次开发,实现其每天的日志分析需求。

2、问题剖析

OA日志结构化通过kylin来分析,和之前的OA数据导入还是有区别的,首先每天只需要刷一天的数据,不需要担心或者处理之前的数据,其次Refresh功能也只是针对当日的数据,过了今日就不会对之前的数据进行refresh了。理清了这两点,发现问题并没有之前的那么棘手了,之前还有segment忙时等待设计,现在我只要让kylin定时的刷那个segment,就不需要刻意的记录什么了。

3、方案设计

①方案设计一

根据系统时间定时,segment按天来,且均为当日的零点到次日零点,比如要刷今天了,segment的时间区间为:2016-10-07 08:00:00~2016-10-08 08:00:00,每隔一个小时刷一次,每次刷,先去向kylin请求,看日志对应的cube中是否存在今天的segment,没有就去hive中查,看当天的数据是否来了,来了则去刷,并且是add操作,数据没来则不去刷,非第一次刷,且有数据则进行refresh操作,当初这样设计的,是想着业务上可能到23:00:00后就没数据了(后来证明,小伙子想的挺美的哈),因为oa日志数据是人触发的,通过点击生成,23:00:00不就早下班了嘛,后来老大提醒了我,万一加到23:59:59分了,对哦,确实忽视了,所以方案一扑街,不过后来又细细想了想,其实还是可以稍作改动就可以继续正常的,因为方案一的设计唯一的盲区是在当天的23:00:00~24:00:00,只要我第二天把前一天的这段盲区加到例行检查不就ok了,实现起来,也不需太大的改动。

②方案设计二

方案设计二,不基于系统时间,而是基于oa日志的最大时间,有两份配置文件,其中一份配置文件存放两列,第一列为cube名称,第二列为最近一批更新的oa日志的最大时间,还有一份配置文件有三列,第一列为cube名,第二列为对应的主表名,第三列为主表对应的时间字段。
具体设计思路如下,存放最大时间的配置文件每次会更新,每处理完一批日志,把处理的这批日志中的最大时间覆盖更新至该配置文件。与Hive交互的有两条SQL,第一条用来查询hive中存放的数据中大于配置文件中最大时间的数据,并以(yyyy-MM-dd)格式存放至Set集合中,第二条用来存放,当前hive中的最大时间,并以(yyyy-MM-dd hh:mm:ss)格式写入配置文件中。更新的时候,就遍历相应cube中的相应的set,通过kylin返回的buf如果有exception,说明是需要add的数据,否则统统refresh。具体实现代码如下:

/*
 * 拟定每30分钟执行一次
 */
public void run(){
            OaLog oa = new OaLog();
            JavaHive jh = new JavaHive();
            cubeSet=rw.readConfigFile(PropertyUtil.prop.getProperty("configFile"));
            rw.readTimeFile(PropertyUtil.prop.getProperty("timeFile"));
            StringBuffer  newMaxTimeBuf = new StringBuffer();
                for(String cubeName:cubeSet){
                    System.out.println(cubeName);
                    jh.queryDataTime(cubeName,rw.cubeMax.get(cubeName), rw.cubeTime.get(cubeName),rw.cubeTable.get(cubeName),PropertyUtil.prop.getProperty("hiveIp"));
                    newMaxTimeBuf=jh.queryMaxTime(cubeName,rw.cubeTime.get(cubeName),rw.cubeTable.get(cubeName),PropertyUtil.prop.getProperty("hiveIp"));
                    Map logTimeMap=jh.initMap.get(cubeName);
                      if (logTimeMap!=null) {
                          Set logTimeSet=logTimeMap.keySet();
                          for (String logTime1:logTimeSet) {
                                if(je.isSegmentExist(oa.refreshCube(logTime1,time.getNextDate(logTime1),cubeName,PropertyUtil.prop.getProperty("kylinIp")).toString())){
                                    oa.addSegment(logTime1,time.getNextDate(logTime1),cubeName,PropertyUtil.prop.getProperty("kylinIp"));
                            }     
                          }
                      }
                    }   
                if(newMaxTimeBuf.toString()!="\t\r\n"){
                  rw.writeToFile(PropertyUtil.prop.getProperty("timeFile"),newMaxTimeBuf.toString());
                }
        }

先读取两份配置文件,然后同hive交互,通过两条sql查询待刷数据以及最大时间,并且将最大时间放至newMaxTimeBuf中,等遍历完所有的cube后,一次性覆盖写入至time.properties文件中,待刷新的数据放到logTimeSet中,直接拿去refresh,通过isSegmentExist方法判断返回buf中是否存在exception,进而判断对应的segment是否存在,如果isSegmentExist返回true,就进行if判断,说明返回buf中有exception,进而说明对应segment不存在,刚好执行if中的addSegment操作,如果isSegmentExist返回false,不执行if判断中的内容,判断条件中已经包含refresh语句,此时cube已经刷了起来。

4、优化设计

较之前数据导入那块,将数据导入以及守护进程的检测j错误状态的job分为两个project,运行时比较繁琐,对于OA日志结构化,采取的是通过任务调度,开辟两个线程,守护进程拟定8分钟执行一次,集成到了对接kylin的程序中。

你可能感兴趣的:(Apache Kylin在OA日志结构化中的应用)