《大数据之路:阿里巴巴大数据实践》语录
目录
一、数据采集 1
◆日志采集 1
▼浏览器的页面日志采集 1
▼无线客户端的日志采集 2
(1) 页面事件 3
(2) 控件点击事件 3
(3) 其它事件 3
(4) 特殊场景 3
(5)H5 & Native 日志统一 4
(6)设备标识 4
(7) 日志传输 5
▼日志采集挑战 5
(1) 日志分流与定制处理 5
(2) 采集与计算一体化设计 5
(3)大促保障 5
◆数据同步 6
▼直连同步 6
▼数据文件同步 6
▼数据库日志解析同步 6
▼阿里数据仓库的同步方式 7
(1) 批量数据同步 7
(2) 实时数据同步 7
▼数据同步遇到的问题与解决方案 8
(1)分库分表的处理 8
(2)高效同步和批量同步 8
(3) 增量与全量同步的合并 8
(4)同步性能的处理 8
(5)数据漂移的处理 9
(1)多获取后一天的数据 10
(2)通过多个时间戳字段限制时间来获取相对准确的数据 10
一、数据采集
◆日志采集
阿里巴巴的日志采集体系方案包括两大体系: Aplus.JS是Web端
(基于浏览器)日志采集技术方案: UserTrack是APP 端(无线客户端
日志采集技术方案。
▼浏览器的页面日志采集
(1)页面浏览(展现)日志采集。页面浏览日志是指一个页面被浏览器加载呈现时采集的日志。采集、发送、收集、解析存档四个步骤。
过程实现: 用户请求 -> 服务器响应用户请求(在HTML内插入日志采集代码) -> 浏览器执行日志采集代码,向日志服务器发送URL参数形式的日志请求 -> 日志服务器对日志解析、预处理、存储供后续使用
(2)页面交互日志采集。用户可在浏览器内与网页进行的互动,便通过量化获知用户的兴趣点或者体验优化点。需要了解用户在访问某个页面时具体的互动行为特征,比如鼠标或输入焦点的移动变化(代表用户关注内容的变化)、对某些页面交互的反应(可借此判断用户是否对某些页面元素发生认知困难)等。因为这些行为往往并不触发浏览器加载新页面,所以无法通过常规的 日志采集方法来收集。在阿里巴巴,通过一套名为“黄金令箭”的采集方案来解决交互日志的采集问题。
“黄金令箭”是一个开放的基于 HTTP 协议的日志服务,经过如下步骤即可将
自助采集的交互日志发送到日志服务器。
--在“黄金令箭”的元数据管理界面依次注册需要采集交互的业务、具体的业务场景以及场景下的具体交互采集点,在注册完成之后,系统将生成与之对应的交互日志采集代码模板。
--将交互日志采集代码植入目标页面,并将采集代码与需监测的交互行为做绑定。
--当用户在页面上产生指定行为时,采集代码和正常的业务互动
响应代码一起被触发和执行。
--采集数据到日志服务器,并可与浏览日志做关联运算等。
(3)其它日志采集。还有些专门针对某些特定统计场合的日志采集需求,如专门采集特定媒体在页面被曝光状态的曝光日志、用户在线状态的实时监测等,但基本原理上都脱胎于上述两大类。
(4)页面日志服务器端的清洗和预处理
--识别流量攻击、网络爬虫和流量作弊(虚假流量)。需要对所采集的日志进行合法性校验,依托算法识别非正常的流量并归纳出对应的过滤规则集加以滤除。
--数据缺项补正。需要对日志中的一些公用且重要的数据项做取值归一、标准化处理或反向补正。反向补正,即根据新日志对稍早收集的日志中的个别数据项做回补或修订(例如,在用户登录后,对登录前页面日志做身份信息的回补)。
--无效数据剔除。在某些情况下,因业务变更或配置不当,在采集到的日志中会存在一些无意义、已经失效或者冗余的数据项。这些数据项不仅消耗存储空间和运算能力,而且在偶然的情况下还可能干扰正常计算的进行。
--日志隔离分发。某些日志需要做隔离,避免互相干扰。
▼无线客户端的日志采集
无线客户端的日志采集采用采集 SDK 来完成,在阿里,使用名为 UserTrack的SDK 来进行日志采集。“事件”为无线客户端日志行为的最小单位。基于常规的分析, UserTrack (UT)把事件分成了几类,常用的包括页面事件(同前述的页面浏览)和控件点击事件(同前述的页面交互)等。
每条页面事件日志记录三类信息 ①设备及用户的基本信息:②被访问页面的信息,这里主要是一些业务参数(如商品详情页的商品 ID 、所属的店铺等) ; ③访问基本路径(如页面来源、来源的来源 ),用于还原用户完整的访问行为。
手动模式的埋点方式:
--页面展现的接口调用,记录页面进入时的一些状态信息,此时不发送日志。
--页面扩展信息的接口调用,使用该接口提供的方法给页面添加更多的参数。
--页面退出的接口调用,如当从该店铺详情页离开时(可能是在店铺详情页上点击某个商品到了对应的商品详情页,也可能是退出了手机淘宝,抑或是点击返回,返回到了之前的一个页面),调用页面退出的接口,该接口发送日志 。
透传参数,即把当前页面的某些信息,传递到下一个页面甚至下下一个页面的日志中。在阿里系内,使用 SPM (Super Position Model ,超级位置模型)进行来源去向的追踪, SPM 就使用到了透传机制。
控件点击事件比页面事件要简单得多,首先,它和页面事件一样,记录了基本的设备信息、用户信息:其次,它记录了控件所在页面名称、控件名称、控件的业务参数等。
所谓其他事件,就是用户可以根据业务场景需求,使用自定义事件来采集相关信息。UT 提供了一个自定义埋点类,其包括:①事件名称:②事件时长 ③事
件所携带的属性:④事件对应的页面。
UT提供了一些默认的日志采集方法 ,比如可以自动捕获应用崩溃,并且产生一条日志记录崩溃相关信息。类似的日志采集方法还有很多,比如应用的退出、页面的前后台切换等。诸如 些和业务信息不是非常相关,但又对分析起很大作用的日志采集 ,就完全没有必要让应用开发者去触发埋点了。
--上述场景均为一个行为产生一条日志,如一次浏览、一次点击等。如此用来处理普通的业务是足够的。为了平衡日志大小,减小流量消耗、采集服务器压力、网络传输压力等,采集 SDK 提供了聚合功能,对某些场景如曝光或一些性能技术类日志 ,提倡在客户端对这类日志进行适当聚合,以减少对日志采集服务器端的请求 ,适当减小日志大小。总体思路就是每个曝光的元素一般都属于一个页面,利用页面的生命周期来实现适当的聚合及确定发送时机。如商品页面浏览中商品曝光、对于一些只需要计数,而不需要知道具体内容的场景,如需要分析某些接口的调用次数。
--回退行为(如点击回退按钮、各种滑屏等),如页面回退导致页面来源记录不正确,解决方案,做特殊的设计,利用页面的生命周期,识别页面的复用配合栈的深度来识别是否是回退行为。
(5)H5 & Native 日志统一
APP分为两种:纯 Native APP; Hybrid APP(既有Native又有H5页面嵌入的APP)
Native 页面采用采集 SDK 进行日志采集, H5 页面采用基于浏览器的页面日志采集方式进行采集。由于采集方式的不同,采集到的内容及采集服务器均分开。若需要进行完整的数据分析,就需要将两类日志在数据处理时进关联,很麻烦。所以需要对Native和H5日志进行统一处理。
基于两点,我们选择将 H5日志归到 Native 日志。一是采 SDK 可以采集到更 多的设备相关数据,这在移动端的数据分析中尤为重要; 二是采集 SDK 处理日志,会先在本地缓存,而后借机上传,在网络状况不佳时延迟上报,保证数据不丢失。实现过程:
--H5页面浏览和页面交互的数据,在执行时通过加载日志采集JavaScript 脚本,采集当前页面参数。跟浏览器处理方式一样。
--JavaScript 脚本中实现将所采的数据打包到一个对象中,然后调用 WebView 框架的 JSBridge 接口,调用移动客户端对应的接口方法,将埋点数据对象当作参数传入。
--移动客户端日志采集 SDK ,封装提供接口,实现将传入的内容转换成移动客户端日志格式。采集 SDK 会根据日志类别来识别是页面浏览事件,还是控件点击事件,然后调用内部相应的接口进行处理,将埋点数据转换成移动客户端日志的统一格式。而后就同移动客户端的日志处理一样,先记录到本地日志缓存中,择机上传。未来如果要实现新的事件类别,比如自定义事件,就不需要改动 WebView 层的接口,只 需改动 JavaScript的部分内容及移动客户端日志采集 SDK 中对应的实现即可。
此方案也有其局限性,必须要浏览器采集 JavaScript脚本、Web View 、客户端采集 SDK 的配合。
(6)设备标识
关于 UV,对于登录用户,可以使用用户 ID 来进行唯一标识,但是很多日志行为并不要求用户登录,这就导致在很多情况下采集上来的日志都没有用户ID。PC端一般使用 Cookie 信息来作为设备的唯一信息,对于 APP来说,我们就要想办法获取到能够唯一标识设备的信息。
对于只有单 APP 的公司来说,设备唯一标识不是需要攻克的难题,但对于像阿里巴巴这样拥有众多 APP 的公司来说,设备唯 标识就显得尤为重要。历史上, MEI 、IMSI、 MAC 、苹果禁用之前的UDID。随着用户的自我保护意识加强以及各系统升级,很多基本的设备信息获取都不再那么容易。阿里无线设备唯一标识使用 UTDID ,它当然有很清晰的责任和目标,就是每台设备一个 ID 作为唯一标识。其生成方式使用一套较完备的算法。
当然单纯地靠间隔时间来决定上传动作是不够的,还需要考虑日志的大小及合理性(如单条日志超大,很可能就是错误日志)。另外,还需要考虑上传时网络的耗时,来决定是否要调整上传机制。
客户端数据上传时是向服务器发送 POST 请求,服务器端处理上传请求 ,对请求进行相关校验 ,将数据追加到本地文件中进行存储,存储方式使用 Nginx access_log, access_log 的切分维度为天,即当天接收的日志存储到当天的日志文件中。考虑到后续的数据处理,以及特殊时期不同日志的保障级别,还对日志进行了分流。
那么日志采集服务器的日志怎么给到下游呢?阿里主要使用消息队列(TimeTunel,TT)来实现从日采集服务器到数据计算的 MaxCompute 。简单来讲,就是 TT 将消息集功能部署到日志采集服务器上进行消息的收集,而后续的应用可以是实时的应用实时来订阅 TT 收集到的消息,进行实时计算,也可以是离线的应用定时来获取消息,完成离线的计算。
▼日志采集挑战
各类采集方案所面临的主要挑战已不是日志采集技术本身,而是如何实现日志数据的结构化和规范化组织,实现更为高效的下游统计计算,提供符合业务特性的数据展现,以及为算法提供更便捷、灵活的支持等方面。
往往会出现短时间的流量热点爆发。这一特点,使得在日志服务器端采用集中统一的解析处理方案变得不可能,其要求在日志解析和处理过程中必须考虑业务分流(相互之间不应存在明显的影响,爆发热点不应干扰定常业务日志的处理)、日志优先级控制,以及根据业务特点实现定制处理。例如,对于电商网站而言,数据分析人员对位于点击流前端的促销页面和位于后端的商品页面的关注点是不一样的,而这两类页面的流量又往往同等重要且庞大 ,如果采用统一的解析处理方案,则往往需要在资源浪费(尽可能多地进行预处理)和需求覆盖不全(仅对最重要的内容进行预处理)两个选择之 间进行取舍。
(3)大促保障
考虑到服务器的收集能力(如峰值QPS 等)、数据传输能力(TT的搬运速度)、实时解析的吞吐量、实时业务分析的处理能力。
服务器端推送配置包含较多的内容,首先是作用范围,可以针对应用、平台、事件、事件中的某个场景:其次是具体实施,包括延迟上报、部分采样等。所谓延迟上报,即配置生效后 ,满足条件的日志将被暂时存在客户端,待配置恢复后再上传到服务器 ;所谓采样 ,即配置生效后,满足条件的日志将被实施采样(对于些技术类日志,如页面加载情况、消耗内存等,可以实施采样),上报部分日志到服务器。
◆数据同步
▼直连同步
直连同步是指通过定义好的规范接口 API 和基于动态链接库的方式直接连接业务库,如 ODBC/JDBC 等规定了统一规范的标准接口,不同的数据库基于这套标准接口提供规范的驱动,支持完全相同的函数调用和 SQL 实现
业务库直连的方式对源系统的性能影响较大,当执行大批量数据同步时会降低甚至拖垮业务系统的性能。如果业务库采取主备策略,则可以从备库抽取数据,避免对业务系统产生性能影响。但是当数据量较大时,采取此种抽取方式性能较差,不太适合从业务系统到数据仓库系统的同步。
▼数据文件同步
数据文件同步通过约定好的文件编码、大小、格式等,直接从源系统生成数据的文本文件,由专门的文件服务器,如 FTP 服务器传输到目标系统后,加载到目标数据库系统中。
由于通过文件服务器上传、下载可能会造成丢包或错误,为了确保数据文件同步的完整性,通常除了上传数据文件本身以外,还会上传一个校验文件,该校验文件记录了数据文件的数据量以及文件大小等校验信息,以供下游目标系统验证数据同步的准确性。另外,在从源系统生成数据文件的过程中,可以增加压缩和加密功能,传输到目标系统以后,再对数据进行解压缩和解密,这样可以大大提高文件的传输效率和安全性。
▼数据库日志解析同步
以Oracle 为例,可以通过源系统的进程,读取归档日志文件用以收集变化的数据信息,并判断日志中的变更是否属于被收集对象,将其解析到目标数据文件中。这种读操作是在操作系统层面完成的,不需要通过数据库,因此不会给源系统带来性能影响。
数据库日志解析同步方式实现了实时与准实时同步的能力,延迟以控制在毫秒级别,并且对业务系统的性能影响也比较小,目前广泛应用于从业务系统到数据仓库系统的增量数据同步应用之中。
由于数据库日志抽取一般是获取所有的数据记录的变更(增、删、改),落地到目标表时我们需要根据主键去重按照日志时间倒排序获取最后状态的变化情况。对于删除数据这种变更情况,针对不同的业务场景可以采用一些不同的落地手法。针对删除数据这种变更,主要有三种方式:
第一种方式,不过滤删除流水。不管是否是删除操作,都获取同一主键最后变更的那条流水。
第二种方式,过滤最后一条删除流水,如果同一主键最后变更的那条流水是删除操作,就获取倒数第二条流水。
第三种方式,过滤删除流水和之前的流水。如果在同一主键变更的
过程中有删除操作,则根据操作时间将该删除操作对应的流水和之前的流水都过滤掉。
前端业务系统删除数据的方式一般有两种 :正常业务数据删除和工批量删除。手工批量删除通常针对类似的场景,业务系统只做逻辑删除,不做物理删除, DBA 定期将部分历史数据直接删除或者备份到备份库。一般情况下,可以采用不过滤的方式来处理,下游通过是否删除记录的标识来判断记录是否有效。
通过数据库日志解析进行同步的方式性能好、效率高,对业务系统的影响较小。但是它也存在如下一些问题
·数据延迟。例如,业务系统做批量补录可能会使数据更新量超出系统处理峰值,导致数据延迟。
·投人较大。采用数据库日 抽取的方式投入较大,需要在源数据库与目标数据库之间部署 个系统实时抽取数据。
·数据漂移和遗漏。数据漂移,一般是对增量表而言的,通常是指该表的同一个业务日期数据中包含前一天或后一天凌晨 附近的数据或者丢失当天的变更数据。
▼阿里数据仓库的同步方式
可以通过将各类源数据库系统的数据类型统一转换为字符串类型的方式,实现数据格式的统一。
DataX能满足多方向高自由度的异构数据交换服务产品。对于不同的数据源, DataX 通过插件的形式提供支持,将数据从数据源读出并转换为中间状态,同时维护好数据的传输、缓存等工作。数据在 DataX 中以中间状态存在, 并在目标数据系统中将中间状态的数据转换为对应的数据格式后写人。
DataX 采用 Framework+Plugin 的开放式框架实现, Framework 处理缓冲、流程控制、并发、上下文加载等高速数据交换的大部分技术问题,并提供简单的接口与插件接入。数据传输在单进程(单机模式)/多进程(分布式模式)下完成,传输过程全内存操作,不读写磁盘,也没有进程间通信,实现了在异构数据库或文件系统之间的高速数据交换。Reader和Writer 通过 channel 交换数据。
通过解析 MySQL的 binlog日志(相当于 Oracle 的归档日志)来实时获得增量的数据更新,并通过消息订阅模式来实现数据的实时同步的。
TimeTunnel (TT )是一种基于生产者、消费者和 Topic 消息标识的消息中间件,支持主动、被动等多种数据订阅机制,订阅端自动负载均衡,消费者自己把握消费策略。对于读写比例很高的 Topic ,能够做到读写分离,使消费不影响发送。同时支持订阅历史数据,可以随意设置订阅位置,方便用户回补数据。另外,针对订阅有强大的属性过滤功能,用户只需关心自己需要的数据即可。
▼数据同步遇到的问题与解决方案
(1)分库分表的处理
阿里的TDDL ( Taobao Distributed Data Layer )是一个分布式数据库的访问引擎,通过建立中间状态的逻辑表来整合统一分库分表的访问。就能让下游应用像访问单库单表一样方便。
(2)高效同步和批量同步
阿里通过 OneClick 产品,真正实现了数据的一键化和批量化同步,一键完成 DDL和DML 生成、数据的冒烟测试以及在生产环境中测试等。因此,阿里巴巴通过极少的人力投入,实现了数据同步的集中化建设和管理:改变了之前各数据开发人员自行同步带来的效率低、重复同步和同步配置质量低下等问题,大大降低了数据同步成本。
将当天的增量数据和前一天的全量数据做全外连接,重新加载最新的全量数据。在大数据量规模下,全量更新的性能比 update 要高得多。此外,如果担心数据更新错误问题,可以采用分区方式,每天保持一个最新的全量版本,保留较短的时间周期(如3~7天)
(4)同步性能的处理
在大型的数据调度工作台上,每天会运行大量的数据同步任务。针对数据同步任务,一般首先需要设定首轮同步的线程数,然后运行同步任务。这样的数据同步模式存在几个问题,导致的最终结果是数据同步任务运行不稳定。
针对数据同步任务中存在的问题,阿里巴巴数据团队实践出了一套基于负载均衡思想的新型数据同步方案。该方案的核心思想是通过目标数据库的元数据估算同步任务的总线程数,以及通过系统预先定义的期望同步速度估算首轮同步的线程数,同时通过数据同步任务的业务优先级决定同步线程的优先级,最终提升同步任务的执行效率和稳定性。
具体实现步骤如下
·用户创建数据同步任务,并提交该同步任务。
·根据系统提前获知及设定的数据,估算该同步任务需要同步的数据量、平均同步速度、首轮运行期望的线程数、需要同步的总线程数。
·根据需要同步的总线程数将待同步的数据拆分成相等数量的数据块,一个线程处理一个数据块,并将该任务对应的所有线程提交至同步控制器。
·同步控制器判断需要同步的总线程数是否大于首轮运行期望的线程数,若大于,则跳转至,若不大于,则跳转至。
·同步控制器采用多机多线程的数据同步模式,准备该任务第一轮线程的调度,优先发送等待时间最长、优先级最高且同一任务的线程。
·同步控制器准备一定数据量(期望首轮线程数-总线程数)的虚拟线程,采用单机多线程的数据同步模式 ,准备该任务相应实体线程和虚拟线程的调度,优先发送等待时间最长、优先级最高且单机 CPU 剩余资源可以支持首轮所有线程数且同一任务的线程,如果没有满足条件的机器,则选择 CPU 剩余资源最多的机器进行首轮发送。
·数据任务开始同步,并等待完成。
·数据任务同步结束。
(5)数据漂移的处理
数据漂移是 ODS 数据的一个顽疾,通常是指 ODS 表的同一个业务日期数据中包含前一天或后一天凌晨附近的数据或者丢失当天的变更数据。
时间戳字段分为四类:
数据库表中用来记录具体业务过程发生时间的时间戳字段 (假设这类字段叫 proc_time)
数据库表中用来标识数据记录更新时间的时间戳字段(假设这类字段叫 modified time )
数据库日志中用来标识数据记录更新时间的时间戳字段(假设这类字段叫 log_time)
标识数据记录被抽取到时间的时间戳字段(假设这类字段Extract_time)
理论上,这几个时间应该是一致的,但是在实际生产中,这几个时间往往会出现差异,如由于网络或者系统压力问题, log_time 或者 modified_time 会晚于Proc_time。通常的做法是根据其中的某个字段来切分 ODS 表,这就导致产生数据漂移。
具体看下数据漂移的几种场景:
·根据 extract_time 来获取数据。这种情况数据漂移的问题最明显
·根据 modified_time 限制。在实际生产中这种情况最常见,但是往往会发生不更新 modified time 而导致的数据遗漏,或者凌晨时间产生的数据记录漂移到后一天。
·根据 log_time 限制。由于网络或者系统压力问题, log_time 会晚于proc_time ,从而导致凌晨时间产生的数据记录漂移到后一天。
·根据 proc_time 限制。仅仅根据 proc_time 限制,我们所获取的ODS 表只是包含一个业务过程所产生的记录(如订单有下单、支付、成功等多个业务状态),会遗漏很多其他过程的变化记录,这违背了 ODS 和业务系统保持一致的设计原则
处理方法主要有以下两种:
(1)多获取后一天的数据
在ODS 每个时间分区中向前、向后多冗余些数据,保障数据只会多不会少,而具体的数据切分让下游根据自身不同的业务场景用不同的业务时间 proc time 来限制。但是这种方式会有一些数据误差,例如 个订单是当天支付的,但是第二天凌晨申请退款关闭了该订单,那么这条记录的订单状态会被更新,下游在统计支付订单状态时会出现错误。
(2)通过多个时间戳字段限制时间来获取相对准确的数据
·首先根据 log_time 分别冗余前一天最后 15 分钟的数据和后一天凌晨开始 15 分钟的数据,并用 modified time 过滤非当天数据,确保数据不会因为系统问题而遗漏。
·然后根据 log_time 获取后一天 15 分钟的数据,针对此数据,按照主键根据 log_time 做升序排列去重。因为我们需要获取的是最接近当天记录变化的数据(数据库日志将保留所有变化的数据,但是落地到 ODS 表的是根据主键去重获取最后状态变化的数据)。
·最后将前两步的结果数据做全外连接,通过限制业务时间proc_time 来获取我们所需要的数据。
处理淘宝交易订单的数据漂移的实际案例:
·根据实际情况获取后一天15 分钟的数据,并限制多个业务过程的时间戳字段(下单、支付、成功)都是“双11 ”当天的,然后对这些数据按照订单的 modified_time做升序排列,获取每个订单首次数据变更的那条记录。
·此外,我们可以根据 log_time 分别冗余前一天最后 15 分钟的数据和后一天凌晨开始 15 分钟的数据,并用 modified_time 过滤非当天数据,针对每个订单按照 log_time 进行降序排列 ,取每个订单当天最后一次数据变更的那条记录。
·最后将两份数据根据订单做全外连接,将漂移数据回补到当天数据中。