百亿级日志流分析实践 | 剖析个推后效分析功能实现原理

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: “码”上注册和登录个推开发者中心(https://dev.getui.com/),体验个推后效分析功能和最新推出的消息链路查询功能吧!

消息推送作为用户促活的有效利器,具有低成本、高效率的明显优势,已成为App运营中最重要的用户触达方式之一。为帮助开发者有策略地提升消息推送的效果,增加消息的到达率和点击率,个推消息推送SDK于今年初重磅上线了后效分析功能,旨在为开发者和运营人员科学调整推送策略提供有效支撑。

 

后效分析功能上线后,我们结合产品目标和用户建议,进行了多次迭代。本文就开发和迭代过程中沉淀的经验与大家做分享,也欢迎感兴趣的开发者们通过企业微信和我们交流。

 

2.png

 

后效分析功能的开发背景

 

消息推送过程中,从服务端推送消息、消息到达客户端,到用户点击推送、打开应用的各阶段,都可能存在消息折损的情况。

 

以往,消息系统通过简单对比下发、到达、展示、点击等四个维度的数据,来计算消息的折损程度。但这样的消息折损计算方式不够准确,运营人员较难深入了解消息的折损原因,也就无法对推送参数、推送设置做出科学有效的改进。此外,以往客户遇到消息推送的问题时,会直接与技术支持人员联系解决,沟通和时间成本较高

 

因此,我们需要设计出一种自动化方式,来帮助开发者清晰了解推送消息的各项后效数据,并能够自主、高效地找出消息折损的原因。

 

后效分析功能的开发思路

 

我们的解决思路是:

 

1.推出后效数据报表功能。通过将消息在服务端下发过程中的折损情况以及客户端回执数据进行梳理、统计,形成各环节后效数据的清晰报表,以帮助开发者和运营人员透过数据表象,快速定位出消息折损原因,找到提升推送效果的关键环节。

 

2.自动采集各推送模块日志并形成后效分析报告。通过不同模块获取推送日志:以类似人工查询日志的方式,将一些含有原因标识的日志进行统一存储和梳理,从而梳理出某条任务下发时产生的所有异常和折损原因。这其中就包含“目标正处于黑名单”“请求受到频控(或流控)限制”等原因。与人工技术支持相比,这样不仅能提高后效分析的效率,还能从一些以往可能被忽略的折损中自动提炼出问题,帮助用户自检并规避一些使用不当的情况。

 

 

后效分析功能的开发难点

 

在开发后效分析功能的过程中,我们也遇到了如下一些技术上的难点:

 

难点一:日志的聚合归类和后效原因提炼

 

在通过日志进行消息折损原因排查和分析的过程中,我们首先需要从海量日志数据中筛选出有效的部分,并对该部分日志数据进行归纳,根据我们预先设置的日志解析策略,对全链路的日志数据打上对应标记,以帮助我们分析消息在各阶段的折损原因。

 

为此,我们对消息推送的整个链路做了一次大梳理,从推送阶段入手,将推送模块区分为入口层、处理层、下发层、客户端等四层,然后对各层可能存在的消息折损原因进行了提炼:

 

1.png

 

在入口层,我们主要关注服务端收到的请求内容是否通过格式校验,以及各类目标参数是否设置无误,比如“CID是否有效”“鉴权信息是否异常”等。

 

在处理层,我们关注目标客户端是否符合下发条件,例如可能因为推送策略限制,导致服务端无法给部分客户端进行后续推送。

 

在下发层,我们关注客户端与服务端的网络连接是否正常,比如,在线通道是否有效等。

 

✦最终在客户端收到推送、用户点击消息时,客户端也会将回执汇报到服务端模块。这一阶段的消息折损原因可能是“通知开关没有打开”等。

 

基于以上业务层次区分,我们可以更清晰地看到消息推送的整体业务流程。我们将各阶段可能存在的异常关注点提炼出来,以便于我们梳理相对应的日志模块。最终我们将后效异常原因总结为12类,分别对应消息推送各阶段中可能遇到的折损情况。

 

3.png

 

难点二:TB级别日志数据的处理和准确计算

 

基于上述各场景,我们筛选出相关日志,通过前期的标记来提炼消息折损原因。

 

在一条消息的下发过程中,服务端会产生大量日志,单个功能节点一天的日志量就能达到TB级别。如何对亿级别的日志进行过滤和计算,成为我们进行后效数据分析的第一个难题。

 4.png


我们通过Flume传输日志,将日志数据写入到HDFS,采用Spark作为计算引擎,HDFS存储原始日志数据和维度数据,最后的报表数据存放在ElasticSearch、Hbase和Mysql中。

 

 海量日志数据的清洗和计算

 

根据对推送业务特性的了解,我们总结出推送日志数据可能存在的问题如下:

 

日志重复。例如,用户不断地登录和登出服务,从而产生大量的重复日志。

 

请求重复。例如,用户多次发起相同请求,对某个客户端发送同一条消息。客户端最终只会收到一次消息并展示,但服务器会产生多条重复的客户端/消息关联日志。

 

回执重复。下游回执中,由于客户端的网络环境复杂,有时会出现重复回执的情况,从而导致服务器重复打印回执日志。

 

日志不足。比如,一般情况下,关闭通知、设备活跃等客户端信息,在推送流程中不会有日志产生,这就必须依赖相关数据作为补充,才能综合评估出客户端的状态信息。

 

针对以上问题,我们提出的解决办法是“人群打标”我们按照推送流程对日志数据进行划分,将推送任务影响到的人群分为到达人群、下发人群、请求人群等三类。我们根据消息与客户端的关联情况,对客户端进行打标。例如当采集到“在线下发模块”日志时,如果其中包含某消息与客户端的关联信息,那么我们就会给该推送任务下的客户端打上成功下发标记。每个标记只有0或1,不同日志不会重复打标,如此就避免了日志重复统计的情况。

 

5.png

 

结合上述人群打标逻辑,我们将四个维度的打标数据汇总,最终得到单个推送任务的原始数据。这份数据内,一个客户端会有多个标记,我们只需要按过滤逻辑将这些标记整理并归纳出最终状态,就可区分该条消息对这个客户端的下发流程最终到了哪一阶段,或是在哪一阶段因何种原因折损。

 

6.png

 

 解决数据倾斜问题

 

在日志数据的计算过程中,我们还遇到了数据倾斜的问题。

 

我们按照消息下发阶段将整个日志计算任务拆分成四个。根据推送漏斗,这四个任务之间存在上下游关系。在对指标维度进行聚合的时候,会出现维度聚合体量差异过大导致数据倾斜的情况,甚至因为个别任务计算时间过久拖慢整体的计算进度。

 

为了解决该问题,我们需要在计算前和计算时对Spark任务进行处理,以减少数据倾斜。

 

我们采取的处理方式有:1.将大文件分割成小文件,或将小文件合并成大文件,以此保证每个任务处理的日志数据量均匀;2.优化分区策略,防止某个较大推送请求下的所有数据全部汇聚到同一节点,使节点计算压力更均衡;3.优化任务的计算链路,保证以最优的计算链路完成数据处理。

 

至此,基于如上所述的日志数据处理和计算逻辑,我们就可以在HBase中存储每条任务的后效数据,从而供业务层查询、调用。

 

 

总结

近期,我们还引入了Flink流式计算引擎来提升后效数据计算的实时性;我们也结合了更多的消息细则日志进一步完善数据,将后效数据报表升级,推出了消息链路查询功能,借此来帮助开发者更好地了解推送消息下发情况,并根据对应建议来快速提升消息的整体到达率。

 

“码”上注册和登录个推开发者中心(https://dev.getui.com/),体验个推后效分析功能和最新推出的消息链路查询功能吧!

 

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
Rust 前端开发 JavaScript
Tauri 开发实践 — Tauri 日志记录功能开发
本文介绍了如何为 Tauri 应用配置日志记录。Tauri 是一个利用 Web 技术构建桌面应用的框架。文章详细说明了如何在 Rust 和 JavaScript 代码中设置和集成日志记录,并控制日志输出。通过添加 `log` crate 和 Tauri 日志插件,可以轻松实现多平台日志记录,包括控制台输出、Webview 控制台和日志文件。文章还展示了如何调整日志级别以优化输出内容。配置完成后,日志记录功能将显著提升开发体验和程序稳定性。
65 1
Tauri 开发实践 — Tauri 日志记录功能开发
|
10天前
|
存储 SQL 监控
|
10天前
|
运维 监控 安全
|
30天前
|
SQL 存储 关系型数据库
美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
老架构师尼恩在其读者交流群中分享了关于 MySQL 中 redo log、undo log 和 binlog 的面试题及其答案。这些问题涵盖了事务的 ACID 特性、日志的一致性问题、SQL 语句的执行流程等。尼恩详细解释了这些日志的作用、所在架构层级、日志形式、缓存机制以及写文件方式等内容。他还提供了多个面试题的详细解答,帮助读者系统化地掌握这些知识点,提升面试表现。此外,尼恩还推荐了《尼恩Java面试宝典PDF》和其他技术圣经系列PDF,帮助读者进一步巩固知识,实现“offer自由”。
美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
|
13天前
|
监控 关系型数据库 MySQL
分析慢查询日志
【10月更文挑战第29天】分析慢查询日志
32 3
|
13天前
|
监控 关系型数据库 数据库
怎样分析慢查询日志?
【10月更文挑战第29天】怎样分析慢查询日志?
31 2
|
1月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1623 14
|
1月前
|
存储 消息中间件 大数据
大数据-69 Kafka 高级特性 物理存储 实机查看分析 日志存储一篇详解
大数据-69 Kafka 高级特性 物理存储 实机查看分析 日志存储一篇详解
35 4
|
11天前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
115 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
1月前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
216 3