从零构建FLINK整合Drools动态规则实时运营系统(项目案例)-第4篇(日志准备篇)

前言

项目介绍在线视频: https://www.bilibili.com/video/BV1zv41157yY

本案例是一个专注于flink动态规则计算的项目,核心技术组件涉及flink、hbase、clickhouse、drools等
项目可根据各类个性化需求进行二次开发后,直接用于实时运营,实时风控、交通监控等场景的线上生产
项目完整视频教程和资料代码等,可在易学在线 https://v.51doit.cn 获取
技术交流,可加微信: haitao-duan
在这里插入图片描述

兵马未动,粮草先行

巧妇难为无米之炊,本运营系统的开发,离不开用户行为的数据记录;
各类网站、app等互联网产品上,用户的行为记录数据,往往称作“行为日志”,或曰“埋点日志”,亦或曰“流量日志”,亦或曰“点击流日志”,皆类同矣;

日志数据埋点介绍

埋点技术,通常在前端系统进行埋点

  • 如html页面,采用js埋点
  • app端则可以用android api代码埋点
  • 微信小程序,使用微信小程序的js api代码埋点

埋点代码,主要的技术手段是对界面元素进行函数绑定,当用户浏览,点击,滑动等动作发生时,绑定函数会被触发,从而获取到用户的行为信息,并通过HTTP发给后端的日志服务器进行收集存储(日志文件);

埋点技术,在业内通常又分为特定事件埋点,全埋点(或称无埋点)方案

  • 特定事件埋点,是针对特定按钮上的特定操作行为,进行专门函数的绑定,获取到的信息有针对性,比如捕获的用户行为是一个什么事件,拥有哪些业务属性等;

  • 全埋点(无埋点),则通常是对整个界面上的所有元素进行统一函数的绑定,这样一来,用户的所有行为都将被捕获,但是获得的数据相对来说没有那么具备针对性,往往是产生,用户操作的元素类型,元素id,元素标题等通用信息;

本项目侧重数据平台开发,因此,前端埋点技术具体内容不在此展开;

日志数据字段说明

本公司的埋点日志数据,整体结构为一个嵌套json串,如下所示:

{
	"account": "Vz54E9Ya",
	"appId": "cn.doitedu.app1",
	"appVersion": "3.4",
	"carrier": "中国移动",
	"deviceId": "WEISLD0235S0934OL",
	"deviceType": "MI-6",
    "ip": "24.93.136.175",
	"latitude": 42.09287620431088,
	"longitude": 79.42106825764643,
	"netType": "WIFI",
	"osName": "android",
	"osVersion": "6.5",
	"releaseChannel": "豌豆荚",
	"resolution": "1024*768",
	"sessionId": "SE18329583458",
	"timeStamp": 1594534406220
	"eventId": "productView",
	"properties": {
		"pageId": "646",
		"productId": "157",
		"refType": "4",
		"refUrl": "805",
		"title": "爱得堡 男靴中高帮马丁靴秋冬雪地靴 H1878 复古黄 40码",
		"url": "https://item.jd.com/36506691363.html",
		"utm_campain": "4",
		"utm_loctype": "1",
		"utm_source": "10"
	}	
}

其中主要有如下内容:

  • 用户终端属性(公共属性)
  • 事件类型(eventId)
  • 事件详情(properties,map结构)

行为明细数据入kafka

  • 用模拟器生成数据写入kafka
/**
 * @author 涛哥
 * @nick_name "deep as the sea"
 * @contact qq:657270652 wx:doit_edu
 * @site www.doitedu.cn
 * @date 2021-03-25
 * @desc 压测数据模拟器
 * {
 * "account":"157","appId":"cn.do",
 * "appVersion":"3.0","carrier":"中国移动",
 * "deviceId":"157","deviceType":"mi10",
 * "eventId":"thumbUp","ip":"152.33.68.90",
 * "latitude":56.29385792,"longitude":120.329857234,
 * "netType":"wifi","osName":"android","osVersion":"9.0",
 * "properties":{"productId":"10","pageId":"10"},
 * "releaseChannel":"小米应用",
 * "resolution":"1024*2048",
 * "sessionId":"sessionid157",
 * "timeStamp":1616142957968
 * }
 *
 */
