zoukankan      html  css  js  c++  java
  • 腾讯分析系统架构解析

    版权声明:本文由楚大鹏原创文章,转载请注明出处: 
    文章原文链接:https://www.qcloud.com/community/article/262

    来源:腾云阁 https://www.qcloud.com/community

    TA(Tencent Analyticis,腾讯分析)是一款面向第三方站长的免费网站分析系统,是腾讯海量数据分析能力对外的开放。腾讯分析在数据稳定性、及时性方面广受站长好评,其秒级的实时数据更新频率达到业界领先水平。本文将从实时数据处理、数据存储等多个方面带您深入探寻TA的系统架构及实现原理。

    腾讯分析业务简介

    网站分析(Web Analytics)主要指的是基于网站的用户浏览行为,对网站的点击流数据和运营数据进行分析,以监控网站的运营状况,为网站的优化提供决策依据。网站分析系统已成为站长日常运营必不可少的工具,业界比较流行的网站分析系统主要有Google Analytics、CNZZ、百度统计等产品。

    腾讯分析作为网站分析产品的后起之秀在社区分析、用户画像、网站工具等多个方面形成了自己的特色,尤其TA的秒级的实时数据更新频率更是业界翘楚,在数据稳定性、准确性、及时性方面TA在站长圈也是享有良好的口碑。

    随着接入业务量的不断发展,TA日均需要处理、计算的数据量达到T级。如此庞大的数据量想要达到秒级实时并且保证系统的高可用并非是容易的事情。腾讯分析的实时计算框架借鉴了业界一些业界流行的流式计算系统,在构建系统中遇到的一些问题,之于海量数据的实时处理、实时存储具备一定的典型性与通用性,故将腾讯分析的解决方案分享出来,希望可以带给大家一些启示。

    腾讯分析基本原理及系统架构

    腾讯分析的基本原理是通过嵌入站长网站的JS脚本“打点”收集用户访问行为数据,并发送腾讯分析采集集群,采集集群收到数据后将其过滤、编码、格式化后继续后向分发。数据处理集群负责按照业务逻辑计算数据,并将计算结果“写入”到数据存储集群,最后将结果数据展现给广大站长使用。基本原理如下图所示:

    腾讯分析后台是一套完成的数据流处理系统:由JS采集的用户行为数据像川流不息的河水一样流入腾讯分析后台,经过清洗、计算后源源不断地流出到腾讯分析存储集群,供用户浏览、查询。具体架构及核心部件如下图:

    腾讯分析的后台分为离线和实时两个部分,实时部分负责系统的主要功能计算,数据更新频率为秒级;离线部分负责系统复杂的关联分析及跨天计算,数据更新频率为天级。

    n Http Access:主要负责http协议的解析,数据的清洗及格式化;

    n ESC: Event Streaming Coder:主要负责将系统不可枚举的数据类型编码成为整型,并将对应关系持久化;

    n ESP: Event Streaming Processor:主要负责将数据按照站点、UID重新组织并计算PV、UV、停留时长、蹦失率等网站分析指标;

    n ESA:Event Streaming Aggregator:主要负责将ESP计算后的数据按照站点汇总,并将接入写入到redis中;

    n Center:系统的中心节点,负责系统配置、数据路由的管理,并承担容灾切换功能;

    n Logserver:负责将Access收集到的数据以字符串形式写入文件,并上传到TDCP上;

    n TDCP:腾讯分布式计算平台,负责离线数据的计算,并由脚本将结果数据写入到mysql中;

    腾讯分析的实时解决方案

    在介绍腾讯分析实时解决方案前,我们先来了解下腾讯分析支撑的业务量。当前腾讯分析日均需要处理几十万网站的上T级数据,处理过后的url个数仍有上亿条,系统存储的key个数超过十亿。如何高效、低延迟的处理如此大量的业务数据是腾讯分析实时系统面临的主要挑战。腾讯分析的解决主要思路可以概括为数据全二进制化、计算全内存化、存储nosql化。下面就实时计算和实时存储这两大子系统进行深入的讨论。

    实时计算

    对于计算子系统我们参考了Hadoop, S4,Storm等开源项目,力图设计为一个较为通用,扩展性较强的全内存实时Event处理系统(或者套用流行的术语称为流式实时Event处理系统)。对于这样的一个系统,我们设计支持的典型输入输出流程大致如下:

    实时计算系统主要的设计要点在数据组织、协议以及增量计算模型上。

    1.数据组织

    万物皆Int,考虑到内存以及计算过程的性能需求,我们将所有非int的数据类型转化为int。可以枚举的数据类型将其配置化映射为唯一int;不可枚举的数据类型则利用MD5算法近似得到唯一的int。例如页面URL属于不可枚举的类型,则预处理通过MD5算法近似得到唯一的int;UserAgent里的浏览器类型字符串则属于可枚举的数据,则预先配置化映射为int。这个方法节省了较多的内存,也提高了整个系统的计算性能。

    2.协议

    协议层面上,我们首先设计实现了一种可扩展的Event结构,这种Event结构支持半自动化的序列化/反序列化机制(参考自msgpack的设计),紧凑的二进制编码(基于Zigzag编码,参考Protobuf的实现)。这种Event结构在流式高性能IO(网络传输,持久化)方面表现的相当良好。实时计算子系统被设计为可以扩展支持任意的Event实现。

    3.增量计算模型

    所谓的增量计算模型,指的是基本计算过程被定义为三个部分:

    n Processor:负责具体业务逻辑的计算处理

    n Data Holder:负责保存增量结果数据,以及计算依赖的中间状态数据

    n Emitter:负责定期输出清空增量计算结果

    具体到流程方面,则如下所示分三个步骤:

    • n 接收Event,计算处理——Processor

    • n 保存计算结果以及计算依赖中间数据——Data Holder

    • n 定时触发输出时间片内计算结果,清空计算结果——Emitter

    增量计算模型弱化了分布式系统中单台机器的事务状态,相应地简化了分布式计算系统的实现,同时也提高了整个系统的性能。

    实时存储

    在TA系统中,实时存储的数据都是需要通过Web展示层读取的统计数据。这类数据存在两个典型特点:

    • n 频繁更新写,更新频度视系统实时性而定,每条统计结果更新频度最快可以达到1秒;

    • n 少量读取,“少量”是相对上述更新而言;

    同时根据业务逻辑,我们将统计数据划分为两类:

    • n 固定不变数据:主要是URL,搜索关键词等数据,这一部分数据理论上是不停地增加,不会修改旧有数据;
    • n 动态数据:主要是频繁更新的结果统计数据,这一部分数据则需要不停地更新。比如QQ域名下的PV,UV统计结果;

    考虑到上述的TA实时统计数据的特点,我们选择NoSQL实现我们的存储系统;同时,针对两类不同的数据类型,分别选择LevelDB,Redis存储不同的类型数据。

    • n Redis
      腾讯分析实时存储的主要构件。考虑到腾讯分析系统本身就是一个比较完善的分布式集群系统,因此我们需要的存储构件是”not clustering, but sharding”。也就是说像Hbase、mogoDB这样的“重武器”并不适合腾讯分析,而nosql数据库中的“瑞士军刀”redis凭借其出色的性能走入我们的视野。同时腾讯分析的结果数据类型也比较丰富,有像站点PV、UV、VV、IP等hash类型的数据,也有像用户访问轨迹这样set类型的“动态数据”,而redis丰富的数据结构很好地完成了这项任务。
      另外一个选择redis的原因是它足够的简单且易于扩展。在实际应用的过程中,我们发现的问题都可以通过扩展redis命令来解决。例如,腾讯分析中有这样的一种应用场景:为了消除ESA模块的状态,存储在redis中的数据往往并不是最终的结果数据,而是还需要进一步运算的中间数据。像bounce rate这个指标(bounce rate=bounce session数/total session数),需要前台查询两次再做一次运算后最终展示给用户。在高并发的情况下,这无疑会影响系统的响应速度。本着“移动计算,而不是移动数据”的原则,我们对redis的sort、hmget命令进行了扩展使其支持四则运算,成功地将原来的两次查询优化为一次。扩展四则运算的另外一个目的是可以“通过计算换取存储”,例如需要将两种类型加总成总和的类型数据,可以只存储两份,加总数据“通过计算换取”。除了数据读取,数据的写入也可以进行类似合并数据的优化,例如,腾讯分析在写入url的PV、UV、VV、IP、停留时长、bounce rate这6个指标时,需要调用6次redis命令,而实际上这6个指标是存储在同一个hash内的,通过扩展hmincrby命令,支持将hash的所有field一次更改,将调用次数优化至一次。上线之后也取得了良好的效果,峰值时的CPU利用率几乎下降了一半,同时也大幅提升了上层模块ESA的吞吐量。

    • n LevelDB
      Redis的有效补充,考虑到redis为内存数据库,而使用内存的成本要高于硬盘,因此选择引入了基于磁盘存储的LevelDB作为补充。LevelDB的写性能足够好,而读性能也远远超过目前“在线少量读取”的需求的。因此我们选择LevelDB存储“固定不变数据”。

    在数据存储的架构设计上,由于实时数据服务与在线系统,可靠性要求较高,因此我们主要采取双写复制+Sharding的设计:

    1.双写复制

    所有的数据存储都会至少同步写两份,以此提高在线系统服务的可用性

    2.数据分片Sharding

    l 基于域名

    n 所有的数据以域名为单位组织分片;
    n 任何域名可以调整到任意分片中;
    n 单个域名数据原则上存储在一个分片中;

    l 动态调整

    n 只调整分片策略,不移动数据;
    n 基于数据量计算分片负载;

    此外,针对分片集群数据的查询,我们主要做了三项工作:

    n 实现了一个较为完整的Redis协议栈作为上层应用的基础,设计是直接用redis协议作为对外提供的查询通用协议,这样外部用户可以直接通过目前各种Redis Client实现来查询访问数据;

    n 一个灵活的查询引擎:能够根据规则智能的在多个Redis、LevelDB数据源中查询,执行类join的操作;也简单扩展支持其它的异构数据源如Mysql、Hbase等

    n 一个实时查询计算引擎:一些复杂的查询,实时根据基础查询结果实时计算。引入此部分的主要目的在于减少Redis数据空间占用。

    未来展望

    目前腾讯分析虽然在后台上已经做到数据秒级更新,但展示方式仍为传统的静态方式。后续腾讯分析会在数据的动态刷新上进行更多尝试,让站长可以第一时间了解网站营销效果,时刻感受网站心跳。让腾讯分析持续带给站长价值!

  • 相关阅读:
    推荐一个博客,或许给技术流的自己一些启示
    Boost多线程-替换MFC线程
    Python:Matplotlib 画曲线和柱状图(Code)
    AI:机器人与关键技术--总是被科普
    OnLineML一:关于Jubatus 的简介...
    使用PCL::GPU::遇到问题
    dll文件:关于MFC程序不能定位输入点
    实践:使用FLANN.LSH进行检索
    模式识别两种方法:知识和数据
    几个方便编程的C++特性
  • 原文地址:https://www.cnblogs.com/purpleraintear/p/6184160.html
Copyright © 2011-2022 走看看