携程机票日志追踪系统架构演进

1,390 阅读6分钟
原文链接: mp.weixin.qq.com

作者简介

 

许鹏,携程高级研发经理,负责机票大数据基础平台的构建和运维。

机票业务看起来简单,实际上整个流程的处理链条很长,调用关系也非常复杂,上下游涉及的各类日志种类约60个,每种日志都有独立格式和请求/响应报文,日生产的日志数据量约50-100亿,如果时间范围再扩大到15天,数据量轻松的达到千亿级以上。

如何在海量的数据中提取想要的数据,这不是一件容易的事情。在大多数情况下,我们需要一种稳定而快速的架构,帮助我们在资源和性能之间获得平衡,于是我们开始了探索之旅。

一、初始架构

1.1  ElasticSearch

首先需要解决存储和查询的问题,海量的数据需要存储起来,供查询使用。如何有效的存储和查询这些日志数据,是系统设计时要回答的首要问题。

日志数据存储的特点和要求:

  • 支持海量写入,TPS要能够支撑>50K/s

  • 支持灵活的schema

  • 支持灵活的数据查询,响应时间要尽可能短,时延<5s

  • 对于过期的数据,支持海量删除

按照以上指标,我们对市面上的产品进行摸底和预研,选定了三种存储方式来进行对比:Cassandra、HBase、ElasticSearch。

1.1.1  Cassandra

Cassandra支持海量的数据写入,但是查询字段单一,同时对于数据删除不够友好,不支持行级别的TTL。当有大量的cell过期后,很容易出现TombStone的问题,并且在数据定期清理的过程中,很容易出现数据写入超时等现象。

1.1.2  HBase

1)HBase支持海量数据写入,在过期数据处理层面,不容易产生Cassandra才有的TombStone现象。但在查询接口层面,需要调用api才行,使用难度较高,尽管引入apache phoenix可以通过SQL来进行查询,但这增强了系统解决方案的复杂度。

2)HBase对于Row Key的查询能够快速返回,如果变更查询条件,响应会下降非常明显。

1.1.3  Elasticsearch

在排除了Cassandra和HBase之后,开始尝试Elasticsearch,通过研究发现,Elasticsearch可以很好的满足我们的需求:

  • 支持灵活的数据结构,支持schemaless

  • 可以通过水平扩展来支持海量的数据写入

  • 查询方式灵活,响应时间短,平均查询响应低于<1s

  • 结合别名和每天创建新索引,可以很好的移除过期数据,同时操作过程对用户透明

1.2  Kafka

Kafka作为消息队列,在存储日志数据的同时,隔离开数据产生的应用和数据处理流程。

1.3  ETL

为了把海量日志从Kafka近实时的导入到Elasticsearch,我们采用spark来进行处理,当前数据导入延迟不超过5s。

1.4  全局ID

每一次用户会话请求会被赋予一个单独的全局ID(TransactionID),这个全局ID会在各个模块之间的消息传递中出现。通过这样一个全局ID,开发人员可以追踪请求在整个链路中的处理情况。

各开发模块将含有全局ID的日志信息存储到Kafka集群中。

二、架构演进

第一代架构采用Elasticsearch解决了日志存储的问题,单日志查询的表现令人满意。

在实际系统使用过程中发现,由于机票日志种类繁多, 同时对50个以上日志并行查询会导致ElasticSearch集群整体状态变黄甚至变红,集群变的不稳定,整体反应速度变得非常缓慢。

硬件扩容Or提升性能,在架构层次需要进行决策,扩容能够解决一些问题,但是对于携程机票而言,后续还会有更多的日志接入,架构层面必须均衡资源和性能的平衡,而不是单纯的硬件扩容,我们决定在架构层面进一步演进来提升性能。

2.1  增加二级索引

通过分析,发现由于Elasticsearch会保存最近15天的日志,如果针对每一个TransactionID,都去查询15天的所有日志,那么查询响应时间会变得缓慢。

实际上每一个TransactionID不可能都存在于60多种日志中,做了很多多余的查询,如果能够精确的查询就好了。

为了增强查询的精确性,我们采用只对存有TransactionID的索引进行查询,我们建立了二级索引,通过二级索引,可以将TransactionID映射到一到多个具体的Elasticseaerch索引,然后对这些索引发起查询请求,获取详情信息。

也就是说,我们建立了索引,在查询前能准确的知道一个TransactionID在哪些日志、哪些日期中存在。

这样可以准确的查询这些日志,去掉不需要查询的日志。

通过二级索引的设置,查询速度获得很大的提升,由原来的20-30秒提升到5秒以内。

2.2  冷热数据分离

二级索引的建立解决了很大一部分问题,随着而来又产生了新的问题。

每天的二级索引数据量高达5亿条,随着时间推移二级索引数据量迅速增长,查询速度出现了抖动甚至大幅度下降,二级索引本身变成了瓶颈。

对二级索引我们再次做出了优化,对冷热数据进行切割,当天的二级索引会存储到redis中,因为系统使用中发现,用户一般对于当天的请求处理情况关注的比较多。Redis可以在5ms以内返回二级索引结果。

对于历史的二级索引,会将信息从Redis导入到Elasticsearch中。

三、小结

目前,机票日志追踪系统仍然在不断的、持续的演进中,比如最新的二级索引中冷数据不再存储到ElasticSearch,而是存储在codis集群中,ETL我们采用更快更好的批量灌入方式等等。

随着大数据技术的不断发展和进步,相信我们的架构也会不断的升级换代,架构的升级必然带来效能的提升,这就是技术的魅力所在。

我们始终相信,架构没有最好,只有更好。

【推荐阅读】