public class GenLogData {public static void main(String[] args) throws InterruptedException {
​
        Properties props = new Properties();
        props.setProperty("bootstrap.servers", "hdp01:9092,hdp02:9092,hdp03:9092");
        props.put("acks", "all");// acks=0 配置适用于实现非常高的吞吐量 , acks=all 这是最安全的模式
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
​
        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
​
        String[] events = {"pageView", "addCart", "collect", "thumbUp", "share", "search", "adShow", "adClick", "fetchCoupon", "useCoupon", "register"};for(int i=0;i<10;i++){
            new Thread(
                    new Runnable() {
                        @Override
                        public void run() {
                            while (true) {
                                LogBean bean = new LogBean();
                                // 决定人数,3个就可能有1000人
                                String account = StringUtils.leftPad(RandomStringUtils.randomNumeric(2),4,"0");
                                bean.setAccount(account);
​
                                String eventId = events[RandomUtils.nextInt(0, events.length)];
                                bean.setEventId(eventId);
                                bean.setTimeStamp(System.currentTimeMillis());
                                bean.setAppId("cn.do");
                                bean.setAppVersion("3.0");
                                bean.setCarrier("中国移动");
                                bean.setDeviceId(account);
                                bean.setDeviceType("mi10");
                                bean.setIp("152.33.68.90");
                                bean.setLatitude(56.29385792);
                                bean.setLongitude(120.329857234);
                                bean.setSessionId("sessionid" + account);
                                bean.setResolution("1024*2048");
                                bean.setReleaseChannel("小米应用");
                                bean.setNetType("wifi");
                                bean.setOsName("android");
                                bean.setOsVersion("9.0");
​
                                HashMap<String, String> properties = new HashMap<>();
                                // 页面数量可能达到10种
                                properties.put("pageId", RandomUtils.nextInt(1, 11) + "");
                                if (eventId.equals("addCart") || eventId.equals("collect") 
                                      || eventId.equals("share") || eventId.equals("thumbUp")) {
                                    properties.put("productId", RandomUtils.nextInt(1, 11) + "");
                                }
                                if (eventId.equals("fetchCoupon") || eventId.equals("useCoupon")) {
                                    properties.put("couponId", RandomUtils.nextInt(1, 11) + "");
                                }
                                if (eventId.equals("adShow") || eventId.equals("adClick")) {
                                    properties.put("adId", RandomUtils.nextInt(1, 11) + "");
                                }if (eventId.equals("search")) {
                                    properties.put("keyword", RandomStringUtils.randomNumeric(1));
                                }
​
                                bean.setProperties(properties);
​
                                producer.send(new ProducerRecord<String, String>("app_log", JSON.toJSONString(bean)));try {
                                    // 20ms相当于每秒2k条,相当于2w人同时在线
                                    // 当前配置情况下,完全hold住没有任何反压延迟
                                    // 内存占用约6G(原因,缓存没有清除机制,内存一直在增长)
                                    Thread.sleep(RandomUtils.nextInt(1000,4000));
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }}
                        }
                    }
            ).start();
        }
    }
}
<think>嗯,用户问的是大数据中的用户画像如何实现。这个问题看起来挺常见的,不过用户可能有具体的需求,比如他们可能在做一个电商项目,或者想优化广告投放,需要了解用户画像的具体步骤和技术。首先,我得回忆一下用户画像的基本概念,然后拆解实现的流程。 用户画像,其实就是通过收集用户的各种数据,然后分析整理,最终形成标签化的用户模型。大数据环境下,这个过程需要处理海量数据,所以可能需要用到分布式存储和计算框架,比如Hadoop、Spark之类的。 用户可能已经知道一些基本概念,但需要具体的步骤和技术细节。比如数据采集、数据处理、标签构建、存储和更新,以及应用场景。需要分步骤解释,每个步骤可能用到哪些技术,比如数据采集阶段需要埋点、日志收集工具,或者第三方数据接入。 然后,数据处理部分可能需要ETL工具,数据清洗、去重、归一化等。标签构建是关键,可能需要机器学习模型,比如聚类、分类算法,或者规则引擎来打标签。这里可能需要举一些例子,比如用户性别、年龄、购买偏好等标签是怎么生成的。 存储方面,可能需要用到HBase、Hive、或者图数据库,根据查询需求不同选择不同的存储方案。实时更新的话,可能需要用到流处理技术,比如Flink或者Kafka Streams。 应用场景部分,用户可能想知道画像具体怎么用,比如个性化推荐、精准营销、风险控制等。这部分需要结合实际案例说明,让用户更容易理解。 还要考虑用户可能的疑问,比如数据隐私问题,如何处理敏感信息,或者如何保证标签的准确性。可能需要在回答中提到数据脱敏、权限控制,以及模型评估的方法。 另外,用户可能对实时画像和离线画像的区别不太清楚,需要解释批处理和流处理的区别,以及各自适用的场景。比如实时画像用于即时推荐,离线画像用于长期行为分析。 最后,总结一下实现用户画像的关键技术和挑战,帮助用户全面了解整个流程。可能需要提到数据质量、计算资源、算法选择等方面的注意事项。</think>### **大数据中的用户画像实现详解** 用户画像是通过收集、分析用户行为与属性数据,构建标签化用户模型的过程,广泛应用于精准营销、个性化推荐、风控等领域。其核心实现流程可分为 **数据采集 → 数据建模 → 标签构建 → 画像应用** 四个阶段,以下从技术角度分步骤解析: --- #### **一、数据采集:多源数据整合** 用户画像依赖 **全维度数据**,需整合以下数据源: 1. **基础属性数据** - 来源:用户注册信息(性别、年龄、地域)、设备信息(手机型号、操作系统- 存储:结构化数据库(MySQL、HBase) 2. **行为数据** - **埋点采集**:通过 SDK(如 Sensors Analytics)记录用户点击、浏览、购买等事件 - 示例:`用户A 在 2023-10-01 10:00 浏览商品页ID=123,停留时长120秒` - **日志数据**:服务器日志(Nginx)、应用日志(ELK 采集) - 存储:Kafka(实时流)、HDFS(离线批处理) 3. **业务数据** - 交易记录(订单金额、支付方式)、会员等级、优惠券使用情况 - 存储:数据仓库(Hive、ClickHouse4. **第三方数据** - 社交数据(微博/微信授权)、地理位置(GPS)、广告投放反馈数据 - 工具:API 接口(如微信开放平台)、数据清洗工具(Apache NiFi) --- #### **二、数据建模:构建统一用户标识** **核心挑战**:跨渠道、跨设备用户身份打通 1. **用户标识体系** - **强标识**:手机号、身份证号(需脱敏处理) - **弱标识**:设备ID(IMEI、Cookie)、第三方账号(微信OpenID) - **解决方案**: - 基于 **ID-Mapping 技术**(如图数据库 Neo4j)建立关联关系 - 使用 **概率模型**(如联合熵算法)推断同一用户的设备关联性 2. **数据清洗与归一化** - 去重:利用 Spark 的 `dropDuplicates()` 处理重复日志 - 缺失值填充:规则补全(如根据 IP 推断地域)或模型预测 - 标准化:将不同数据源的字段统一(如时间戳转为 UTC 格式) --- #### **三、标签构建:从原始数据到用户标签** 标签体系分为 **统计类、规则类、模型类** 三类: 1. **统计类标签(直接计算)** - 示例:近30天购买次数、累计消费金额 - 技术实现: - 离线计算:Hive SQL(`COUNT`, `SUM` 聚合) - 实时计算:Flink 窗口函数(滚动窗口统计) 2. **规则类标签(人工定义逻辑)** - 示例: - 高价值用户:`近一年消费金额 > 10万元 AND 活跃天数 > 50天` - 流失风险:`最近30天未登录 AND 历史订单数 ≥ 3` - 工具: - Drools 规则引擎 - SQL 条件筛选(`CASE WHEN` 语句) 3. **模型类标签(机器学习预测)** - 示例: - 兴趣偏好:基于协同过滤(ALS算法)的商品偏好预测 - 信用评分:使用 XGBoost 预测还款概率 - 流程: - **特征工程**:提取用户行为序列(如点击序列 Embedding) - **模型训练**:Spark MLlib/TensorFlow 构建分类/聚类模型 - **标签输出**:将预测结果映射为标签(如 `母婴品类偏好度=0.92`) 4. **标签存储方案** | **存储类型** | **适用场景** | **技术选型** | |-------------------|---------------------------|-------------------------| | 宽表存储 | 简单标签查询(用户维度) | HBase(RowKey=UserID) | | 图数据库 | 复杂关系挖掘(社交网络) | Neo4j、JanusGraph | | 搜索引擎 | 标签组合筛选(多条件查询) | Elasticsearch(倒排索引)| --- #### **四、画像应用:驱动业务决策** 1. **个性化推荐** - 示例:根据用户“价格敏感度”标签展示不同折扣商品 - 技术链路: ``` 用户请求 → 实时读取画像标签(Redis) → 召回算法(Faiss向量检索) → 排序模型(TensorFlow Serving) ``` 2. **精准营销** - 示例:筛选“孕妇群体”推送母婴产品广告 - 工具: - SQL 圈选:`SELECT user_id FROM tags WHERE 怀孕状态=1 AND 地域='北京'` - 可视化平台:Superset/Redash 创建用户分群 3. **风险控制** - 示例:识别“羊毛党”(同一设备频繁注册新账号) - 实时风控: - Flink CEP 检测异常模式(如1小时内注册5次) - 结合画像标签(设备指纹、IP归属地)动态拦截 --- ### **技术架构示例(Lambda 架构)** ``` [数据层] ├─ 批量数据:HDFS → Hive(离线标签计算) ├─ 流数据:Kafka → Flink实时标签更新) [计算层] ├─ 离线任务:Airflow 调度 Spark 作业 ├─ 实时任务:Flink 状态计算 [存储层] ├─ 标签库:HBase(主存储) + Elasticsearch(检索) ├─ 特征库:Redis(实时访问) + Cassandra(宽表) [应用层] ├─ API 服务:Spring Boot 提供标签查询接口 ├─ 可视化:Grafana 监控标签覆盖率与准确性 ``` --- ### **关键挑战与优化方向** 1. **数据质量** - 问题:埋点丢失、日志格式错误 - 方案: - 埋点自动化测试(如 Mock 数据验证) - 实时监控告警(Prometheus + Grafana) 2. **实时性要求** - 问题:小时级延迟无法满足实时推荐需求 - 方案: - 流批一体(Apache Iceberg + Flink- 增量计算(仅处理新增数据) 3. **隐私合规** - 问题:用户敏感信息(如位置)泄露风险 - 方案: - 数据脱敏(MD5 哈希处理手机号) - GDPR/CCPA 合规审计(Apache Atlas 元数据管理) --- ### **总结** 用户画像的构建是 **数据+算法+工程** 的综合实践: - **数据是基础**:需覆盖全链路用户触点,建立高质量数据管道 - **标签是核心**:通过统计、规则、模型结合,实现精准描述 - **应用是价值**:与业务场景深度结合,驱动增长与效率提升 实际落地中,建议从小规模标签体系起步(如优先构建“用户生命周期阶段”标签),逐步迭代优化,避免过度工程化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值