11 月 19 - 20 日 Apache Pulsar 社区年度盛会来啦,立即报名! 了解详情
写点什么

面对百亿用户数据,日均亿次请求,携程应用架构如何涅槃?

  • 2016-10-07
  • 本文字数:4805 字

    阅读完需:约 16 分钟

互联网二次革命的移动互联网时代,如何吸引用户、留住用户并深入挖掘用户价值,在激烈的竞争中脱颖而出,是各大电商的重要课题。通过各类大数据对用户进行研究,以数据驱动产品是解决这个课题的主要手段,携程的大数据团队也由此应运而生;经过几年的努力,大数据的相关技术为业务带来了惊人的提升与帮助。

以基础大数据的用户意图服务为例,通过将广告和栏位的“千人一面”变为“千人千面”,在提升用户便捷性,可用性,降低费力度的同时,其转化率也得到了数倍的提升,体现了大数据服务的真正价值。

在新形势下,传统应用架构不得不变为大数据及新的高并发架构,来应对业务需求激增及高速迭代的需要。

一、业务高速发展带来的应用架构挑战

公司业务高速发展带来哪些主要的变化,以及给我们的系统带来了哪些挑战?

  1. 业务需求的急速增长,访问请求的并发量激增,2016 年 1 月份以来,业务部门的服务日均请求量激增了 5.5 倍
  2. 业务逻辑日益复杂化,基础业务研发部需要支撑起 OTA 数十个业务线,业务逻辑日趋复杂和繁多。
  3. 业务数据源多样化,异构化,接入的业务线、合作公司的数据源越来越多;接入的数据结构由以前的数据库结构化数据整合转为 Hive 表、评论文本数据、日志数据、天气数据、网页数据等多元化异构数据整合。
  4. 业务的高速发展和迭代,部门一直以追求以最少的开发人力,以架构和系统的技术优化,支撑起携程各业务线高速发展和迭代的需要。

在这种新形势下,传统应用架构不得不变,做为工程师也必然要自我涅槃,改为大数据及新的高并发架构,来应对业务需求激增及高速迭代的需要。计算分层分解、去 SQL、去数据库化、模块化拆解的相关技改工作已经刻不容缓。

以用户意图(AI 点金杖)的个性化服务为例, 面对 BU 业务线的全面支持的迫切需要,其应用架构必须解决如下技术难点

  1. 高访问并发:每天近亿次的访问请求;
  2. 数据量大:每天 TB 级的增量数据,近百亿条的用户数据,上百万的产品数据;
  3. 业务逻辑复杂:复杂个性化算法和 LBS 算法;例如:满足一个复杂用户请求需要大量计算和 30 次左右的 SQL 数据查询,服务延时越来越长;
  4. 高速迭代上线:面对 OTA 多业务线的个性化、Cross-saling、Up-saling、需满足提升转化率的迫切需求,迭代栏位或场景要快速,同时减少研发成本。

二、应对挑战的架构涅磐

面对这些挑战,我们的应用系统架构应该如何涅磐?主要分如下三大方面系统详解:

存储的涅磐,这一点对于整个系统的吞吐量和并发量的提升起到最关键的作用,需要结合数据存储模型和具体应用的场景。

计算的涅磐,可以从横向和纵向考虑:横向主要是增加并发度,首先想到的是分布式。纵向拆分就是要求我们找到计算的结合点从而进行分层,针对不同的层次选择不同的计算地点。然后再将各层次计算完后的结果相结合,尽可能最大化系统整体的处理能力。

业务层架构的涅磐,要求系统的良好的模块化设计,清楚的定义模块的边界,模块自升级和可配置化。

三、应用系统的整体架构

认识到需要应对的挑战,我们应该如何设计我们的系统呢,下面将全面的介绍下我们的应用系统整体架构。

下图就是我们应用系统整体架构以及系统层次的模块构成。

数据源部分, Hermes 是携程框架部门提供的消息队列,基于 Kafka 和 Mysql 做为底层实现的封装,应用于系统间实时数据传输交互通道。Hive 和 HDFS 是携程海量数据的主要存储,两者来自 Hadoop 生态体系。Hadoop 这块大家已经很熟悉, 如果不熟悉的同学只要知道 Hadoop 主要用于大数据量存储和并行计算批处理工作。

