一种监控系统的链路跟踪型日志数据的存储设计
软件学报ISSN 1000-9825, CODEN RUXUEW
E-mail:************ Journal of Software ,2021,32(5):1302−1321 [doi: 10.13328/jki.jos.006234]
©中国科学院软件研究所版权所有. Tel: +86-10-62562563
一种监控系统的链路跟踪型日志数据的存储设计
∗ 尤  勇1,  汪  浩2,3,  任  天1,  顾胜晖2,3,  孙佳林1
1
(美团点评,上海  200335) 2
(南京大学 软件学院,江苏 南京  210023) 3(计算机软件新技术国家重点实验室(南京大学),江苏 南京  210023)
通讯作者: 孙佳林,E-mail:**********************
摘  要: 随着软件系统越来越复杂化和分布化,为系统提供具有完善功能的监控服务显得越来越重要.APM (application performance management)系统通过采集软件系统运行时的各项指标数据来分析软件的运行
状态,例如CPU 、内存使用率、垃圾回收的耗时、QPS 等指标.此外,APM 系统也会在软件运行中生成各种日志数据.通常来说,它能提供的监控数据分为3种:指标统计数据、链路跟踪(tracing)数据以及离散事件记录.这些数据有助于系统或者服务的维护人员理解运行状态,从而确保系统或者服务的稳定运行.基于开源的APM 监控系统——CAT 系统,提出了一种针对tracing 类型数据的存储设计方案,通过内存块批量写入的方式提升存储效率,并设计了两级索引以提高查询效率.从线上的真实运行数据来看,该方案在写入性能和查询性能方面均有较好的表现.
关键词: 监控系统;日志存储;两级索引
中图法分类号: TP311 中文引用格式: 尤勇,汪浩,任天,顾胜晖,孙佳林.一种监控系统的链路跟踪型日志数据的存储设计.软件学报,2021,32(5): 1302−1321. /1000-9825/6234.htm
英文引用格式: You Y, Wang H, Ren T, Gu SH, Sun JL. Storage design of tracing-logs for application performance management system. Ruan Jian Xue Bao/Journal of Software, 2021,32(5):1302−1321 (in Chinese). /1000-9825/6234.htm Storage Design of Tracing-logs for Application Performance Management System
YOU Yong 1,  WANG Hao 2,3,  REN Tian 1,  GU Sheng-Hui 2,3,  SUN Jia-Lin 1
1
(Meituan-Dianping Group, Shanghai 200335, China) 2
(Software Institute, Nanjing University, Nanjing 210023, China) 3(State Key Laboratory for Novel Software Technology (Nanjing University), Nanjing 210023, China)
Abstract :  With the software system becoming more and more complex and distributed, it is more and more important to provide monitoring services with complete functions for the system. APM (application performance management) system analyzes the running state of software by collecting various indicator data of software system, such as CPU, memory utilization, the consuming time of garbage collection, QPS. In addition, the APM system can also generate various types of logs during the operation of the software. Generally speaking, it can provide three types of monitoring data: statistic metrics, tracing data, and discrete event records. The data can help the maintenance personnel of the system or service understand the running state, so as to ensure the stable operation of the system or service. Based on the open-source APM monitoring system (i.e., CAT system), this study proposes a storage design scheme for tracing data. It
∗ 基金项目: 国家自然科学基金(62072227, 61802173); 国家重点研发计划(2019YFE0105500); 江苏省政府间双边创新项目(BZ2020017); 计算机软件新技术国家重点实验室(南京大学
)创新项目(ZZKT2019B01)
Foundation item: National Natural Science Foundation of China (62072227, 61802173); National Key Research and Development Program of China (2019YFE0105500); Intergovernmental Bilateral Innovation Project of Jiangsu Province (BZ2020017); Innovation Project of State Key Laboratory for Novel Software Technology (Nanjing University) (ZZKT2019B01)
本文由“面向持续软件工程的微服务架构技术”专题特约编辑张贺教授、王忠杰教授、陈连平研究员和彭鑫教授推荐.
收稿时间: 2020-09-15; 修改时间: 2020-10-26; 采用时间: 2020-12-15; jos 在线出版时间: 2021-02-07
尤勇等:一种监控系统的链路跟踪型日志数据的存储设计1303
improves the storage efficiency by memory block which is designed for batch writing logs, and query efficiency by the structure of the two-level index. Through analyzing the real on-line running data, the proposed scheme has sound performance in both write performance and query performance.
Key words: monitoring system; log storage; two-level indexing
当前,软件系统和服务所处理的业务越来越复杂;相应的,软件系统的规模和复杂度也在逐渐扩大.与此同时,为了支持高可用、高并发以及软件系统演进的同时持续提供系统服务,很多软件系统选择分布式部署的微服务架构,并引入APM(application performance management)系统来对系统的各个服务进行监控.相关监控数据的采集和分析是服务监控的基础,开发人员通过对监控数据的分析,可以实时地了解到软件系统或者服务的运行状态,并且在软件系统或者服务发生异常后,通过诸如指标数据或者日志数据分析出导致异常的原因,进而及时处理故障,恢复服务.显然,分析并处理问题的实时性非常关键,这对监控数据的采集与存储提出了极高的要求.在监控数据中,有一类日志数据,用以记录一个软件系统或者服务运行时的动态行为.此前,大部分日志采集系统采用的都是集中的存储方式,但是随着业务扩大和用户数量的快速增长,日志数据量日渐庞大,再加上为了及时性,还需要支持较高的读写性能,这种集中的数据存储架构越来越难以满足目前很多软件服务监控对日志的存储和读写的要求.所以日志存储系统
同样需要分布式架构才能满足整体的性能要求,通过存储集的方式对外提供日志的存储与查询操作.如果使用现有的HDFS技术来实现日志文件的分布式存储,虽然让存储集的整体性能提高很多,但是它需要对日志文件进行分块,并在集的各个节点上存储副本[1],这样同时也增大了磁盘存储压力.所以,设计一个更轻量的分布式存储架构也同样很有必要.该轻量的分布式架构能够满足日志在存储集中较为均匀地分布,使得存储集整体的性能很高.
CAT[2]是美团开源的用于系统监控的项目,目前被广泛应用于国内多个行业的多个在线系统/服务中.截至2020年6月30日,CAT在著名的开源软件平台GitHub上,同类型项目中的Watch数量(1.2K)、Fork数量(4.4K)、Star数量(13.6K)等均居首位,这充分说明了该监控框架受欢迎的程度.CAT支持多语言客户端,内部定义了多种监控数据类型,Transaction用于记录耗时较长的调用过程、Event用于记录离散简单的事件、Problem用于记录异常、Heartbeat用于记录CPU/JVM等心跳数据.Transaction数据通过嵌套的形式表示调用关系.此外,logs数据同样会在项目的运行中生成.针对被监控服务采用CAT所产生的Transaction类型日志,本文对该类型数据设计了一种存储方案,使用数据文件、索引文件分别存储对应数据,并在此基础上设计了两级索引结构,文中将对该方案的系统架构与索引设计等进行详细的介绍.需要说明的是:本文将要讨论的日志数据为CAT中Transaction类型的监控数据,它同样是一种链路跟踪型(tracing)日志数据,在第1节中会对此类型数据进行介绍.
本文第1节首先针对单条日志的数据格式以及监控数据类型进行说明,提出设计方案面临的难点与挑战.
第2节针对日志数据的特点分析多个现有的存储方式,证明它们并不适合于存储日志;此外,分析两种索引结构的优缺点,并提出本文存储方案的设计要求.第3节对日志存储的设计方案进行详细分析,并指出不足之处.第4节介绍存储方案的性能效果.第5节讨论本文索引结构的优缺点以及对可优化的问题进行说明,并提出适合的解决方案.最后指出未来的工作,并对全文进行总结.
1  介绍
1.1  链路跟踪型日志数据
通常情况下,监控系统会跟踪一次请求中所有的RPC调用和功能模块调用,并记录分布式中的调用节点关系、节点内容的调用路径、部分参数值的等信息,并形成完整的调用链数据,此类型数据即为链路跟踪型数据(tracing数据).Tracing数据是通常意义下的链路跟踪型日志数据,在微服务架构的广泛应用下,各个后端服务节点之间存在大量的相互调用,所以记录一次调用中经过的所有节点、对应的某些参数以及节点内部的功能模块调用,对于系统的运维有着至关重要的作用.在系统或者服务出现异常时,一条完整的tracing数据可以给开发人员提供很好的问题排查依据.相关人员能够根据全链路数据梳理在一次调用中所有节点的依赖关系,从而定位
1304 Journal of Software  软件学报 V ol.32, No.5, May 2021    出现问题的原因.比如,根据链路日志数据可以生成各个模块间的因果关系图(一般是有向无环图),再通过图的相关算法分析出现问题的节点[3−
7].生成Tracing 类型的监控数据有较多的开源技术框架都能实现,例如X-Trace [8]和Dapper [9].Tracing 数据可以标识一个全局唯一id,此外,每个节点中的监控数据段同样可以标识一个id 值,而这些技术框架则通过将完整请求中所有节点内部的监控数据串联起来形成完整的Tracing 数据.
1.2  CAT 的日志数据类型
1.2.1  Transaction 数据
被监控服务使用CAT 所生成的监控数据为Transaction 监控数据,它可以视作Tracing 中一个单节点内的监控数据,也同样是链路跟踪型日志数据.一个Transaction 内部能够嵌套多个其他类型的监控数据,并记录下函数调用中的参数、自定义数据以及耗时等.在图1中展示了一条完整的Transaction 数据,从中可以看出整体的数据结构、嵌套关系、自定义数据等
.
Fig.1  Visualization of “LogView”
图1  LogView 的数据可视化
1.2.2  LogView
本文将一条完整的Transaction 类型日志数据定义为LogView,每条LogView 中会记录一次请求调用中单台机器单个进程上的服务实例的函数调用过程以及各种自定义的数据.此外,每条LogView 具有全局唯一的id 标识值,该值由应用名、机器ip 等信息组成.LogView 的id 的统一格式为{domain}-{ip}-{hour}-{index},它由4部分组成.
{domain}:指被监控的应用名. •
{ip}:ip 地址的16进制表示,指被监控应用所部署机器的ip-v4地址. •
{hour}:表示该条logView 发生的小时,使用时间戳表示. • {index}:递增值.index 需要以一定的周期将持久化到单独的文件中,当前采取了每3s 刷新到磁盘一次
的策略,这样可以避免机器宕机后,index 重置为0导致大量id 重复.宕机重启后,首先从文件中加载之前的index 值,并在此值基础上进行自增操作.此外,在多线程并发运行的情况下,可以通过对index 值进行原子操作实现自增,不存在因同步引起的性能问题.每过1小时后,该值会重置为0重新开始计数. 图1展示了一条完整的LogView 日志数据,从图中的长方框可以看出有3种类型的监控数据(即E/t/T),t 是Transaction 的开始标识,T 是结束标识,而E 代表Event 类型监控数据.整体来看,存在两层Transaction 嵌套关系以及3个内部Transaction 的并列关系,并且内部有多个Event 类型.从该LogView 中可以获取到多项监控指标,比如调用是否成功、开始与结束时间戳、耗时、自定义的分类名、自定义的附加数据.例如,图中的第1行与最后一行为一个Transaction,第1列数据标识了数据类型、起始与结束的时间戳;而对应的第2列与第3列的信息是自定义的两级分类:一级分类为“URL.API”,二级分类为“/cat/r/model”;从第4列的信息可以看出,最外层Transaction 的整体耗时小于1ms,还附加了其他自定义的数据“module=r&in=model&out=model”.
Tracing 的完整数据可以视作将多个LogView 数据按时间先后和调用关系关联起来的数据集合,数据集合中含有多个节点级的Transaction 数据,且Tracing 数据同样会具有唯一的id 标识.
尤勇等:一种监控系统的链路跟踪型日志数据的存储设计1305
1.3  难点与挑战
CAT的日志数据同样也是一种链路跟踪型日志数据.在美团的线上真实环境中,一条LogView日志数据单条字节量可能仅几十字节,也可能达到几兆字节;并且在美团线上服务中,CAT所监控的所有软件系统每秒产生的LogView日志达到了百万条.所以,如何对海量日志数据进行分布式存储、如何提高存储效率、如何节省磁盘空间以及在查询时如何快速获取日志数据,都是存储设计方案所面临的难点与挑战.此类型链路跟踪型数据存在以下两点特征.
•具有唯一的id标识;
•单条日志数据的字节量相差很大,单条LogView字节量最小仅几KB,最大可达几MB.
本文存储方案考虑将id标识值利用起来创建索引结构,并通过数据文件存储日志数据、索引文件存储索引信息的方式来实现.此外,在真实的线上业务需求中,在LogView的写入与查询方面具有不同的性能要求,同样也是设计的挑战.
•LogView写入.在美团的真实业务中,每秒产生的LogView量可达上万条,所以要求存储方案在存储方面具备较高的TPS(transaction per second),例如:通过批量写入来减少磁盘IO以提高写入效率,使得存储方案的写入性能满实际的业务需求.
•LogView查询.相对于LogView高频的写入操作,LogView的查询操作是偶发的、离散的.偶发性:日志查
询请求的频率是相对很低的,在实际业务中查询完整LogView的请求每秒仅上百次;离散性:在较小时间窗口内,对同一条LogView进行查询操作的情况很少发生.所以对于查询并不要求很高的性能,只要求单次查询能够在100ms内完整获取到原始的LogView数据即可.
2  相关技术方案分析
本节主要对现有的存储方案进行分析,以及分析可选的主流索引结构的优缺点,提出了本文存储方案的各项设计目标.
2.1  现有存储方案
LogView日志在生成时,会创建一个全局唯一的id值,用于区分每一条日志.同时也需要注意:线上实际业务中,每天LogView数据量会达到上百TB;另一方面,为了方便业务进行故障定位和复盘,数据至少需要保存2周时间,这样就需要维护PB级数据量的存储和查询.下面介绍几种主流的数据库以及日志存储方案,并根据日志的数据特征解释它们是否适合LogView存储.
2.1.1  MySQL
MySQL[10]是目前主流的关系型数据库管理系统,默认使用Innodb存储引擎,通过建表的方式存储数据.如果使用MySQL存储LogView日志数据,建表时需要创建“id”字段与“日志数据”字段,存储日志数据时,
以行的格式插入LogView的id值与对应的字节数即可,并使用id字段作为主键创建索引以提高查询的效率.如使用VARCHAR类型存放LogView,在MySQL 5.7版本中,每行最大可存放65 535字节(即64KB)数据.而LogView 日志的数据最大字节量可达MB级别,64KB大小的空间无法满足所有日志数据的大小,此类型数据不合适存储LogView数据.
MySQL提供了Blob与Text类型两种类型的数据[11],存储大对象与字符串类型的数据.此类型的数据原则上可以用于存储LogView数据,但是前面提到:在实际业务中.LogView每天写入会达到上百TB数据量,高峰期的TPS超过百万.为了应对这种大流量的数据写入,使用MySQL必然需要进行分库分表,并且搭建多个存储集来支持,同时也需要维护一套分库分表的策略关系,在储存进行扩容或者缩容时,需要做好历史数据访问的兼容,增加整个系统搭建成本和复杂度;另一方面,MySQL应对的储存场景比较丰富,支持数据的增删改查、事务等,所以MySQL整个架构的设计就比较复杂,并且数据存储时会自动额外增加很多隐形字段来支持实时的删除、修改.对于LogView的存储场景是不涉及数据的修改和删除,MySQL提供的诸多能力对于此种场景是一种
1306 Journal of Software软件学报 V ol.32, No.5, May 2021
浪费;另外,MySQL为了支持这些能力,对整体性能做了很大折衷,所以使用MySQL存储从成本和技术运维角度并不适合.
此外,MySQL基于B+树建立索引,该方式由于需要建立索引树,对写入性能有一定影响.但是B+树却提供了很高的查询性能,在第1.3节中提到了,LogView是一种写多读少的场景,因此需要一种支持写入性能很高的存储技术.但是查询效率的要求并不高,从查询的角度而言,MySQL应对的场景同样不适合LogView.
2.1.2  MongoDB
MongoDB[12]是一个面向文档存储的数据库,可以将每条LogView日志数据以文档的形式存储在数据库中.而实际每日上百TB的LogView日志数据量并不合适存放在单个MongoDB,需要采取MongoDB集存放海量的数据.集引入分片机制并存储数据的多份副本以保证数据的一致性[13],而海量日志数据的多副本存储对存储资源而言是一种浪费,所以该方式同样不适LogView的存储.
2.1.3  Key-Value
Key-Value数据库是一种典型的NoSQL数据库,相关的数据库有Memcached[14]、Redis[15]、TiKV[16].此类型数据库通过在内存中维护海量的键值对数据,在查询时直接使用key值即可,此类型的数据库将键值数据维护在内存中,从而使得系统整体的读写性能非常高[17].以Redis为例,它具有非常高的读写速度,此外,它还支持数据持久化到硬盘中、支持多种类型的数据、支持主从部署.如果选取Redis存储LogView日志数据,要求将日志数据都维护在内存中,但是每条日志数据字节量是相对较大的,所以能
够在维护内存中的LogView的数量必然不会很大,从而无法将庞大数量的日志维护在内存中,所以同样也不适合于日志的存储.此外,分布式事务Key-Value数据库TiKV不仅能够支持分布式的数据存储,同样充分利用内存提供了很高的查询性能.但是TiKV 是基于事务的数据库,强调数据的强一致性、数据的完整性等,在数据的写入时存在较多约束,写入性能受到影响.TiKV的设计中,会对数据会创建多份副本存放在集的不同节点中,对于LogView的海量数据而言,集中存放多份数据副本会造成极大的存储开销.
综上,Key-Value类型的存储方案同样不适合用于LogView日志的存储与查询.
2.1.4  ELK
ELK是目前热门的日志管理与分析系统,ELK是Elasticsearch[18]、Logstash[19]、Kibana[20]的简称, Elasticsearch是搜索与分析引擎,Logstash负责日志数据的采集,Kibana是基于web的图形界面.存储与查询主要与es(elasticsearch)有关,它可以快速地储存、搜索和分析海量数据.原则上,es可以用来存储日志数据,但是ELK这种高度集成化的日志管理框架在后期的定制化需求中存在局限性,其中,仅有es能够用于LogView日志的数据存储.但是由于LogView的数据特征,es也仅能用于存储LogView的id与对应存储位置的索引信息.虽然es集能够提供非常高的查询性能,支持高效丰富的查询筛选功能,而前面提到LogView搜索条件比较简单(根据id检索到具体的日志即可),并且日志数据量十分庞大,每天上百TB的
存储量,es不能十分高效存储这种海量数据.通常,es单个索引存储上限仅几TB,每日需要创建上百个索引去存储这些日志,极大地增加了运维成本,并且需要存储2周的LogView数据,则需要维持10余个es集、上千个索引,运维开发难度极大.所以,单独设计完整的存储与查询方案会有更好的可用性.
2.2  索引结构
监控系统软件在实现LogView日志的存储时,同时也需要考虑合适的索引结构用以提高查询的效率.在日志数据写入磁盘后,需要充分利用日志的id标识、磁盘中的地址信息这两项数据来建立索引结构,这样在查询时即可直接根据id值获取到该条日志在磁盘中的位置信息.
下面分析两种在数据库广泛应用的索引结构,并指出它们的优缺点.
2.2.1  Hash索引结构
Hash索引[21]是基于哈希表建立的,哈希表是由数组与链表两部分组成,如图2所示.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。