Titan 数据运营系统 --数据的采集和ods开发

一:埋点数据的采集

1.1埋点日志在本项目中,有3大类:

①App端行为日志
②PC web端行为日志
③微信小程序端行为日志

日志生成在了公司的N台(5台)日志服务器中,现在需要使用flume采集到HDFS

1.2需求

3类日志采集后要分别存储到不同的hdfs路径
①日志中的手机号、账号需要脱敏处理(加密)
②不同日期的数据,要写入不同的文件夹,且分配应以事件时间为依据
③因为日志服务器所在子网跟HDFS集群不在同一个网段,需要中转传输

1.3埋点数据中的结构和说明

埋点生成的日志数据,统一设计为JSON格式;
各个终端渠道的埋点日志,都由公共属性字段,和事件属性字段组成;
①不同终端渠道,公共属性字段略有不同;
②事件属性则根据事件类型,灵活多样;

1.4flume采集数据设计方案
在这里插入图片描述
1.5具体实现
1.5.1上游文件配置

a1.sources = r1
a1.channels = c1
a1.sinks = k1 k2

a1.sources.r1.channels = c1
a1.sources.r1.type = TAILDIR
a1.sources.r1.filegroups = g1 g2
a1.sources.r1.filegroups.g1 = /opt/data/logdata/app/event.*
a1.sources.r1.filegroups.g2 = /opt/data/logdata/wx/event.*
a1.sources.r1.headers.g1.datatype = app
a1.sources.r1.headers.g2.datatype = wx
a1.sources.r1.batchSize = 100

a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = cn.doitedu.flume.interceptor.EventTimeStampInterceptor$EventTimeStampInterceptorBuilder
a1.sources.r1.interceptors.i1.headerName = timestamp
a1.sources.r1.interceptors.i1.timestamp_field = timeStamp
a1.sources.r1.interceptors.i1.to_encrypt_field = account

a1.channels.c1.type = file
a1.channels.c1.checkpointDir = /opt/data/flumedata/file-channel/checkpoint
a1.channels.c1.dataDirs = /opt/data/flumedata/file-channel/data

a1.sinks.k1.channel = c1
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hdp02.doitedu.cn
a1.sinks.k1.port = 41414
a1.sinks.k1.batch-size = 100

a1.sinks.k2.channel = c1
a1.sinks.k2.type = avro
a1.sinks.k2.hostname = hdp03.doitedu.cn
a1.sinks.k2.port = 41414
a1.sinks.k2.batch-size = 100

# 定义sink组及其配套的sink处理器
a1.sinkgroups = g1
a1.sinkgroups.g1.sinks = k1 k2
a1.sinkgroups.g1.processor.type = failover
a1.sinkgroups.g1.processor.priority.k1 = 5
a1.sinkgroups.g1.processor.priority.k2 = 1
a1.sinkgroups.g1.processor.maxpenalty = 10000

1.5.2下游文件配置

a1.sources = r1
a1.channels = c1
a1.sinks = k1

a1.sources.r1.channels = c1
a1.sources.r1.type = avro
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 41414
a1.sources.r1.batchSize = 100

a1.channels.c1.type = file
a1.channels.c1.checkpointDir = /opt/data/flumedata/file-channel/checkpoint
a1.channels.c1.dataDirs = /opt/data/flumedata/file-channel/data

a1.sinks.k1.channel = c1
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = hdfs://hdp01.doitedu.cn:8020/logdata/%{datatype}/%Y-%m-%d/
a1.sinks.k1.hdfs.filePrefix = DoitEduData
a1.sinks.k1.hdfs.fileSuffix = .log
a1.sinks.k1.hdfs.rollInterval = 60
a1.sinks.k1.hdfs.rollSize = 268435456
a1.sinks.k1.hdfs.rollCount = 0
a1.sinks.k1.hdfs.batchSize = 100
a1.sinks.k1.hdfs.codeC = gzip
a1.sinks.k1.hdfs.fileType = CompressedStream
a1.sinks.k1.hdfs.useLocalTimeStamp = false

1.5.3自定义拦截器代码实现

package cn._51doit;



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;


import java.util.List;

/**
 * @date 2021-01-11
 * @desc 项目字段加密及时间戳提取拦截器
 */
public class FieldEncryptInterceptor implements Interceptor {

    String timestamp_field;
    String to_encrypt_field;
    String headerName;

    public FieldEncryptInterceptor(String timestamp_field, String to_encrypt_field, String headerName) {

        this.timestamp_field = timestamp_field;
        this.to_encrypt_field = to_encrypt_field;
        this.headerName = headerName;

    }

    public void initialize() {

    }

