携程实时用户数据采集与分析系统

1、携程实时用户数据采集系统设计实践


随着移动互联网的兴起,特别是近年来,智能手机、pad等移动设备凭借便捷、高效的特色风靡全球,同时各种APP的快速发展进一步下降了移动互联网的接入门槛,愈来愈多的网民开始从传统PC转移至移动终端上。但传统的基于PC网站和访问日志的用户数据采集系统已经没法知足实时分析用户行为、实时统计流量属性和基于位置服务(LBS)等方面的需求。

咱们针对传统用户数据采集系统在实时性、吞吐量、终端覆盖率等方面的不足,分析了在移动互联网流量剧增的背景下,用户数据采集系统的需求,研究在多种访问终端和多种网络类型的场景下,用户数据实时、高效采集的方法,并在此基础上设计和实现实时、有序和健壮的用户数据采集系统。此系统基于Java NIO网络通讯框架(Netty)和分布式消息队列(Kafka)存储框架实现,其具备实时性、高吞吐、通用性好等优势。

一、技术选型和设计方案

一个典型的数据采集分析统计平台,对数据的处理,主要由以下五个步骤组成:


图1 数据平台处理流程


其中,数据采集步骤是最核心的问题,数据采集是否丰富、准确和实时,都直接影响整个数据分析平台的应用的效果。本论文关注的步骤主要在数据采集、数据传输和数据建模存储这三部分。

为知足数据采集服务实时、高效性、高吞吐量和安全性等方面的要求,同时能借鉴互联网大数据行业一些优秀开源的解决方案,因此整个系统都将基于Java技术栈进行设计和实现。整个数据采集分析平台系统架构以下图所示:


图2 数据采集分析平台系统架构


其中整个平台系统主要包括以上五部分:客户端数据采集SDK以Http(s)/Tcp/Udp协议根据不一样的网络环境按必定策略将数据发送到Mechanic(UBT-Collector)服务器。服务器对采集的数据进行一系列处理以后将数据异步写入Hermes(Kafka)分布式消息队列系统。为了关联业务服务端用户业务操做埋点、日志,业务服务器须要获取由客户端SDK统一辈子成的用户标识(C-GUID),而后业务服务器将用户业务操做埋点、日志信息以异步方式写入Hermes(Kafka)队列。最后数据消费分析平台,都从Hermes(Kafka)中消费采集数据,进行数据实时或者离线分析。其中Mechanic(UBT-Collector)系统还包括对采集数据和自身系统的监控,这些监控信息先写入Hbase集群,而后经过Dashboard界面进行实时监控。

(1)基于NIO的Netty网络框架方案

要知足前面提到的高吞吐、高并发和多协议支持等方面的要求。咱们调研了几种开源异步IO网络服务组件(如Netty、MINI、xSocket),用它们和Nginx Web服务器进行了性能对比,决定采用Netty做为采集服务网络组件。下面对它进行一些概要介绍:Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,Netty的全部IO操做都是异步非阻塞的,经过Future-Listener机制,用户能够方便的主动获取或者经过通知机制得到IO操做结果。


图3 Netty框架内部组件逻辑结构


Netty的优势有:

    功能丰富,内置了多种数据编解码功能、支持多种网络协议。

    高性能,经过与其它主流NIO网络框架对比,它的综合性能最佳。

    可扩展性好,可经过它提供的ChannelHandler组件对网络通讯方面进行灵活扩展。

    易用性,API使用简单。

    通过了许多商业应用的考验,在互联网、网络游戏、大数据、电信软件等众多行业获得成功商用。

Netty采用了典型的三层网络架构进行设计,逻辑架构图以下:


图4 Netty三层网络逻辑架构


    第一层:Reactor通讯调度层。该层的主要职责就是监听网络的链接和读写操做,负责将网络层的数据读取到内存缓冲区中,而后触发各类网络事件,例如链接建立、链接激活、读事件、写事件等,将这些事件触发到Pipeline中,再由Pipeline充当的职责链来进行后续的处理
    第二层:职责链Pipeline层。负责事件在职责链中有序的向前(后)传播,同时负责动态的编排职责链。Pipeline能够选择监听和处理本身关心的事件。
    第三层:业务逻辑处理层,通常可分为两类:a. 纯粹的业务逻辑处理,例如日志、订单处理。b. 应用层协议管理,例如HTTP(S)协议、FTP协议等。

