机票垂直搜索引擎的性能优化

机票垂直搜索引擎的性能优化
原文:机票垂直搜索引擎的性能优化

一、行业背景与垂直搜索

我们先了解一下机票的行业背景,下图是由中航信统计的数据,蓝色的曲线代表平均每公里的票价,红色曲线指的是客运量。从2011年到2016年,无论是国内、港澳台还是国际,整体趋势都是机票价格便宜了,坐飞机的人也越来越多了。特别是国际机票,这五年里机票价格下降30%,客运量增长了140%。

乘客越来越多,购买机票的渠道有哪些呢?现在主要有三个:网络平台、代售点和航司官网。像携程、去哪儿、飞猪、同程等,是主流的网络购票平台;像旅行社这类代售点,是旅行团的主要购票渠道;同时大部分航空公司的官网也可以购票,而且有相对较低的价格。总体来说,网络平台是最大的销售渠道,占比76%。为什么网络平台占有这么大的份额呢,主要原因是机票垂直搜索引擎是主要的用户流量入口,用户一般是先比价然后再去预订,一个好的机票搜索引擎查询的产品丰富、价格便宜,而且响应速度快,运价也准,这些特性在技术方面实现好并不容易。

二、主要问题与解决方案

机票查询要快、准、低。快是指查询快,能够提供一个良好的用户体验;准是指运价准,可以保证出票的成功率;低是指票价低,能够吸引更多的用户。但是,如果票价要有优势,就要有大量产品,产品数据多了查询就慢,如果查询要快,就必须要缓存,但是数据缓存了,运价就可能不准。这三者是矛盾的,类似于CAP原则,具体示意图如下:

对于以上问题,怎么解决呢?通用的三个技术方案有:一、用DB+Redis平衡响应速度、数据实时性和查询成本;二、用削峰填谷的MQ来处理高并发;三、将业务服务化、模块解耦。这些只是通用的技术点,并没有什么难度,我们这里重点介绍与最终结果密切相关的四个模块:静态数据、缓存策略、实时查询、政策匹配。

  1. 静态数据:能静态处理的数据尽量静态化,存储到本地,可以是数据库或缓存,以方便快速地查询,如航班信息、运价数据和政策数据等;
  1. 缓存策略:从中航信拿到运价数据之后,进行热冷门数据分类,数据永不过期但持续更新,自主控制数据的更新频率;
  1. 实时查询:多渠道多供应实时获取远端数据,多数据源查询速度会变慢,远端服务不可控,解决方案是三段超时,即前端用户超时、中端运营超时、后端供应超时;
  1. 政策匹配:大量的产品数据和大量的业务规则,不可能都提供给用户,需要通过一定的算法进行匹配过滤、排序等。
三、静态数据与任务打底

机票查询的静态数据主要有:城市、机型、航司、运价数据等,这里重点介绍较为复杂的运价数据,运价数据的获取虽然间隔时间较长,但数据量大且更新频次不同。运价数据是由中航信统一提供的,有两种途径:黑屏查询和IBE接口,将获取到的数据保存到数据库和缓存中,用户查询的时候直接从缓存中获取,同时也会按照一定的缓存策略来更新。

最初我们设计了两套方案来打底运价数据,两个方案各有优劣。方案1是先预加载所有的运价数据,然后全部保存到数据库和缓存,然后在航班查询时通过缓存策略进行相应地更新;方案2是把运价数据根据航线查询频率分为热门和冷门数据,然后每天凌晨对热门数据预加载,并在航班查询的时候对冷门数据进行更新。可以看出,方案1能保证数据的完整性和实时性,但预加载用时太长;方案2能控制预加载用时,但热门数据的实时性会从早到晚逐渐降低。两个方案中都需要实时更新,在考虑数据实时性的同时,还要考虑获取数据的费用,平衡好两者才是一个实用的方案。

综合对比之后,我们采用了方案1,具体实现如下图所示:首先是通过Job对运价数据的初始化,然后以任务消息的方式发送给MQ,MQ里的消息会被后台服务自动消费,执行消息队列里的任务,把运价数据保存到数据库和缓存。数据预加载之后,用户在前台查询时,如果缓存里面没有数据,或者查到的缓存数据是过期的,系统会自动发一条任务消息给MQ,或者人工配置指定的航线定时更新,Job也会自动发送任务消息给MQ,前台和后台的消息被服务消费以实现数据的更新。用户的不断请求和后台指定的任务,保证数据的持续更新,时间越久数据的准确性越高,用户查询的命中率也会越来越高。

四、缓存策略与数据一致