    public Event intercept(Event event) {

        // 根据要加密的字段,从event中提取原值(用json解析)
        try {
            String line = new String(event.getBody());
            JSONObject jsonObject = JSON.parseObject(line);

            String toEncryptField = jsonObject.getString(to_encrypt_field);
            String timeStampField = jsonObject.getString(timestamp_field);

            // 加密
            if (StringUtils.isNotBlank(toEncryptField)) {
                String encrypted = DigestUtils.md5Hex(toEncryptField);

                // 将加密后的值替换掉原值
                jsonObject.put(to_encrypt_field, encrypted);

                // 转回json,并放回event
                String res = jsonObject.toJSONString();
                event.setBody(res.getBytes("UTF-8"));
            }

            // 放入时间戳到header中
            event.getHeaders().put(headerName, timeStampField);

        } catch (Exception e) {

            event.getHeaders().put("datatype", "malformed");

            e.printStackTrace();
        }


        return event;
    }

    public List<Event> intercept(List<Event> list) {
        for (Event event : list) {
            intercept(event);
        }

        return list;
    }

    public void close() {

    }


    public static class FieldEncryptInterceptorBuilder implements Builder {
        String timestamp_field;
        String to_encrypt_field;
        String headerName;

        public Interceptor build() {

            return new FieldEncryptInterceptor(timestamp_field, to_encrypt_field, headerName);
        }

        public void configure(Context context) {
            timestamp_field = context.getString("timestamp_field");
            headerName = context.getString("headerName");
            to_encrypt_field = context.getString("to_encrypt_field");


        }
    }
}

1.6ods层app及wx埋点日志对应模型创建
1.6.1app端

-- ODS层,app埋点日志对应表模型创建
DROP TABLE IF EXISTS `ods.event_app_log`;
CREATE EXTERNAL TABLE `ods.event_app_log`(         
  `account` string ,    
  `appid` string ,      
  `appversion` string , 
  `carrier` string ,    
  `deviceid` string ,   
  `devicetype` string , 
  `eventid` string ,    
  `ip` string ,         
  `latitude` double ,   
  `longitude` double ,  
  `nettype` string ,    
  `osname` string ,     
  `osversion` string ,  
  `properties` map<string,string> ,  
  `releasechannel` string ,   
  `resolution` string ,   
  `sessionid` string ,   
  `timestamp` bigint 
)   
PARTITIONED BY (`dt` string)                                      
ROW FORMAT SERDE                                    
  'org.apache.hive.hcatalog.data.JsonSerDe'         
STORED AS INPUTFORMAT                               
  'org.apache.hadoop.mapred.TextInputFormat'        
OUTPUTFORMAT                                        
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'  
LOCATION                                            
  'hdfs://hdp01.doitedu.cn:8020/user/hive/warehouse/ods.db/event_app_log'  
TBLPROPERTIES (                                     
  'bucketing_version'='2',                          
  'transient_lastDdlTime'='1610337798'
);            

-- 数据入库
load data inpath '/logdata/app/2021-01-10' into table ods.event_app_log partition(dt='2021-01-10');

-- 如何删除一个表中已存在分区
alter table ods.event_app_log drop partition(dt='2020-01-10');

-- 不适用load,如何添加一个分区到已存在的表中
alter table ods.event_app_log add partition(dt='2020-01-11') location '/abc/ddd/'

1.6.2微信端

DROP TABLE IF EXISTS `ods.event_wx_log`;
CREATE EXTERNAL TABLE `ods.event_wx_log`(         
  `account` string , 
  `openid` string,  
  `carrier` string ,    
  `deviceid` string ,   
  `devicetype` string , 
  `eventid` string ,    
  `ip` string ,         
  `latitude` double ,   
  `longitude` double ,  
  `nettype` string ,    
  `osname` string ,     
  `osversion` string ,  
  `properties` map<string,string> ,   
  `resolution` string ,   
  `sessionid` string ,   
  `timestamp` bigint 
)   
PARTITIONED BY (`dt` string)                                      
ROW FORMAT SERDE                                    
  'org.apache.hive.hcatalog.data.JsonSerDe'         
STORED AS INPUTFORMAT                               
  'org.apache.hadoop.mapred.TextInputFormat'        
OUTPUTFORMAT                                        
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'  
LOCATION                                            
  'hdfs://linux01:8020/user/hive/warehouse/ods.db/event_wx_log'  
TBLPROPERTIES (                                     
  'bucketing_version'='2',                          
  'transient_lastDdlTime'='1610337798'
); 

1.7自定义开发shell脚本自动导数据进ods库
1.7.1app端