咱们都知道影响网络服务通讯性能的主要因素有:网络I/O模型、线程(进程)调度模型和数据序列化方式。

在网络I/O模型方面,Netty采用基于非阻塞I/O的实现,底层依赖的是JDK NIO框架的Selector。

在线程调度模型方面,Netty采用Reactor线程模型。经常使用的Reactor线程模型有三种,分别是:

    Reactor单线程模型:Reactor单线程模型,指的是全部的I/O操做都在同一个NIO线程上面完成。对于一些小容量应用场景,可使用单线程模型。

    Reactor多线程模型:Rector多线程模型与单线程模型最大的区别就是有一组NIO线程处理I/O操做。主要用于高并发、大业务量场景。

    主从Reactor多线程模型:主从Reactor线程模型的特色是服务端用于接收客户端链接的再也不是一个单独的NIO线程,而是一个独立的NIO线程池。利用主从NIO线程模型,能够解决一个服务端监听线程没法有效处理全部客户端链接的性能不足问题。Netty线程模型并不是固定不变的,它能够支持三种Reactor线程模型。

在数据序列化方面,影响序列化性能的主要因素有:

    序列化后的码流大小(网络带宽占用)。

    序列化和反序列化操做的性能(CPU资源占用)。

    并发调用时的性能表现:稳定性、线性增加等。

Netty默认提供了对Google Protobuf二进制序列化框架的支持,但经过扩展Netty的编解码接口,能够实现其它的高性能序列化框架,例如Avro、Thrift的压缩二进制编解码框架。

经过对Netty网络框架的分析研究以及对比测试(见后面的可行性分析测试报告)可判断,基于Netty的数据采集方案能解决高数据吞吐量和数据实时收集的难点。

(2)客户端数据加解密和压缩方案

对一些明感的采集数据,须要在数据传输过程当中进行加密处理。目前存在的问题是,客户端采集代码比较容易被匿名用户获取并反编译(例如Android、JavaScript),致使数据加密的算法和密钥被用户窃取,较难保证数据的安全性。根据加密结果是否能够被解密,算法能够分为可逆加密和不可逆加密(单向加密)。具体的分类结构以下:


图5 加密算法分类


密钥:对于可逆加密,密钥是加密解算法中的一个参数,对称加密对应的加解密密钥是相同的;非对称加密对应的密钥分为公钥和私钥,公钥用于加密,私钥用于解密。私钥是不公开不传送的,仅仅由通讯双方持有保留;而公钥是能够公开传送的。非对称密钥还提供一种功能,即数字签名。经过私钥进行签名,公钥进行认证,达到身份认证的目的。

根据数据采集客户端的特色,对于采集数据使用对称加密算法是很明智的选择,关键是要保证对称密钥的安全性。目前考虑的方案主要有:

    将加解密密钥放入APP中某些编译好的so文件中,若是是JavaScript采集的话,构造一个用C编写的算法用于生成密钥,而后借助Emscripten把C代码转化为JavaScript代码,这种方案有较好的混淆做用,让窃听者不太容易获取到对称密钥。

    将密钥保存到服务器端,每次发送数据前,经过HTTPS的方式获取加密密钥,而后对采集数据进行加密和发送。

    客户端和服务器端保存一份公钥,客户端生成一个对称密钥K(具备随机性和时效性),使用公钥加密客户端通讯认证内容(UID+K),并发送到服务器端,服务端收到通讯认证请求,使用私钥进行解密,获取到UID和对称密钥K,后面每次采集的数据都用客户端内存中的K进行加密,服务器端根据UID找到对应的对称密钥K,进行数据解密。

这三种客户端数据加密方式基本能解决客户端采集数据传输的安全性难题。

采集数据压缩。为了节省流量和带宽,高效发送客户端采集的数据,须要使用快速且高压缩比的压缩算法,目前考虑使用标准的GZIP和定制的LZ77算法。

(3)基于携程分布式消息中间件Hermes的数据存储方案