上面说到运价数据同时存储在数据库和缓存,为什么有了缓存还要数据库呢?存储到数据库是为了方便数据的多维查询和管理,包括对缓存的进一步干预。数据库查询的功能强大,但速度慢,缓存的性能好,但从缓存里获取的数据,会有不准确的问题。怎么才能做到查询快而且数据准呢?我们的解决方法是缓存永不失效、数据分类、自主控制更新频率,以实现运价数据的又快又准。

我们根据航线查询的频率,将可以分成热门数据、冷门数据和没有数据,航班多、查询多的是热门数据,航班少、查询少的是冷门数据,查询不到就是没有数据。在预加载或更新运价数据时,将缓存设置为一个较长时间或永不过期,然后在前台访问时,不同数据类型采用不同的更新策略,具体如下:

  • 热门航线查询,在缓存中获取数据,数据中有一个自己的缓存时间字段,然后根据这个时间来分别处理:
  • 1小时之内更新的:新鲜度较高,可以直接用;
  • 1-6小时之内更新的:预警n次,第n+1次命中时则异步更新运价;
  • 6小时之外更新的:新鲜度太低,异步更新运价;
  • 冷门航线查询,与热门航线一样,只是不预加载且缓存时间稍长:
  • 12个小时之内更新的:新鲜度较高,可以直接用;
  • 12-48个小时之内更新的:预警n次,第n+1次命中时则异步更新运价;
  • 48个小时之外更新的:新鲜度太低,异步更新运价;
  • 缓存没有数据时,直接获取最新运价,同时更新数据库和缓存。

以上无论是预警后更新还是直接更新,都是先把缓存中数据返回给用户,同时异步更新数据库和缓存。虽然有存在数据查询不准确的概率,但被用户再次查询时就准确了。查询到的数据即便不准确,在后继的航班预订时也会二次的验舱验价,运价数据和库存数据会再次更新。用户不断地查询,数据不断地更新,查询命中率就会越来越高,并且用的人越多情况会越好,会逐步趋近于n个9。

五、实时查询与三段超时

能静态化的数据我们要尽量静态化,但远端数据的实时查询还是必不可少。实时查询如何做到又快又好呢,特别是多数据源、多供应商的实时查询场景。我们的国际机票查询就是这样,前台页面点击查询时实时调用供应商接口,早期我们仅调用一个供应接口,产品比较单一,数据不够丰富,后面我们引入了多供应商,产品变丰富了,也有了低价,但同时带来了很多新问题,比如供应端接口需要20~30秒,但前端客户只能接受8秒以内,怎么办?提高供应数据门槛?但这不是核心竞争。还有查询速度变慢、外部数据源不可控、数据格式多样等问题。

对于以上问题,我们的解决办法是三段超时,所谓三段超时,即供应端、运营端和客户端。前端满足客人、中间满足运营控制策略、后端满足供应商,三方都要满意,这样才能产品更丰富、价格更低、运营策略更灵活、用户响应更及时。三段超时的时间可以根据具体场景进行配置,具体如下:

  • 供应端超时:供应端是后端,是指提供数据源的一方,供应端存在的问题就是外部不可控。供应端处于数据来源的最底端,解决办法是尽量加大供应端的超时时间限制。我们对请求供应接口的最大HTTP超时时间设置为45秒,这个值可以满足绝大部分情况。
  • 运营端超时:运营端是中间端,把供应商的数据拿过来之后,做包装转换、去重、政策匹配等业务处理。我们先统计每一个供应接口的请求时间,确认供应接口数据的质量和优先级,比如说:A供应数据的质量相比B和C供应数据的质量要高,那么A的请求级别可以设置得高一些。我们优先考虑拿到A供应的数据,如果A的数据在8秒就返回,而B和C的超过这个时间,那么我们此时在前台就只把A的数据返回给客户。对于B和C的数据,由于在HTTP请求时我们采用异步并设置了较大的供应端超时,所以它会在A返回之后,继续异步请求并将返回的数据保存到缓存中,以供用户下次或其他用户使用。当我们拿到了多供应商的产品数据后,这时会有一定重复的数据,需要规范化处理,将不同数据格式转换成统一标准,然后去重并选取最优,最后根据运营策略进行政策匹配等。
  • 客户端超时:客户端是前端,需要处理最终展示和不同终端用户的不同需求。客户端采用多线程异步读取,这样不会影响主线程的速度,同时并发请求,提升响应速度和用户体验。这里指的主线程请求时间,可以理解为在前台终端设备需要等待的时间,比如APP要求8秒钟返回,那就设置8秒时间;如果PC端B2B白屏网页查询,客户可以等待时间为25秒,那么就是设置25秒。客户端的超时时间要大于或等于所有的运营端超时时间,例如客户端超时是25秒,那么运营端线程A的超时可以最大为25秒,但如果线程A的绝大部分航线获取时间是18秒,那么线程B和C的超时最好不要超过18秒,这里的用户体验要综合考虑概率问题。