Hive 是基于 Hadoop 平台的数据仓库,沿用了关系型数据库的很多概念。比如说数据库和表,还有一套近似于 SQL 的查询接口的支持,在 Hive 里 叫做 HQL,但是其底层的实现细节和关系型数据库完全不一样,Hive 底层所有的计算都是基于 MR 来完成,我们的数据工程师 90% 都数据处理工作都基于它来完成。

离线部分,包含的模块有 MR, Hive , Mahout, SparkQL/MLLib。Hive 上面已经介绍过,Mahout 简单理解提供基于 Hadoop 平台进行数据挖掘的一些机器学习的算法包。Spark 类似 hadoop 也是提供大数据并行批量处理平台,但是它是基于内存的。SparkQL 和 Spark MLLib 是基于 Spark 平台的 SQL 查询引擎和数据挖掘相关算法框架。我们主要用 Mahout 和 Spark MLLib 进行数据挖掘工作。

调度系统 zeus,是淘宝开源大数据平台调度系统,于 2015 年引进到携程,之后我们进行了重构和功能升级,做为携程大数据平台的作业调度平台。

近线部分,是基于 Muise 来实现我们的近实时的计算场景,Muise 是也是携程 OPS 提供的实时计算流处理平台,内部是基于 Storm 实现与 HERMES 消息队列搭配起来使用。例如,我们使用 MUSIE 通过消费来自消息队列里的用户实时行为,订单记录,结合画像等一起基础数据,经一系列复杂的规则和算法,实时的识别出用户的行程意图。

后台 / 线上应用部分,Mysql 用于支撑后台系统的数据库。ElasticSearch 是基于 Lucene 实现的分布式搜索引擎,用于索引用户画像的数据,支持离线精准营销的用户筛选,同时支持线上应用推荐系统的选品功能 。Hbase 基于 Hadoop 的 Hdfs 上的列存储 Nosql 数据库,用于后台报表可视化系统和线上服务的数据存储。

这里说明一下, 在线和后台应用使用的 ElasticSearch 和 Hbase 集群是分开的,互不影响。 Redis 支持在线服务的高速缓存,用于缓存统计分析出来的热点数据。

四、推荐系统案例

介绍完我们应用系统的整体构成, 接下来分享基于这套系统架构实现的一个实例——携程个性化推荐系统。

推荐系统的架构图:

1 存储的涅磐

1)Nosql (Hbase+Redis)

我们之前存储使用的是 Mysql, 一般关系型数据库会做为应用系统存储的首选。大家知道 Mysql 非商业版对分布式支持不够,在存储数据量不高,查询量和计算复杂度不是很大的情况下,可以满足应用系统绝大部分的功能需求。

我们现状是需要安全存储海量的数据,高吞吐,并发能力强,同时随着数据量和请求量的快速增加,能够通过加节点来扩容。另外还需要支持故障转移,自动恢复,无需额外的运维成本。综上几个主要因素,我们进行了大量的调研和测试,最终我们选用 Hbase 和 Redis 两个 Nosql 数据库来取代以往使用的 Mysql,。我们把用户意图以及推荐产品数据以 KV 的形式存储在 Hbase 中,我对操作 Hbase 进行一些优化,其中包括 rowkey 的设计,预分配,数据压缩等, 同时针对我们的使用场景对 Hbase 本身配置方面的也进行了调优。目前存储的数据量已经达到 TB 级别,支持每天千万次请求,同时保证 99% 在 50 毫秒内返回 。

Redis 这块和多数应用系统使用方式一样,主要用于缓存热点数据,这里就不多说了。

2)搜索引擎 (ElasticSearch)

ES 索引各业务线产品特征数据,提供基于用户的意图特征和产品特征复杂的多维检索和排序功能,当前集群由 4 台大内存物理机器构成,采用全内存索引。对比某一个复杂的查询场景, 之前用 Mysql 将近需要 30 次查询,使用 ES 只需要一次组合查询且在 100 毫秒内返回 。目前每天千万次搜索,99% 以上在 300 毫秒以内返回。

2 计算的涅磐

1)数据源,我们的数据源分结构化和半结构化数据以及非结构化数据。