#!/bin/bash
######################################
#
#  @author :  杰
#  @date   :  2021-01-11
#  @desc   :  app端埋点日志入库
#  @other  
######################################

export JAVA_HOME=/opt/apps/jdk1.8.0_191/
export HIVE_HOME=/opt/apps/hive-3.1.2/


DT=$(date -d'-1 day' +%Y-%m-%d)

if [ $1 ]
then
DT=$1
fi


${HIVE_HOME}/bin/hive -e "
load data inpath '/logdata/app/${DT}' into table ods.event_app_log partition(dt='${DT}')
"

if [ $? -eq 0 ]
then
 echo "${DT}app埋点日志,入库成功"
else
 echo "入库失败"
fi

1.7.2wx端

#!/bin/bash
######################################
#
#  @author :  杰
#  @date   :  2021-01-11
#  @desc   :  wx端埋点日志入库
#  @other  
######################################

export JAVA_HOME=/opt/apps/jdk1.8.0_191/
export HIVE_HOME=/opt/apps/hive-3.1.2/


DT=$(date -d'-1 day' +%Y-%m-%d)

if [ $1 ]
then
DT=$1
fi


${HIVE_HOME}/bin/hive -e "
load data inpath '/logdata/wx/${DT}' into table ods.event_wx_log partition(dt='${DT}')
"

if [ $? -eq 0 ]
then
 echo "${DT}wx埋点日志,入库成功"
else
 echo "入库失败"
fi
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
课程简介:  本项目课程是一门极具综合性和完整性的大型项目课程;课程项目的业务背景源自各类互联网公司对海量用户浏览行为数据和业务数据分析的需求及企业数据管理、数据运营需求。 本课程项目涵盖数据采集与预处理、数据仓库体系建设、用户画像系统建设、数据治理(元数据管理、数据质量管理)、任务调度系统数据服务层建设、OLAP即席分析系统建设等大量模块,力求原汁原味重现一个完备的企业级大型数据运营系统。  拒绝demo,拒绝宏观抽象,拒绝只讲不练,本课程高度揉和理论与实战,并兼顾各层次的学员,真正从0开始,循序渐进,每一个步骤每一个环节,都会带领学员从需求分析开始,到逻辑设计,最后落实到每一行代码,所有流程都采用企业级解决方案,并手把手带领学员一一实现,拒绝复制粘贴,拒绝demo化的实现。并且会穿插大量的原创图解,来帮助学员理解复杂逻辑,掌握关键流程,熟悉核心架构。   跟随项目课程,历经接近100+小时的时间,从需求分析开始,到数据埋点采集,到预处理程序代码编写,到数仓体系搭建......逐渐展开整个项目的宏大视图,构建起整个项目的摩天大厦。  由于本课程不光讲解项目的实现,还会在实现过程中反复揉和各种技术细节,各种设计思想,各种最佳实践思维,学完本项目并勤于实践的话,学员的收获将远远超越一个项目的具体实现,更能对大型数据系统开发产生深刻体悟,对很多技术的应用将感觉豁然开朗,并带来融会贯通能力的巨大飞跃。当然,最直接的收获是,学完本课程,你将很容易就拿到大数据数仓建设或用户画像建设等岗位的OFFER课程模块: 1. 数据采集:涉及到埋点日志flume采集系统,sqoop业务数据抽取系统等; 2. 数据预处理:涉及到各类字典数据构建,复杂结构数据清洗解析,数据集成,数据修正,以及多渠道数据的用户身份标识打通:ID-MAPPING等;3. 数据仓库:涉及到hive数仓基础设施搭建,数仓分层体系设计,数仓分析主题设计,多维分析实现,ETL任务脚本开发,ETL任务调度,数据生命周期管理等;4. 数据治理:涉及数据资产查询管理,数据质量监控管理,atlas元数据管理系统,atlas数据血缘管理等;5. 用户画像系统:涉及画像标签体系设计,标签体系层级关系设计,各类标签计算实现,兴趣类标签的衰减合并,模型标签的机器学习算法应用及特征提取、模型训练等;6. OLAP即席分析平台:涉及OLAP平台的整体架构设计,技术选型,底层存储实现,Presto查询引擎搭建,数据服务接口开发等;7. 数据服务:涉及数据服务的整体设计理念,架构搭建,各类数据访问需求的restapi开发等;课程所涉及的技术: 整个项目课程中,将涉及到一个大型数据系统中所用到的几乎所有主要技术,具体来说,包含但不限于如下技术组件:l Hadoopl Hivel HBasel SparkCore /SparkSQL/ Spark GRAPHX / Spark Mllibl Sqoopl Azkabanl Flumel lasal Kafkal Zookeeperl Solrl Prestop

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值