六、政策匹配与算法优化

弄来这么多产品,不可能都提供给客人,需要根据运营规则来匹配。机票政策就是机票产品的运营控制策略,如上图所示,包括政策类型、客户类型、航程类型、乘客类型、航司、航班、舱位、城市、日期、返点 、定额、Office号等多种属性。为什么有这么多属性呢?因为机票产品的运营规则很复杂,而这种规则的复杂性,直接导致在航班查询的时候,机票政策的匹配也很复杂的。对于这种大数据、复杂业务规则的数据处理,需要有一套专门的政策匹配算法,具体如下:

第一步是直接从数据库查政策,在前端查询的时候,根据查询的条件,如出发到达城市、日期等,从数据库中大范围的获取政策数据,并把这些数据放到内存中。第二步在内存中对每个产品进行政策匹配即过滤,先将每一个属性转化为业务规则如限制城市、排除供应商、航司指定供应商等,一个属性一个类、采用统一的接口,然后增加到政策过滤器中。产品与政策的匹配过程,就像水流过过滤网一样,把最优政策应用到产品上如调整价格。这个过程有些复杂,为此我们编写了一套自己的政策过滤器PolicyFilter框架。第三步是按照政策返点高低进行排序。第四步是将最优政策返回给前台。以下是部分核心代码的演示:

七、小结

机票垂直搜索性能优化不仅仅适合于机票行业,也适合于其它垂直行业,在垂直搜索引擎方面有一定的通用性,只要它存在:远端数据获取、静态数据、缓存更新、规则匹配、多数据源等问题,都是类似解决方案。垂直搜索主要有四把刷子。第一把刷子是静态数据与任务打底。第二把刷子是缓存与更新,保持数据的新鲜度,不仅要快,还要准。第三把刷子是实时查询与三段超时,多供应商多数据源,供应商要20秒,客户只能接受3秒,怎么办?解决办法是三段超时。第四刷子是政策匹配,好不容易弄来这么多产品,不可能都直接显示给客人,需要根据运营规则进行匹配。以上,每一个具体的技术可能并不复杂,但把它们综合起来,解决具体的实际问题,为公司为行业带来价值,并不是件容易的事。技术的核心价值在于技术的应用,技术价值要借助技术应用和产品才能发挥出来,这比单纯的技术学习要有意思得多,希望以上能应用到你具体的工作中。

 

posted on 2019-02-13 15:00 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10369891.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395184.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2015国内征信机构大数据整合能力对比

自2001年起,大陆地区现代企业征信业进入在竞争中发展的阶段,信用问题开始得到社会各界的广泛关注,许多政府和民间投资的企业征信机构携带大量资本如雨后春笋般出现。 随着企业征信行业环境不断改善,信息透明度低的问题日益凸显。大…

Unity3D 装备系统学习Inventory Pro 2.1.2 基础篇

前言 前一篇 Unity3D 装备系统学习Inventory Pro 2.1.2 总结 基本泛泛的对于Inventory Pro 这个插件进行了讲解,主要是想提炼下通用装备系统结构和类体系。前两天又读了另一个插件 C# Inventory-uGui v2.0.1的源码(应该也是老外写的)&#xf…

Java项目问题_Java项目出现的问题01----学习

0 运行环境MyEcplise2016Tomcat8.01今天在html的表格提交跳转时发现,想要提交到自己写servlet程序中,却发现总是出错http://localhost:8080/Test4/Test4/fail.html多出一个项目路径/Test4,但是程序没有任何问题,最后发现是在Ecpli…

express-cli入门_使用Express.js入门

express-cli入门by Victor Ofoegbu由Victor Ofoegbu 使用Express.js入门 (Getting off the ground with Express.js) 使用Node.js框架编写Web应用 (Writing web apps with the Node.js framework) A common moment of truth is when you develop a lot of applications that n…

《疯狂前端开发讲义jQuery+Angular+Bootstrap前端开发实践》学习笔记

《疯狂前端开发讲义jQueryAngularBootstrap前端开发实践》学习笔记 二〇一九年二月十三日星期三2时28分54秒 前提:本书适合有初步HTML、CSS、JavaScript基础的读者,或对企业应用前端开发不太熟悉的开发人员。 第1章:前端开发与Ajax技术 要点&…

混合云:公共云和私有云之间取得平衡的方式?

