meituan交互式系统项目浅析(1) session 模块

项目简介:

    本项目主要用于互联网电商企业中,使用Spark技术开发的大数据统计分析平台,对电商网站的各种用户行为(访问行    为、购物行为、广告点击行为等)进行复杂的分析。用统计分析出来的数据,辅助公司中的PM(产品经理)、数据分析师以及管理人员分析现有产品的情况,并根据用户行为分析结果持续改进产品的设计,以及调整公司的战略和业务。最终达到用大数据技术来帮助提升公司的业绩、营业额以及市场占有率的目标。
  项目主要采用目前大数据领域较为流行的Spark技术堆栈。采用了Spark技术生态栈中最常用的三个技术框架,Spark Core、Spark SQL和Spark Streaming,进行离线计算和实时计算业务模块的开发。实现了包括用户访问session分析、页面单跳转化率统计、热门商品离线统计、广告流量实时统计4个业务模块。

主要的功能和模块:

  用户访问session分析:该模块主要是对用户访问session进行统计分析,包括session的聚合指标计算、按时间比例随机抽取session、获取每天点击、下单和购买排名前N的品类、并获取topN品类的点击量排名前N的session。该模块可以让产品经理、数据分析师以及企业管理层形象地看到各种条件下的具体用户行为以及统计指标,从而对公司的产品设计以及业务发展战略做出调整。主要使用Spark Core实现。
  页面单跳转化率统计:该模块主要是计算关键页面之间的单步跳转转化率,涉及到页面切片算法以及页面流匹配算法。该模块可以让产品经理、数据分析师以及企业管理层看到各个关键页面之间的转化率,从而对网页布局,进行更好的优化设计。主要使用Spark Core实现。
  热门商品离线统计:该模块主要实现每天统计出各个区域的top3热门商品。然后使用Oozie进行离线统计任务的定时调度;使用Zeppelin进行数据可视化的报表展示。该模块可以让企业管理层看到公司售卖的商品的整体情况,从而对公司的商品相关的战略进行调整。主要使用Spark SQL实现。
 广告流量实时统计:该模块负责实时统计公司的广告流量,包括广告展现流量和广告点击流量。实现动态黑名单机制,以及黑名单过滤;实现滑动窗口内的各城市的广告展现流量和广告点击流量的统计;实现每个区域每个广告的点击流量实时统计;实现每个区域top3点击量的广告的统计。主要使用Spark Streaming实现。

架构图如下:
在这里插入图片描述

项目用到的算法

该项目用到的是:按照时间比例抽取session算法按照时间比例抽取session算法
正是因为各个时间段内的用户访问量的不同,那我们使用对应的数据做一个聚合统计分析,则显的不是很准确,举个例子,我们不能一个处于业务高峰期的数据流量去衡量处于业务低谷期的业务需求。
又因为我们要从全量session中抽取一部分的session,比如1000条的session,那么我不就不应该从业务量峰值中获取,也不能冲业务低谷值中获取,要想用抽取的这一部分数据去准去的衡量全量的数据,那么我们就应该每一个阶段,每一个部分都应该抽取相应比例的数据。
样本个数/容量:就是要抽取的事物的个数
样本:要抽取的事物组成的集体
总体:所有事物的整体
要从学校2000人中,抽取200个人,参加活动,要求每个方向都要有对人的学生,怎么才能做到想对公平的人员分配呢?
最简单的就是按照每个学科方向学员个数占总体的比重来进行抽取。

x就是应该抽取的人数(session数)
在这里插入图片描述

Session块的DAO层(数据访问层)

ISessionAggrStatDao接口:


import com.aura.bigdata.analysis.domain.session.SessionAggrStat;

import java.util.List;

public interface ISessionAggrStatDao {
   

    void insert(SessionAggrStat sas);
    void insertBatch(List<SessionAggrStat> list);
}

用来聚合统计用户在某一个页面上的停留时间,利用QueryRunner来实现查询
其中insert用于单条插入/更新,insertBatch用于List集合对象的插入更新。

public class SessionAggrStatDaoImpl implements ISessionAggrStatDao {
   

    private QueryRunner qr = new QueryRunner(DBCPUtils.getDataSource());
   private String sql = "INSERT INTO session_aggr_stat VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";   //向表 session_aggr_stat 中插入数据
    @Override
    public void insert(SessionAggrStat sas) {
   

        try {
                                                                               //同时抛出异常
            qr.update(sql, sas.getTask_id(), sas.getSession_count(),
                    sas.getVisit_len_1s_3s_ratio(), sas.getVisit_len_4s_6s_ratio(),
                    sas.getVisit_len_7s_9s_ratio(), sas.getVisit_len_10s_30s_ratio(),
                    sas.getVisit_len_30s_60s_ratio(), sas.getVisit_len_1m_3m_ratio(),
                    sas.getVisit_len_3m_10m_ratio(), sas.getVisit_len_10m_30m_ratio(),
                    sas.getVisit_len_30m_ratio(), sas.getStep_len_1_3_ratio(),
                    sas.getStep_len_4_6_ratio(), sas.getStep_len_7_9_ratio(),
                    sas.getStep_len_10_30_ratio(), sas.getStep_len_30_60_ratio(),
                    sas.getStep_len_60_ratio());
        } catch (SQLException e) {
   
            e.printStackTrace();
        }
    }