Hermes是基于开源的消息中间件Kafka且由携程自主设计研发。总体架构如图:


图6 Hermes消息队列总体架构


Hermes消息队列存储有三种类型:

    MySQL适用于消息量中等及如下,对消息治理有较高要求的场景。

    Kafka适用于消息量大的场景。

    Broker分布式文件存储(扩展Kafka、定制存储功能)。

因为数据采集服务的消息量很是大,因此采集数据须要存储到Kafka中。Kafka是一种分布式的,基于发布/订阅的消息系统。它能知足采集服务高吞吐量、高并发和实时数据分析的要求。它有以下优秀的特性:

    以时间复杂度为O(1)的方式提供消息持久化能力,即便对TB级以上数据也能保证常数时间复杂度的访问性能。

    高吞吐率。即便在很是廉价的商用机器上也能作到单机支持每秒100K条以上消息的传输。

    支持Kafka Server间的消息分区,及分布式消费,同时保证每一个Partition内的消息顺序传输。

    同时支持离线数据处理和实时数据处理。

    Scale out,即支持在线水平扩展。

一个典型的Kafka集群中包含若干Producer(能够是Web前端产生的采集数据,或者是服务器日志,系统CPU、Memory等),若干broker(Kafka支持水平扩展,通常broker数量越多,集群吞吐率越高),若干Consumer Group,以及一Zookeeper集群。Kafka经过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance。Producer使用push模式将消息发布到broker,Consumer使用pull模式从broker订阅并消费消息。Kafka拓扑结构图以下:


图7 Kafka拓扑结构


咱们知道,客户端用户数据的有序性采集和存储对后面的数据消费和分析很是的重要,可是在一个分布式环境下,要保证消息的有序性是很是困难的,而Kafka消息队列虽然不能保证消息的全局有序性,但能保证每个Partition内的消息是有序的。在用户数据采集和分析的系统中,咱们主要关注的是同一个用户的数据是否能保证有序,若是咱们在数据采集服务端能将同一个用户的数据存储到Kafka的同一个Partition中,那么就能保证同一个用户的数据是有序的,所以基本上能解决采集数据的有序性。

(4)基于Avro格式的数据灾备存储方案

当出现网络严重中断或者Hermes(Kafka)消息队列故障状况下,用户数据须要进行灾备存储,目前考虑的方案是基于Avro格式的本地文件存储。其中Avro是一个数据序列化反序列化框架,它能够将数据结构或对象转化成便于存储或传输的格式,Avro设计之初就用来支持数据密集型应用,适合于远程或本地大规模数据的存储和交换。

Avro定义了一个简单的对象容器文件格式。一个文件对应一个模式,全部存储在文件中的对象都是根据模式写入的。对象按照块进行存储,在块之间采用了同步记号,块能够采用压缩的方式存储。一个文件由两部分组成:文件头和一个或者多个文件数据块。其存储结构以下图所示:


图8 Avro对象容器文件格式


灾备存储处理过程是:当网络异常或者Hermes(Kafka)消息队列出现故障时,将采集的用户数据解析并转化成Avro格式后,直接序列化存储到本地磁盘文件中,数据按Kafka-Topic分红多个文件存储,且每小时自动生成一个新的文件。当网络或者Hermes(Kafka)故障恢复后,后端线程自动读取磁盘Avro文件,将数据写入Hermes(Kafka)消息队列的对应Topic和分区中。每一个文件写入成功后,自动删除灾备存储文件。这样能增长用户数据采集服务的健壮性和加强服务容错性。

二、架构设计方案可行性分析

在相同配置的测试服务器上(包括数据采集服务器、Hermes(Kafka)集群)作以下对比实验测试:(使用ApacheBenchmark进行Web性能压力测试工具)

(1)Netty VS Nginx处理网络请求对比

在不对采集数据进行业务处理的状况下(即只接请求并作响应,不作业务处理,也不存储采集数据),在5000并发,Keepalive模式下均能达到每秒处理4万多请求,其中Nginx的CPU、内存消耗会小一些。测试对比数据以下:( ab参数: -k –n 10000000 –c 5000)




(2)Netty对采集数据进行业务处理

