《阿里大数据之路》读书笔记:第二章 日志采集

  可回答:1)Kafka高吞吐的原因;2)Kafka如何保证高吞吐量;3)Kafka为什么低延迟高吞吐?有哪些特点?4)Kafka为什么高可用、高吞吐?如何保证高可用?5)Kafka高性能的实现机制?6)Kafka高性能的原因?7)Kafka零拷贝的实现原理。8)Kafka的数据存储在磁盘但是为什么速度依旧很快?9)Kafka为什么那么快;10)Kafka如何高效读写数据;11)Kafka读也很快,怎么实现的;12)什么是零拷贝,什么是顺序读写,为什么比随机读写快;13)Kafka的数据存储在磁盘但是为什么速度依旧很快?

  参考答案:

  Kafka 是分布式消息系统,需要处理海量的消息,Kafka 的设计是把所有的消息都写入速度低容量大的硬盘,以此来换取更强的存储能力,但实际上,使用硬盘并没有带来过多的性能损失。

  kafka 主要使用了以下几个方式实现了超高的吞吐率

  1)顺序读写

  kafka 的消息是不断追加到文件中的,这个特性使 kafka 可以充分利用磁盘的顺序读写性能,顺序读写不需要硬盘磁头的寻道时间,只需很少的扇区旋转时间,所以速度远快于随机读写。

  Kafka 官方给出了测试数据(Raid-5,7200rpm):

  顺序 I/O:600MB/s随机 I/O:100KB/s2)零拷贝

  先简单了解下文件系统的操作流程,例如一个程序要把文件内容发送到网络。

  这个程序是工作在用户空间,文件和网络socket属于硬件资源,两者之间有一个内核空间。

  在操作系统内部,整个过程为:

  在Linux kernel2.2之后出现了一种叫做"零拷贝(zero-copy)"系统调用机制,就是跳过“用户缓冲区”的拷贝,建立一个磁盘空间和内存的直接映射,数据不再复制到“用户态缓冲区”。

  系统上下文切换减少为2次,可以提升一倍的性能

  3)文件分段

  kafka 的队列topic被分为了多个区partition,每个partition又分为多个段segment,所以一个队列中的消息实际上是保存在N多个片段文件中。

  通过分段的方式,每次文件操作都是对一个小文件的操作,非常轻便,同时也增加了并行处理能力。

  4)批量发送

  Kafka 允许进行批量发送消息,先将消息缓存在内存中,然后一次请求批量发送出去,比如可以指定缓存的消息达到某个量的时候就发出去,或者缓存了固定的时间后就发送出去,如100条消息就发送,或者每5秒发送一次,这种策略将大大减少服务端的I/O次数。

  5)数据压缩

  Kafka 还支持对消息集合进行压缩,Producer可以通过GZIP或Snappy格式对消息集合进行压缩,压缩的好处就是减少传输的数据量,减轻对网络传输的压力,Producer压缩之后,在Consumer需进行解压,虽然增加了CPU的工作,但在对大数据处理上,瓶颈在网络上而不是CPU,所以这个成本很值得。

  参考答案:

  一个 Kafka 的 Message 由一个固定长度的 header 和一个变长的消息体 body 组成,header 部分由一个字节的 magic(文件格式)和四个字节的 crc32(用于判断 body 消息体是否正常)构成。当 magic 的值为 1 的时候,会在 magic 和 crc32 之间多一个字节的数据:attributes(保存一些相关属性,比如是否压缩、压缩格式等等);如果 magic 的值为 0,那么不存在 attributes 属性。

  body 是由 N 个字节构成的一个消息体,包含了具体的 key/value 消息。

  具体字段解释如下:

  CRC32:4个字节,消息的校验码。magic:1字节,魔数标识,与消息格式有关,取值为0或1。当magic为0时,消息的offset使用绝对offset且消息格式中没有timestamp部分;当magic为1时,消息的offset使用相对offset且消息格式中存在timestamp部分。所以,magic值不同,消息的长度是不同的。attributes: 1字节,消息的属性。其中第0~ 2位的组合表示消息使用的压缩类型,0表示无压缩,1表示gzip压缩,2表示snappy压缩,3表示lz4压缩。第3位表示时间戳类型,0表示创建时间,1表示追加时间。timestamp: 时间戳,其含义由attributes的第3位确定。key length:消息key的长度。key:消息的key。value length:消息的value长度。value:消息的内容

  浏览器的页面型产品/服务的日志采集可分为两大类:

  页面浏览(展现)日志采集指一个页面被浏览器加载呈现时采集的日志此类日志是最基础的互联网日志此类日志是目前所有互联网产品的两大基本指标(页面浏览量(Page View,PV)和访客数(Unique Visitors,UV))的统计基础页面交互日志采集用户操作记录主要是为了对指标网页浏览量(PV)和访客数(UV)进行分析。

  采集页面被浏览器加载展现的记录,这是最原始的互联网日志采集需求,也是一切互联网数据分析得以展开的基 础和前提。

  一次典型的页面访问(请求-响应)过程:

  以用户访问淘宝首页为例

  用户在在地址栏中输入网址并回车浏览器向服务器发起HTTP请求服务器接收并解析请求浏览器接收到服务器的响应内容,并将其按照文档规范展现给用户,从而完成一次请求在上述网页浏览过程中,如果我们需要记录这次浏览行为,日志采集则是在这四个步骤中的某一环节。

  第一二步中,用户的请求尚未抵达服务器。直到第三步完成,我们也只能认为服务器处理了请求,不能保证浏览器能够正确地解析和渲染页面,不能确保用户已确实打开页面,因此在前三步是无法采集用户的浏览日志的。所以,采集日志的动作是发生在第四步,也就是浏览器开始解析文档时才能进行。

  日志采集思路:

  在HTML文档内的适当位置增加一个日志采集节点,当浏览器解析到这个节点时,将自动触发一个特定HTTP请求到日志采集服务器。当日志采集服务器接收到这个请求时,就可以确定浏览器已经成功地接收和打开了页面。页面浏览日志采集的主要过程如下:

  采集:客户端日志采集。HTML文档内植入JavaScript脚本进行采集。

  采集脚本被浏览器加载解析后执行,在执行时采集当前页面参数、浏览行为的上下文信息(如读取用户访问当前页面时的上一步页面)以及一些运行环境信息(如当前的浏览器和分辨率等)HTML文档内植入日志采集脚本的动作可以由业务服务器在响应业务请求时动态执行,也可以在开发页面时由开发人员手动植入。发送:客户端日志发送。日志采集完成后会立即发送或延迟发送。采集到的日志信息一般以URL参数形式放在HTTP日志请求的请求行内。

  采集脚本执行时,会向日志服务器发起日志请求,以将采集到的数据发送到日志服务器。收集:服务器端日志收集。由日志服务器完成对日志的收集。

  日志服务器接收到客户端请求后,会立即向浏览器发回一个请求成功的相应。日志收集模块会将日志请求内容写入一个日志缓冲区内,完成此条浏览日志的收集。存档:服务器端日志解析存档。日志服务器对浏览日志解析并存档。

  对用户在访问某个页面时具体的互动行为特征(交互日志)的采集,比如鼠标或输入焦点的移动变化(代表用户关注内容的变化)、对某些页面交互的反应(可借此判断用户是否对某些页面元素发生认知困难)等。常规的PV日志采集方法无法完成对上述操作日志的采集,因为这些行为往往并不触发浏览器加载新页面。

  交互日志的采集是以技术服务的形式呈现的。

  采集的交互日志发送到日志服务器需经过以下步骤:

  注册业务等的具体交互采集点,注册完成后,系统将生成与之对应的交互日志来集代码模板业务方将交互日志采集代码植入目标页面,并将采集代码与需监测的交互行为做绑定当用户在页面上产生指定行为时,采集代码和正常的业务互动代码起被触发和执行采集代码在采集动作完成后将对应的日志通过HTTP协议发送到日志服务器,日志服务对数据进行转储在大部分场合下,经过上述解析处理之后的日志并不直接提供给下游使用。一般还需要进行相应的离线预处理。具体操作如下:

  识别流量攻击、网络爬虫和流量作弊(虚假流量)对所采集的日志进行合法性校验,依托算法识别非正常的流量并归纳出对应的过滤规则集加以滤除。数据缺项补正对日志中的一些公用且重要的数据项做取值归 、标准化处理或反向补正(即根据新日志对稍早收集的日志中的个别数据项做回补或修订(例如,在用户登录后,对登录前页面日志做身份信息的回补))。无效数据剔除剔除无意义、已经失效或者冗余的数据项。日志隔离分发考虑到安全性,某些日志在进入公共数据环境之前需要做隔离。采集思路:无线客户端的日志采集采用采集SDK来完成。

  移动端的数据采集目的:

  服务于开发者,协助开发者分析各类设备信息帮助开发者了解用户、用户行为,不断对APP进行优化,提升用户体验与浏览器日志采集的不同之处:移动端的日志采集根据不同的用户行为分成不同的事件,“事件”为无线客户端日志行为的最小单位。

  区分不同事件的日志触发时机、日志内容和实现方式的差异更好地完成数据分析在阿里巴巴内部,多使用名为UserTrack(UT)来进行无线客户端的日志采集。基于常规的分析, UserTrack(UT)把事件分成了几类,常用的包括页面事件(同前述的页面浏览)和控件点击事件(同前述的页面交互)等。

  每条页面事件日志记录三类信息:

  设备及用户的基本信息。被访问页面的信息。主要是一些业务参数(如商品详情页的商品 ID 、所属的店铺等)访问基本路径。如页面来源、来源的来源,用于还原用户完整的访问行为。对于页面事件,UT提供了页面事件的无痕埋点, 即无须开发者进行任何编码即可实现。

  UT提供了两个接口,分别在页面展现和页面退出时调用。除此之外,还有页面扩展信息的接口,该接口必须在使用页面展现和页面退出方法的前提下使用。

  UT还提供了透传参数功能。所谓透传参数,即把当前页面的某些信息,传递到下一个页面甚至下下一个页面的日志中。

  1、控件点击事件

  记录了基本的设备信息、用户信息。

  记录了控件所在页面名称、控件名称、控件的业务参数等。

  控件点击事件的逻辑比页面事件要简单得多,就是操作页面上的某个控件,因此只需把相关基础信息告诉采集 即可。

  2、其他事件

  用户可以根据业务场景需求,使用自定义事件来采集相关信息。

  UT 提供了一个自定义埋点类,其包括:

  事件名称事件时长事件所携带的属性事件对应的页面为了平衡日志大小,减小流量消耗、采集服务器压力、网络传输压力等,采集 SDK 提供了聚合功能,对某些场景如曝光或一些性能技术类日志 ,我们提倡在客户端对这类日志进行适当聚合,以减少对日志采集服务器端的请求 ,适当减小日志大小。

  总体思路就是每个曝光的元素一般都属于一个页面,利用页面的生命周期来实现适当的聚合及确定发送时机。

  APP 分为两种:

  纯Native APP既有Native,又有H5页面嵌入的APP ,即Hybrid APPNative页面采用采集SDK进行日志采集,H5页面一般采用基于浏览器的页面日志采集方式进行采集。

  考虑到后续日志数据处理的便捷性、计算成本、数据的合理性及准确性,需要对Native H5日志进行统一处理。

  阿里选择Native部署采集SDK的方式,将H5日志归到Native日志。原因如下:

  SDK可以采集到更多的设备相关数据,这在移动端的数据分析中尤为重要采集SDK处理日志,会先在本地缓存,而后借机上传,在网络状况不佳时延迟上报,保证数据不丢失互联网产品的两大基本指标:页面浏览量(Page View,PV)和访客数(Unique Visitors,UV)。

  关于UV,对于登录用户,可以使用用户ID来进行唯一标识。PC一般使用Cookie信息来作为设备的唯一信息。对于APP来说,则需要选的设备唯一信息,不同版本的系统选择的标识不一样。

  无线客户端日志上传、压缩及传输。

  此时日志不是产生一条就上传一条,而是日志产生后,先存储在客户端本地,然后再伺机上传。

  伺机:需要有数据分析的支持,如在启动后、使用过程中、切换到后台时这些场景下分别多久触发一次上传动作。

  日志切分维度为天,当天接收的日志存储到当天的日志文件中。为了后续数据处理,以及特殊时期不同日志的保障级别,还根据应用及事件类型对每日高达数千亿的日志进行了分流。日志采集完成后,日志采集服务器的日志怎么给到下游呢?

  阿里主要使用消息队里(TimeTunel,TT)来实现从日志采集服务器到数据计算的MaxCompute。

  TT将消息收集功能部署到日志采集服务器上进行消息的收集,便于后续计算。

  实时计算:应用实时来订阅TT收集到的消息,进行实时计算。离线计算:离线的应用定时来获取消息,完成离线计算。各类采集方案提供者所面临的主要挑战已不是日志采集技术本身,而是如何实现日志数据的结构化和规范化组织,实现更为高效的下游统计计算,提供符合业务特性的数据展现,以及为算法提供更便捷、灵活的支持等方面。

  1、日志分流及定制处理

  大型互联网网站的日志类型和日志规模都呈现出高速增长的态势,而且往往会出现短时间的流量热点爆发。这一特点使得在日志服务器端采用集中统一的解析处理方案变得不可能,其要求在日志解析和处理过程中必须考虑业务分流(相互之间不应存在明显的影响,爆发热点不应干扰定常业务日志的处理)、日志优先级控制,以及根据业务特点实现定制处理。

  为了避免资源浪费(尽可能多地进行预处理)和需求覆盖不全(仅对最重要的内容进行预处理)两者取舍问题。阿里互联网日志采集体系的基本原则是分治策略。将分类任务前置到客户端,尽可能靠前地布置路由差异,就可以尽可能早地进行分流,降低日志处理过程中的分支判断消耗,并作为后续的计算资源调配的前提,提高资源利用效率。

  阿里的客户端日志采集代码的一个突出特点是实现了非常高的更新频次(业界大多以季度乃至年为单位更新代码,阿里则是以周/月为单位),并实现了更新的配置 。

  2、采集与计算一体化设计

  以PV日志为例,归类与汇总是页面PV日志采集之后的一个基础性操作。

  早期时,是以URL路径,继而以URL(正则)规则集为依托来进行日志分类的。网站规模小时,这种方式没问题,但是当网站规模大了,这种方式就不现实了,失控的大规模正则适配甚至会将日志计算硬件集群彻底榨干。

  阿里对采集与计算进行一体化设计,给出了两套日志规范和与之对应的元数据中心。

  PV日志的解决方案是目前用户可直观感知的SPM规范(例如,在页面的URL内可以看见spm参数)和SPM元数据中心。通过SPM的注册和简单部署(仅需要在页面文件内声明一个或多个标签),用户即可将任意的页面流量进行聚类,不需要进行任 多余的配置。自定义日志的解决方案则是黄金令箭(Goldlog)/APP端的点击或其他日志规范及其配置中心。通过注册一个与所在页面完全独立的令箭实体/控件实体,用户可以一键获得对应的埋点代码,并自动获得实时统计数据和与之对应的可视化视图。日志本身不是日志采集的目的,服务于基于日志的后续应用,才是日志采集正确的着眼点。

  这里以阿里“双11"为例。

  数据处理全链路如下图:

  端上实现服务器端推送配置到客户端,且做到高到达率;对日志进行分流;在实时处理方面,不断优化以提高应用的吞吐量;实时处理方面,评估峰值数据量,在高峰期通过服务器端推送配置的方式对非重要日志进行适当限流 ,错峰后逐步恢复。

  面试题来源:

  《大数据面试题 V4.0》大数据面试题V3.0,523道题,679页,46w字可回答:1)Kafka高吞吐的原因;2)Kafka如何保证高吞吐量;3)Kafka为什么低延迟高吞吐?有哪些特点?4)Kafka为什么高可用、高吞吐?如何保证高可用?5)Kafka高性能的实现机制?6)Kafka高性能的原因?7)Kafka零拷贝的实现原理。8)Kafka的数据存储在磁盘但是为什么速度依旧很快?9)Kafka为什么那么快;10)Kafka如何高效读写数据;11)Kafka读也很快,怎么实现的;12)什么是零拷贝,什么是顺序读写,为什么比随机读写快;13)Kafka的数据存储在磁盘但是为什么速度依旧很快?

  参考答案:

  Kafka 是分布式消息系统,需要处理海量的消息,Kafka 的设计是把所有的消息都写入速度低容量大的硬盘,以此来换取更强的存储能力,但实际上,使用硬盘并没有带来过多的性能损失。

  kafka 主要使用了以下几个方式实现了超高的吞吐率

  1)顺序读写

  kafka 的消息是不断追加到文件中的,这个特性使 kafka 可以充分利用磁盘的顺序读写性能,顺序读写不需要硬盘磁头的寻道时间,只需很少的扇区旋转时间,所以速度远快于随机读写。

  Kafka 官方给出了测试数据(Raid-5,7200rpm):

  顺序 I/O:600MB/s随机 I/O:100KB/s2)零拷贝

  先简单了解下文件系统的操作流程,例如一个程序要把文件内容发送到网络。

  这个程序是工作在用户空间,文件和网络socket属于硬件资源,两者之间有一个内核空间。

  在操作系统内部,整个过程为:

  在Linux kernel2.2之后出现了一种叫做"零拷贝(zero-copy)"系统调用机制,就是跳过“用户缓冲区”的拷贝,建立一个磁盘空间和内存的直接映射,数据不再复制到“用户态缓冲区”。

  系统上下文切换减少为2次,可以提升一倍的性能

  3)文件分段

  kafka 的队列topic被分为了多个区partition,每个partition又分为多个段segment,所以一个队列中的消息实际上是保存在N多个片段文件中。

  通过分段的方式,每次文件操作都是对一个小文件的操作,非常轻便,同时也增加了并行处理能力。

  4)批量发送

  Kafka 允许进行批量发送消息,先将消息缓存在内存中,然后一次请求批量发送出去,比如可以指定缓存的消息达到某个量的时候就发出去,或者缓存了固定的时间后就发送出去,如100条消息就发送,或者每5秒发送一次,这种策略将大大减少服务端的I/O次数。

  5)数据压缩

  Kafka 还支持对消息集合进行压缩,Producer可以通过GZIP或Snappy格式对消息集合进行压缩,压缩的好处就是减少传输的数据量,减轻对网络传输的压力,Producer压缩之后,在Consumer需进行解压,虽然增加了CPU的工作,但在对大数据处理上,瓶颈在网络上而不是CPU,所以这个成本很值得。

  面试题来源:

  《大数据面试题 V4.0》大数据面试题V3.0,523道题,679页,46w字可回答:

  1)说一说Zookeeper中的角色

  问过的一些公司:京东提前批(2020.07),蘑菇街实习(2020.03)

  参考答案:

  Zookeeper本身可以是单机模式,也可以是集群模式,为了Zookeeper本身不出现单点故障,通常情况下使用集群模式,而且是master/slave模式的集群

  Zookeeper集群角色

  Leader不直接接收client的请求,但接受由其他Follower和Observer转发过来的client请求。此外,Leader还负责投票的发起和决议,即时更新状态和数据。

  Follower角色接手客户端请求并返回结果,参与Leader发起的投票和选举,但不具有写操作的权限。

  Observer角色接受客户端连接,将写操作转给Leader,但Observer不参与投票(即不参加一致性协议的达成),只同步Leader节点的状态,Observer角色是为集群系统扩展而生的。

  连接Zookeeper集群的使用者,请求的发起者,独立于Zookeeper集群的角色。

  面试题来源:

  《大数据面试题 V4.0》大数据面试题V3.0,523道题,679页,46w字参考答案:

  一个 Kafka 的 Message 由一个固定长度的 header 和一个变长的消息体 body 组成,header 部分由一个字节的 magic(文件格式)和四个字节的 crc32(用于判断 body 消息体是否正常)构成。当 magic 的值为 1 的时候,会在 magic 和 crc32 之间多一个字节的数据:attributes(保存一些相关属性,比如是否压缩、压缩格式等等);如果 magic 的值为 0,那么不存在 attributes 属性。

  body 是由 N 个字节构成的一个消息体,包含了具体的 key/value 消息。

  具体字段解释如下:

  CRC32:4个字节,消息的校验码。magic:1字节,魔数标识,与消息格式有关,取值为0或1。当magic为0时,消息的offset使用绝对offset且消息格式中没有timestamp部分;当magic为1时,消息的offset使用相对offset且消息格式中存在timestamp部分。所以,magic值不同,消息的长度是不同的。attributes: 1字节,消息的属性。其中第0~ 2位的组合表示消息使用的压缩类型,0表示无压缩,1表示gzip压缩,2表示snappy压缩,3表示lz4压缩。第3位表示时间戳类型,0表示创建时间,1表示追加时间。timestamp: 时间戳,其含义由attributes的第3位确定。key length:消息key的长度。key:消息的key。value length:消息的value长度。value:消息的内容

  浏览器的页面型产品/服务的日志采集可分为两大类:

  页面浏览(展现)日志采集指一个页面被浏览器加载呈现时采集的日志此类日志是最基础的互联网日志此类日志是目前所有互联网产品的两大基本指标(页面浏览量(Page View,PV)和访客数(Unique Visitors,UV))的统计基础页面交互日志采集用户操作记录主要是为了对指标网页浏览量(PV)和访客数(UV)进行分析。

  采集页面被浏览器加载展现的记录,这是最原始的互联网日志采集需求,也是一切互联网数据分析得以展开的基 础和前提。

  一次典型的页面访问(请求-响应)过程:

  以用户访问淘宝首页为例

  用户在在地址栏中输入网址并回车浏览器向服务器发起HTTP请求服务器接收并解析请求浏览器接收到服务器的响应内容,并将其按照文档规范展现给用户,从而完成一次请求在上述网页浏览过程中,如果我们需要记录这次浏览行为,日志采集则是在这四个步骤中的某一环节。

  第一二步中,用户的请求尚未抵达服务器。直到第三步完成,我们也只能认为服务器处理了请求,不能保证浏览器能够正确地解析和渲染页面,不能确保用户已确实打开页面,因此在前三步是无法采集用户的浏览日志的。所以,采集日志的动作是发生在第四步,也就是浏览器开始解析文档时才能进行。

  日志采集思路:

  在HTML文档内的适当位置增加一个日志采集节点,当浏览器解析到这个节点时,将自动触发一个特定HTTP请求到日志采集服务器。当日志采集服务器接收到这个请求时,就可以确定浏览器已经成功地接收和打开了页面。页面浏览日志采集的主要过程如下:

  采集:客户端日志采集。HTML文档内植入JavaScript脚本进行采集。

  采集脚本被浏览器加载解析后执行,在执行时采集当前页面参数、浏览行为的上下文信息(如读取用户访问当前页面时的上一步页面)以及一些运行环境信息(如当前的浏览器和分辨率等)HTML文档内植入日志采集脚本的动作可以由业务服务器在响应业务请求时动态执行,也可以在开发页面时由开发人员手动植入。发送:客户端日志发送。日志采集完成后会立即发送或延迟发送。采集到的日志信息一般以URL参数形式放在HTTP日志请求的请求行内。

  采集脚本执行时,会向日志服务器发起日志请求,以将采集到的数据发送到日志服务器。收集:服务器端日志收集。由日志服务器完成对日志的收集。

  日志服务器接收到客户端请求后,会立即向浏览器发回一个请求成功的相应。日志收集模块会将日志请求内容写入一个日志缓冲区内,完成此条浏览日志的收集。存档:服务器端日志解析存档。日志服务器对浏览日志解析并存档。

  对用户在访问某个页面时具体的互动行为特征(交互日志)的采集,比如鼠标或输入焦点的移动变化(代表用户关注内容的变化)、对某些页面交互的反应(可借此判断用户是否对某些页面元素发生认知困难)等。常规的PV日志采集方法无法完成对上述操作日志的采集,因为这些行为往往并不触发浏览器加载新页面。

  交互日志的采集是以技术服务的形式呈现的。

  采集的交互日志发送到日志服务器需经过以下步骤:

  注册业务等的具体交互采集点,注册完成后,系统将生成与之对应的交互日志来集代码模板业务方将交互日志采集代码植入目标页面,并将采集代码与需监测的交互行为做绑定当用户在页面上产生指定行为时,采集代码和正常的业务互动代码起被触发和执行采集代码在采集动作完成后将对应的日志通过HTTP协议发送到日志服务器,日志服务对数据进行转储在大部分场合下,经过上述解析处理之后的日志并不直接提供给下游使用。一般还需要进行相应的离线预处理。具体操作如下:

  识别流量攻击、网络爬虫和流量作弊(虚假流量)对所采集的日志进行合法性校验,依托算法识别非正常的流量并归纳出对应的过滤规则集加以滤除。数据缺项补正对日志中的一些公用且重要的数据项做取值归 、标准化处理或反向补正(即根据新日志对稍早收集的日志中的个别数据项做回补或修订(例如,在用户登录后,对登录前页面日志做身份信息的回补))。无效数据剔除剔除无意义、已经失效或者冗余的数据项。日志隔离分发考虑到安全性,某些日志在进入公共数据环境之前需要做隔离。采集思路:无线客户端的日志采集采用采集SDK来完成。

  移动端的数据采集目的:

  服务于开发者,协助开发者分析各类设备信息帮助开发者了解用户、用户行为,不断对APP进行优化,提升用户体验与浏览器日志采集的不同之处:移动端的日志采集根据不同的用户行为分成不同的事件,“事件”为无线客户端日志行为的最小单位。

  区分不同事件的日志触发时机、日志内容和实现方式的差异更好地完成数据分析在阿里巴巴内部,多使用名为UserTrack(UT)来进行无线客户端的日志采集。基于常规的分析, UserTrack(UT)把事件分成了几类,常用的包括页面事件(同前述的页面浏览)和控件点击事件(同前述的页面交互)等。

  每条页面事件日志记录三类信息:

  设备及用户的基本信息。被访问页面的信息。主要是一些业务参数(如商品详情页的商品 ID 、所属的店铺等)访问基本路径。如页面来源、来源的来源,用于还原用户完整的访问行为。对于页面事件,UT提供了页面事件的无痕埋点, 即无须开发者进行任何编码即可实现。

  UT提供了两个接口,分别在页面展现和页面退出时调用。除此之外,还有页面扩展信息的接口,该接口必须在使用页面展现和页面退出方法的前提下使用。

  UT还提供了透传参数功能。所谓透传参数,即把当前页面的某些信息,传递到下一个页面甚至下下一个页面的日志中。

  1、控件点击事件

  记录了基本的设备信息、用户信息。

  记录了控件所在页面名称、控件名称、控件的业务参数等。

  控件点击事件的逻辑比页面事件要简单得多,就是操作页面上的某个控件,因此只需把相关基础信息告诉采集 即可。

  2、其他事件

  用户可以根据业务场景需求,使用自定义事件来采集相关信息。

  UT 提供了一个自定义埋点类,其包括:

  事件名称事件时长事件所携带的属性事件对应的页面为了平衡日志大小,减小流量消耗、采集服务器压力、网络传输压力等,采集 SDK 提供了聚合功能,对某些场景如曝光或一些性能技术类日志 ,我们提倡在客户端对这类日志进行适当聚合,以减少对日志采集服务器端的请求 ,适当减小日志大小。

  总体思路就是每个曝光的元素一般都属于一个页面,利用页面的生命周期来实现适当的聚合及确定发送时机。

  APP 分为两种:

  纯Native APP既有Native,又有H5页面嵌入的APP ,即Hybrid APPNative页面采用采集SDK进行日志采集,H5页面一般采用基于浏览器的页面日志采集方式进行采集。

  考虑到后续日志数据处理的便捷性、计算成本、数据的合理性及准确性,需要对Native H5日志进行统一处理。

  阿里选择Native部署采集SDK的方式,将H5日志归到Native日志。原因如下:

  SDK可以采集到更多的设备相关数据,这在移动端的数据分析中尤为重要采集SDK处理日志,会先在本地缓存,而后借机上传,在网络状况不佳时延迟上报,保证数据不丢失互联网产品的两大基本指标:页面浏览量(Page View,PV)和访客数(Unique Visitors,UV)。

  关于UV,对于登录用户,可以使用用户ID来进行唯一标识。PC一般使用Cookie信息来作为设备的唯一信息。对于APP来说,则需要选的设备唯一信息,不同版本的系统选择的标识不一样。

  无线客户端日志上传、压缩及传输。

  此时日志不是产生一条就上传一条,而是日志产生后,先存储在客户端本地,然后再伺机上传。

  伺机:需要有数据分析的支持,如在启动后、使用过程中、切换到后台时这些场景下分别多久触发一次上传动作。

  日志切分维度为天,当天接收的日志存储到当天的日志文件中。为了后续数据处理,以及特殊时期不同日志的保障级别,还根据应用及事件类型对每日高达数千亿的日志进行了分流。日志采集完成后,日志采集服务器的日志怎么给到下游呢?

  阿里主要使用消息队里(TimeTunel,TT)来实现从日志采集服务器到数据计算的MaxCompute。

  TT将消息收集功能部署到日志采集服务器上进行消息的收集,便于后续计算。

  实时计算:应用实时来订阅TT收集到的消息,进行实时计算。离线计算:离线的应用定时来获取消息,完成离线计算。各类采集方案提供者所面临的主要挑战已不是日志采集技术本身,而是如何实现日志数据的结构化和规范化组织,实现更为高效的下游统计计算,提供符合业务特性的数据展现,以及为算法提供更便捷、灵活的支持等方面。

  1、日志分流及定制处理

  大型互联网网站的日志类型和日志规模都呈现出高速增长的态势,而且往往会出现短时间的流量热点爆发。这一特点使得在日志服务器端采用集中统一的解析处理方案变得不可能,其要求在日志解析和处理过程中必须考虑业务分流(相互之间不应存在明显的影响,爆发热点不应干扰定常业务日志的处理)、日志优先级控制,以及根据业务特点实现定制处理。

  为了避免资源浪费(尽可能多地进行预处理)和需求覆盖不全(仅对最重要的内容进行预处理)两者取舍问题。阿里互联网日志采集体系的基本原则是分治策略。将分类任务前置到客户端,尽可能靠前地布置路由差异,就可以尽可能早地进行分流,降低日志处理过程中的分支判断消耗,并作为后续的计算资源调配的前提,提高资源利用效率。

  阿里的客户端日志采集代码的一个突出特点是实现了非常高的更新频次(业界大多以季度乃至年为单位更新代码,阿里则是以周/月为单位),并实现了更新的配置 。

  2、采集与计算一体化设计

  以PV日志为例,归类与汇总是页面PV日志采集之后的一个基础性操作。

  早期时,是以URL路径,继而以URL(正则)规则集为依托来进行日志分类的。网站规模小时,这种方式没问题,但是当网站规模大了,这种方式就不现实了,失控的大规模正则适配甚至会将日志计算硬件集群彻底榨干。

  阿里对采集与计算进行一体化设计,给出了两套日志规范和与之对应的元数据中心。

  PV日志的解决方案是目前用户可直观感知的SPM规范(例如,在页面的URL内可以看见spm参数)和SPM元数据中心。通过SPM的注册和简单部署(仅需要在页面文件内声明一个或多个标签),用户即可将任意的页面流量进行聚类,不需要进行任 多余的配置。自定义日志的解决方案则是黄金令箭(Goldlog)/APP端的点击或其他日志规范及其配置中心。通过注册一个与所在页面完全独立的令箭实体/控件实体,用户可以一键获得对应的埋点代码,并自动获得实时统计数据和与之对应的可视化视图。日志本身不是日志采集的目的,服务于基于日志的后续应用,才是日志采集正确的着眼点。

  这里以阿里“双11"为例。

  数据处理全链路如下图:

  端上实现服务器端推送配置到客户端,且做到高到达率;对日志进行分流;在实时处理方面,不断优化以提高应用的吞吐量;实时处理方面,评估峰值数据量,在高峰期通过服务器端推送配置的方式对非重要日志进行适当限流 ,错峰后逐步恢复。