结构化数据主要是指携程各产线的产品维表和订单数据,有酒店,景酒,团队游,门票,景点等;还有一些基础数据,比如城市表,车站等,这类数据基本上都是 T+1。每天会有流程去各 BU 的生产表拉取数据。

半结构化数据是指,携程用户的访问行为数据,例如浏览,搜索,预订,反馈等,这边顺便提一下,这些数据这些是由前端采集框架实时采集,然后下发到后端的收集服务,由收集服务在写入到 Hermes 消息队列,一路会落地到 Hadoop 上面做长期存储,另一路近线层可以通过订阅 Hermes 此类数据 Topic 进行近实时的计算工作。

我们还用到外部合作渠道的数据,还有一些评论数据,评论属于非结构化的,也是 T+1 更新。

2)离线计算,主要分三个处理阶段 。

预处理阶段,这块主要为后续数据挖掘做一些数据的准备工作,数据去重,过滤,对缺失信息的补足。举例来说采集下来的用户行为数据,所含有的产品信息很少,我们会使用产品表的数据进行一些补足,确保给后续的数据挖掘使用时候尽量完整的。

数据挖掘阶段,主要运用一些常用的数据挖掘算法进行模型训练和推荐数据的输出 (分类,聚类,回归 ,CF 等)。

结果导入阶段,我们通过可配置的数据导入工具将推荐数据,进行一系列转换后,导入到 HBASE,Redis 以及建立 ES 索引, Redis 存储的是经统计计算出的热点数据 。

3)近线计算(用户意图, 产品缓存)

当用户没有明确的目的性情况下,很难找到满足兴趣的产品,我们不仅需要了解用户的历史兴趣,用户实时行为特征的抽取和理解更加重要,以便快速的推荐出符合用户当前兴趣的产品,这就是用户意图服务需要实现的功能。

一般来说用户特征分成两大类:一种是稳定的特征(用户画像),如用户性别,常住地,主题偏好等特征;另一类是根据用户行为计算获取的特征,如用户对酒店星级的偏好,目的地偏好,跟团游 / 自由行偏好等。基于前面所述的计算的特点,我们使用近在线计算来获取第二类用户特征,整体框图如下。从图中可以看出它的输入数据源包括两大类:第一类是实时的用户行为,第二类是用户画像,历史交易以及情景等离线模块提供的数据。结合这两类数据,经一些列复杂的近线学习算法和规则引擎,计算得出用户当前实时意图列表存储到 Hbase 和 Redis 中。

携程用户意图框架

近线另一个工作是产品数据缓存,携程的业务线很多,而我们的推荐系统会推各个业务线的产品,因此我们需要调用所有业务线的产品服务接口,但随着我们上线的场景的增加,这样无形的增加了对业务方接口的调用压力。而且业务线产品接口服务主要应用于业务的主流程或关键型应用,比较重,且 SLA 服务等级层次不齐,可能会影响到整个推荐系统的响应时间。

为了解决这两个问题,我们设计了近在线计算来进行业务的产品信息异步缓存策略,具体的流程如下。

我们会将待推荐的产品 Id 全部通过 Kafka 异步下发,在 Storm 中我们会对各业务方的产品首先进行聚合,达到批处理个数或者时间 gap 时,再调用各业务方的接口,这样减少对业务方接口的压力。通过调用业务方接口更新的产品状态临时缓存起来(根据各业务产品信息更新周期分别设置缓存失效时间),在线计算的时候直接先读取临时缓存数据,缓存不存在的情况下,再击穿到业务的接口服务。

4)在线计算(2 个关键业务层架构模块介绍)

1,业务层架构 - 数据治理和访问模块,支持的存储介质,目前支持的存储介质有 Localcache,Redis,Hbase,Mysql 可以支持横向扩展 。统一配置,对同一份数据,采用统一配置,可以随意存储在任意介质,根据 id 查询返回统一格式的数据,对查询接口完全透明。

穿透策略和容灾策略,Redis 只存储了热数据,当需要查询冷数据则可以自动到下一级存储如 Hbase 查询,避免缓存资源浪费。当 Redis 出现故障时或请求数异常上涨,超过整体承受能力,此时服务降级自动生效,并可配置化。