Netty服务加上采集数据解析相关业务处理,以及处理后的数据写入Hermes(Kafka)消息队列。能够进行简单的间接估算。若是采集服务要求达到:每秒处理3万左右请求,99%的请求完成时间小于800ms的目标,则采集数据解析和存储流程的处理时间必须在600ms之内。而这两步又分为数据解析和数据存储,能够分别进行压力测试加以验证。 根据咱们的压力测试,采集数据解析和存储也能彻底知足性能要求。

经以上对比实验测试代表,使用Netty服务组件收集、解析数据并直接写入Hermes(Kafka)分布式消息队列的方案初步具有可行性。
2、相关数据分析产品介绍


基于实时采集到的用户数据和系统监控数据,咱们开发了一套相关的数据分析产品。产品的内容主要分如下几部分:(1)、API和页面性能报表;(2)、页面访问和流量;(3)、用户行为分析;(4)、系统异常崩溃分析;(5)、数据实时查询工具;(6)、采集数据排障工具;(7)、其它。其中详细分类以下图所示:


图9 数据分析产品分类


现选取其中几个比较常见的产品作下简单介绍:

一、单用户浏览跟踪

做用:实时跟踪用户浏览记录,帮助产品优化页面访问流程、帮助用户排障定位问题。

使用案例:根据用户在客户端上的惟一标识ID,如:手机号、Email、注册用户名、ClientId、VisitorId等查询此用户在某一时间段顺序浏览过的页面和每一个页面的访问时间及页面停留时长等信息。若是用户在浏览页面过程当中发生了异常崩溃退出状况,能够结合应用崩溃信息关联查询到相关信息。

二、页面转化率

做用:实时查看各个页面的访问量和转化状况,帮助分析页面用户体验以及页面布局问题。

使用案例:用户首先配置页面浏览路径,如p1023 -> p1201 -> p1137 -> p1300,而后根据用户配置页面浏览路径查询某个时间段各个页面的转化率状况。若有1.4万用户进入p1023页面,下一步有1400用户进入下一页面p1201。这样可推算出页面p1201的转化率为10%左右。这是最简单的一种页面转化率,还有间接的页面转化率,即只匹配第一个和最后一个页面的访问量。同时能够按各类维度进行条件筛选,好比:网络、运营商、国家、地区、城市、设备、操做系统等等。

三、用户访问流

做用:了解每一个页面的相对用户量、各个页面间的相对流量和退出率、了解各维度下页面的相对流量。

使用案例:用户选择查询维度和时间段进行查询,就能获取到应用从第一个页面到第N个页面的访问路径中,每一个页面的访问量和独立用户会话数、每一个页面的用户流向、每一个页面的用户流失量等信息。

四、点击热力图

做用:发现用户常常点击的模块或者区域,判断用户喜爱、分析页面中哪些区域或者模块有较高的有效点击数、应用于A/B测试,比较不一样页面的点击分布状况、帮助改进页面交互和用户体验。

使用案例:点击热力图查看工具包括Web和APP端,统计的指标包括:原始点击数(当前选中元素的原始点击总数)、页面浏览点击数(当前选中元素的有效点击数,同一次页面浏览,屡次点击累计算1次点击)、独立访客点击数(当前选中元素的有效点击数, 同一用户,屡次点击累计算1次点击)。

五、采集数据验证测试

做用:快速测试是否能正常采集数据、数据量是否正常、采集的数据是否知足需求等。

使用案例:用户使用携程APP扫描工具页面的二维码,获取用户标识信息,以后正常使用携程APP过程当中,能实时地将采集到的数据分类展现在工具页面中,对数据进行对比测试验证。

六、系统性能报表

做用:监控系统各业务服务调用性能(如SOA服务、RPC调用等)、页面加载性能、APP启动时间、LBS定位服务、Native-Crash占比、JavaScript错误占比等。按小时统计各服务调用耗时、成功率、调用次数等报表信息。

基于前端多平台(包括iOS、Android、Web、Hybrid、RN、小程序)数据采集SDK的丰富的自动化埋点数据,咱们能够对数据、用户、系统三方面进行多维度立体的分析。服务于系统产品和用户体验、用户留存、转换率及吸引新用户。前端

相关文章
相关标签/搜索