Page 375 - 《软件学报》2025年第9期
P. 375

4286                                                       软件学报  2025  年第  36  卷第  9  期


                    在当今日益复杂和庞大的软件系统中, 分布式追踪作为一种关键的可观测性技术, 对保障系统的可靠稳定运
                 行起着不可或缺的作用. 这项技术不仅使得我们能够跟踪和理解分布式系统中各个组件的交互行为                                  [1] , 更为重要
                 的是, 它为系统性能分析       [2,3] 、故障排查  [4–6] 以及性能优化  [7,8] 提供了宝贵的数据支持. 追踪数据中所蕴含的信息, 例
                 如系统调用、请求传递和资源利用等, 使我们可以深入洞察分布式系统在运行时的行为模式与性能瓶颈                                   [9] . 除此
                 之外, 分布式追踪提供了详细的系统运行时视图, 可以用于评估微服务系统的服务独立性和调用链复杂性                                   [10] , 对
                 微服务架构的长期演进发挥了重要作用.
                    然而, 随着系统规模和复杂性的不断增加, 追踪数据量呈指数级增长, 对存储提出了巨大挑战. 以往的研究显
                 示  [11,12] , 微服务架构通常包括数百到数千的微服务, 系统每天都会产生大量的数据. 例如, 腾讯的微信系统在超过
                                                                10
                                                                    11
                 20 000  台机器上运行  3 000  多个服务, 每天的请求量通常在        10 –10 , 一天可以产生    PB  级别的追踪数据    [13] . 此外,
                 许多追踪数据还需要长期存储, 通常根据开发周期以及运维需求需要保留几周或者几个月的时间. 历史追踪数据
                 可以用于异常检测、性能分析以及系统优化. 然而, 存储和分析大量追踪数据会带来巨大的成本. 尽管难以获取公
                 司具体的存储成本, 但有研究估计, 运营成本的下限可能是每月每                     GB  约  2  美分  [14] . 这意味着对于像腾讯、eBay
                 这样的公司来说, 每年需要花费上百万美元存储生成的追踪数据. 因此, 存储追踪数据不仅有保障分布式系统持续
                 提供稳定可靠服务的重要性, 而且也具有数量庞大成本高昂的挑战性.
                    目前有两种主流方法用于减少追踪数据的存储开销. 一种是通过采样的方式减少追踪数据生成和收集的
                 数量, 另一种则是通过压缩减少追踪文件的大小. 常见的采样方法包括随机采样和均匀采样, 此外还有许多研
                 究  [11,12,15−17] 提出了不同的算法用于采样追踪数据. 虽然通过采样可以有效地减少需要存储的追踪数据, 但是采样
                 后的数据规模依旧不容小觑. 因此, 在将追踪数据归档之前, 有必要通过数据压缩来降低存储成本. 现有的分布式
                 追踪工具通常直接使用各种数据库             (如  Elasticsearch、ClickHouse、S3  等) 进行追踪数据的存储. 当前, 在实践中
                 主要使用传统的文本压缩算法对分布式追踪数据进行压缩, 如                     gzip [18] 采用  LZ77  算法  [19] 和霍夫曼编码  [20] 等方法.
                 尽管这些方法可以快速捕获数据中的局部冗余, 但通常不是最优的, 且并未针对追踪进行优化, 因此在压缩追踪数
                 据时效果较差. 另一方面, 现有的压缩算法在设计时并未充分考虑对压缩数据的搜索问题. 对这些方法压缩后的数
                 据进行搜索是相对耗时的, 需要依次解压所有数据, 然后再筛选出满足条件的内容. 为了提高查询的响应速度, 现
                 有的追踪查询工具       (如  Grafana Tempo [21] 和  Jaeger [22] ) 通常将保存的数据分块并建立外部索引. 在查询时, 这些工具
                 搜索对应的索引, 只解压可能包含与查询条件匹配的数据块. 然而, 这种方法以大量的存储空间和内存为代价, 传
                 入的追踪文件越大, 建立索引所消耗的空间也越多.
                    在追踪数据中主要存在模式冗余和结构冗余两种形式的冗余. 模式冗余是指追踪数据的每个跨度中存在的键
                 值对冗余, 即不同跨度间重复的字段和取值组合. 例如: 对于调用相同服务实例产生的不同跨度, 其中表示服务实
                 例、服务名的键值对在这些跨度中都是相同的, 而这些相同的键值对会随不同跨度被系统重复存储, 从而产生大
                 量冗余. 结构冗余是指不同的调用链中存在的相同调用结构. 在分布式追踪中调用链通常可以表示为由跨度组成
                 的有向无环图, 该图结构反映了系统处理请求时具体的服务调用逻辑. 这时, 对相同功能的请求所产生的调用链就
                 可能呈现出同样的调用结构, 如不同用户登录产生的调用链结构可能相同. 另一方面, 在一个微服务系统中一些服
                 务提供的功能可能会被不同请求使用, 例如鉴权等基础功能可能会被多种请求频繁使用, 这时可能会导致不同调
                 用链中存在部分调用结构相同. 这些重复的调用结构也会导致数据在存储时产生大量的冗余信息.
                    针对上述问题, 本文提出了一种基于神经网络的分布式追踪数据的压缩和查询方法                             NCQT (neural-network-
                 based compression and query method for distributed tracing data). NCQT  通过识别追踪中的模式冗余和结构冗余, 减
                 少数据中的重复内容, 并训练了一个基于神经网络的编码器进行数据压缩, NCQT                         允许对压缩数据进行高效的搜
                 索, 而无需解压所有追踪数据. 首先, NCQT          创建了多个不同的索引字典以记录追踪数据中的模式冗余和结构冗
                 余, 并将自然语言文本转换为格式规整的数字表示, 以简化和加快编码器的学习过程. 然后, NCQT                           将处理后的数
                 据分组, 并利用训练过的编码器和算术编码             [23] 创建追踪数据的最小二进制表示. 在查询和解压阶段, NCQT              可以利
                 用索引字典和编码器完整恢复追踪数据的文本表示.
                    为了评估    NCQT  的有效性和效率, 我们在       4  个具有较高影响力的开源微服务系统上收集了不同大小的追踪
   370   371   372   373   374   375   376   377   378   379   380