    @Override
    public void insertBatch(List<SessionAggrStat> list) {
             //对象的个数保存在list里面,然后对list的对象进行操作

        Object[][] params = new Object[list.size()][];
        for (int i = 0; i < list.size(); i++) {
   
            SessionAggrStat sas  = list.get(i);
            Object[] obj = {
   
                    sas.getTask_id(),sas.getSession_count(),
                    sas.getVisit_len_1s_3s_ratio(), sas.getVisit_len_4s_6s_ratio(),
                    sas.getVisit_len_7s_9s_ratio(), sas.getVisit_len_10s_30s_ratio(),
                    sas.getVisit_len_30s_60s_ratio(), sas.getVisit_len_1m_3m_ratio(),
                    sas.getVisit_len_3m_10m_ratio(), sas.getVisit_len_10m_30m_ratio(),
                    sas.getVisit_len_30m_ratio(), sas.getStep_len_1_3_ratio(),
                    sas.getStep_len_4_6_ratio(), sas.getStep_len_7_9_ratio(),
                    sas.getStep_len_10_30_ratio(), sas.getStep_len_30_60_ratio(),
                    sas.getStep_len_60_ratio()

            };
            params[i] = obj;
        }
        try {
   
            qr.batch(sql, params);
        } catch (SQLException e) {
   
            e.printStackTrace();
        }


    }
}

其结果储存到表session_aggr_stat当中

CREATE TABLE IF NOT EXISTS  `session_aggr_stat` (
  `task_id` int(11) NOT NULL,
  `session_count` int(11) DEFAULT NULL,
  `visit_len_1s_3s_ratio` double DEFAULT NULL,
  `visit_len_4s_6s_ratio` double DEFAULT NULL,
  `visit_len_7s_9s_ratio` double DEFAULT NULL,
  `visit_len_10s_30s_ratio` double DEFAULT NULL,
  `visit_len_30s_60s_ratio` double DEFAULT NULL,
  `visit_len_1m_3m_ratio` double DEFAULT NULL,
  `visit_len_3m_10m_ratio` double DEFAULT NULL,
  `visit_len_10m_30m_ratio` double DEFAULT NULL,
  `visit_len_30m_ratio` double DEFAULT NULL,
  `step_len_1_3_ratio` double DEFAULT NULL,
  `step_len_4_6_ratio` double DEFAULT NULL,
  `step_len_7_9_ratio` double DEFAULT NULL,
  `step_len_10_30_ratio` double DEFAULT NULL,
  `step_len_30_60_ratio` double DEFAULT NULL,
  `step_len_60_ratio` double DEFAULT NULL,
  PRIMARY KEY (`task_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

类似的,还有
SessionDetailDaoImpl,用于更新和插入抽取session中的各项明细。

import com.aura.bigdata.analysis.dao.session.ISessionDetailDao;
import com.aura.bigdata.analysis.domain.session.SessionDetail;
import com.aura.bigdata.analysis.util.DBCPUtils;
import org.apache.commons.dbutils.QueryRunner;

import java.sql.SQLException;
import java.util.List;

public class SessionDetailDaoImpl implements ISessionDetailDao {
   
    private QueryRunner qr = new QueryRunner(DBCPUtils.getDataSource());

    String sql = "INSERT INTO session_detail VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

    @Override
    public void insert(SessionDetail entity) {
   

        try {
   
            qr.update(sql, entity.getTaskId(), entity.getUserId(), entity.getSessionId(),
                           entity.getPageId(), entity.getActionTime(), entity.getSearchKeyword(),
                           entity.getClickCategoryId(), entity.getClickProductId(), entity.getOrderCategoryIds(),
                           entity.getOrderProductIds(), entity.getPayCategoryIds(), entity.getPayProductIds());
        } catch (SQLException e) {
   
            e.printStackTrace();
        }
    }

    @Override
    public void insertBatch(List<SessionDetail> list) {
   
        Object[][] params = new Object[list.size()][];
        for (int i = 0; i < list.size(); i++) {
   
            SessionDetail entity = list.get(i);
            Object[] obj = {
   
                    entity.getTaskId(), entity.getUserId(), entity.getSessionId(),
                    entity.getPageId(), entity.getActionTime(), entity.getSearchKeyword(),
                    entity.getClickCategoryId(), entity.getClickProductId(), entity.getOrderCategoryIds(),
                    entity.getOrderProductIds(), entity.getPayCategoryIds(), entity.getPayProductIds()
            };
            params[i] = obj;
        }
        try {
   
            qr.batch(sql, params);
        } catch</
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
mini-session是用于node.js的极简版session模块,非持久化。它的数据存储在内存里,因此,如果Web服务器进程重新启动,session将会丢失。所以,这个模块主要针对小网站,并没有太多的数据存储在session中。安装在使用 mini-session 之前, 你需要先安装 Cookies 包。npm install cookies然后npm install mini-sessionDemovar http = require("http"); var Cookies = require("Cookies"); var Session = require("mini-session"); http.createServer(function(req, res){     var cookies = new Cookies(req, res);     var session = new Session(cookies);//init session with cookies     console.log("sessionId = "   session.sessionId);     session.set("userId", 123);     session.set("userName", "Jhon");     console.log("after set, session data is :");     session.dump();     console.log("session.get(\"userId\") = "   session.get("userId"));     session.abandon();     console.log("after abandon, session data is :");     session.dump();     res.writeHead(200, {"Content-Type":"text/html"});     res.end("<h1>session test done!</h1>"); }).listen(8500); console.log("Server started : http://localhost:8500");控制台输出:Server started : http://localhost:8500 sessionId = f4e4f42b130bfb4fb663ee67122c02b8 after set, session data is : { count: 1,   f4e4f42b130bfb4fb663ee67122c02b8: { count: 2, userId: 123, userName: 'Jhon' } } session.get("userId") = 123 after abandon, session data is : { count: 0 } 标签:minisession

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值