在可预见的未来,混合云是现实的,但真正的收获是试图找出企业最终朝向公共或私人资源是否平衡。 你在与任何技术供应商沟通时,也许会涉及到数据中心,但大多会提到云计算的三种方式:私有云,公共云&#xff0c…

腾腾流氓,云云更流氓(问微信怎样接入支付宝支付),手贱的赶紧点,你会感谢我的...

草原上的两匹马! 打从当年微信开始布局公众号之初时,估计就已经想到了与支付宝正面冲突的场面,所以微信先来个瞒天过海,在春晚搞了个微信红包,那叫一个火呀,此时的云云隐隐感觉到些许不安。 早期的微信开发…

java中的string是什么_什么是String

2017-07-28String和StringBufString namenew String("HuangWeiFeng");System。out。println(name"is my name");看似已经很精简了,其实并非如此。为了生成二进制的代码,要进行如下的步骤和操作:(1) 生成新的字符串 new S…

详解华为与三星专利之争 律师称可能会打持久战

华为技术有限公司(下称“华为”)起诉三星,在近期中国企业起诉外企的“潮流”中掀起不小的漩涡。 “叫好声”认为,这是已经拥有专利积累的中国企业在国际舞台上的一次“实力亮相”,这件事本身就是中国制造业的胜利;“阴谋论者”认为…

租金 预测_如何预测租金并优化租赁期限,从而节省资金

租金 预测by Zhen Liu刘震 如何预测租金并优化租赁期限,从而节省资金 (How to Predict Rent and Optimize Your Lease Duration So You Can Save Money) In my last post, we talked about how to pick the best month to sign the lease based on seasonality. No…

java system load_关于java的System.load 和 System.loadLibrary

关于两者的区别(参见http://blog.csdn.net/ring0hx/article/details/3242245)System.load 参数为库文件的绝对路径,可以是任意路径。System.loadLibrary方法load的为相对路径,即在java.library.path定义下的lib文件,文件名会更具不同的系统实…

东进技术南亚创捷

深圳市东进技术在其海外市场拓展中取得又一骄人战绩,于四月下旬与印度One97通信公司签订了长期战略合作协议,One97将全面采用东进的全系列产品。同时签订的一期采购计划,总装机端口数约3万线。该合约主要涉及东进技术的领先主打产品——Keygo…

如何在5分钟内通过身份验证构建RESTful API —全部从命令行(第1部分)

by Niharika Singh由Niharika Singh 如何在5分钟内通过身份验证构建RESTful API —全部从命令行(第1部分) (How to Build a RESTful API with Authentication in 5 minutes — all from your command line (Part 1)) If the title of this article excites you, then my frien…

MD5与SHA1

一、MD5 MD5消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信…

java基本类型的默认值及其取值范围

转载于:https://www.cnblogs.com/billyu/p/5843845.html

tair client java_TFS(Taobao File System)Java Client 使用经验

TFS Java客户端的说明tfs-client-java版本选择:---------------------------------------tfs-client-java的版本有:release-2.0.0/tfs-with-large-2.1.1/tfs-client-java-2.1.3/release-2.2.2/release-2.2.3/release-2.2.4/release-2.2.6/最终我选用了tf…

Nutanix公布财报数据 准备IPO前表现抢眼

Nutanix已经向美国证券交易委员会提交了修订的S-1 IPO文件,其中的数据显示,Nutanix凭借着强力增长的业务为IPO做好了准备。 Nutanix公布财报数据 准备IPO前表现抢眼 Nutanix CEO Dheeraj Pandey Nutanix最新的财报数据无论从环比和同比收入增长方面看起来…

DevExpress WinForms使用教程:图表控件 - 内置深入查询

【DevExpress WinForms v18.2下载】在最新发布的DevExpress WinForms v18.2中,DevExpress WinForms和ASP.NET图表控件引入嵌套系列模板的概念,是您能在不编写自定义代码的情况下深入查询图表。 Chart控件的嵌入式痕迹导航元素显示导航层次结构中各个数据…

serverless 构建_使用Serverless,StepFunctions和StackStorm Exchange构建社区注册应用程序-Episode…...

serverless 构建by Dmitri Zimine由Dmitri Zimine 使用Serverless,StepFunctions和StackStorm Exchange构建社区注册应用程序-第3集 (Building a community sign-up app with Serverless, StepFunctions, and StackStorm Exchange — Episode 3) Build a real-worl…

AlfaLaval公司采用低速通风技术冷却数据中心

日前,瑞典热交换专家AlfaLaval公司推出了遵循低速通风原则的一系列数据中心冷却解决方案,其方案需要大量的风扇,而使空气以相当慢的速度流动,取得了与计算机机房空调(CRAC)一样有效的制冷效果。 该公司表示…