2,业务层架构 - 推荐策略模块,整个流程是先将用户意图、用户浏览,相关推荐策略生成的产品集合等做为数据输入,接着按照场景规则,业务逻辑重新过滤,聚合、排序。最后验证和拼装业务线产品信息后输出推荐结果;

我们对此流程每一步进行了一些模块化的抽象,将重排序逻辑按步骤抽象解耦,抽象如右图所示的多个组件,开发新接口时仅需要将内部 DSL 拼装便可以得到满足业务需求的推荐服务;提高了代码的复用率和可读性,减少了超过 50% 的开发时间;对于充分验证的模块的复用,有效保证了服务的质量。

作者介绍

董锐,近 9 年的互联网从业经验。2013 年 1 月加入携程,曾在商业智能部设计和开发基于 HADOOP 生态体系的大数据数据仓库。现任基础业务研发部 - 数据智能应用组研发 Leader,专注于携程个性化推荐系统,ABTEST 等系统研发工作。


感谢杜小芳对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-10-07 17:286271

评论

发布
暂无评论
发现更多内容

从字节跳动到火山引擎(二):私有云 PaaS 场景下的 Kubernetes 集群部署实践

字节跳动 云原生 #Kubernetes# 火山引擎

区块链电子印章平台--加速政务数字化

13530558032

百度大规模Service Mesh落地实践

百度开发者中心

百度 service

如何画好架构图

MonkeyZz

百度后端二面有哪些内容,万字总结(一)

我是阿沐

MySQL 面试 索引结构 索引优化

Swift在淘系的工程化应用和实践

阿里巴巴淘系技术

swift 大前端 编程语言 WWDC21

线程与线程池的那些事之线程池篇(万字长文)

秦怀杂货店

线程 线程池 并发

新华三亮相未来网络发展大会 共启国家重大科技基础设施(CENI)开放合作

科技热闻

slate-angular 正式开源

PingCode研发中心

angular.js 开源 angular

原以为哈夫曼树、哈夫曼编码很难,结果大佬用6张图就讲明白了

Java架构师迁哥

微信小游戏直播在Android端的跨进程渲染推流实践

JackJiang

微信 即时通讯 直播技术

案例 | 低代码助力生产制造业,扫平数字化升级“死角”!

优秀

低代码 生产管理系统

进击的云原生,为开发者提供更多可能性

阿里巴巴云原生

如何做好业绩管理?

石云升

职场经验 管理经验 6月日更

网络攻防学习笔记 Day51

穿过生命散发芬芳

网络攻防 6月日更

我看JAVA 之 线程同步(上)

awen

Java synchronized 管程

GraphQL 入门指南

PingCode研发中心

开发者 graphql

如何在 Vue 的计算属性中传递参数

devpoint

Vue vue2 6月日更

5分钟速读之Rust权威指南(二十六)Drop

码生笔谈

rust

从字节跳动到火山引擎(三):替换 Spring Cloud,使用基于 Cloud Native 的服务治理

字节跳动 微服务 云原生 Spring Cloud 火山引擎

联邦计算在百度观星盘的实践

百度开发者中心

百度 联邦计算

从最难的而立之年走来,三十而已 —— 2021 年中总结

清秋

成长与思考 年中总结

工信部发文将整治涉诈电话卡:打击网络诈骗必须釜底抽薪

石头IT视角

Redis入门三:事务

打工人!

redis 事务 6月日更

2021春招面试经历,阿里3轮技术面+交叉3面(已成功拿到offer)

Java 程序员 架构 面试

Flink Checkpoint 和 Large State 调优

Alex🐒

flink 翻译 flink1.13

一文带大家,认识DPDK基础,踏上网络高级编程之路

奔着腾讯去

c++ 计算机网络 TCP/IP 网络层 网络io

分布式事务框架seata落地实践

有道技术团队

分布式 大前端

欧洲杯与618:“夏季限定”MVP诞生记

脑极体

Flink State 和 Fault Tolerance(四)

Alex🐒

flink flink1.13

珠宝正品溯源平台,区块链珠宝溯源方案

13530558032

面对百亿用户数据,日均亿次请求,携程应用架构如何涅槃?_架构_董锐_InfoQ精选文章