背景
链路追踪是微服务中排查的利器,用一个 TraceId 就可以串起整个调用链路的所有环节,对排查一些生产问题帮助很大。但是目前公司自研的链路追踪系统因为资源限制,数据处理延迟很严重。本篇文章分享实习期间对链路追踪进行优化的过程。
实现原理
我们先简单的认识下一个典型的链路追踪系统:
如下图所示,如果想知道一个请求在哪个环节出现了问题,就要知道这个请求调用了哪些服务,调用的顺序和层级关系。这些调用信息像链条一样环环相扣,我们称之为调用链。

p1.png
而在这条链中,每个调用点,比如服务A对服务B的调用,服务B访问数据库,我们称之为 Span。将一次请求看作一个 Trace,使用唯一的 TraceId 标识,通过 SpanId 和 ParentId 记录调用顺序和层级关系,使用 Timestamp 记录调用的各项时间指标。
把 TraceId 相同的 Span 都整合起来,就可以绘制出这个 Trace 的调用情况图,帮助分析问题。如下图所示:

p2.png
存储系统架构
Trace 的数据有以下特点:
-
Trace 的 Span 数量各不相同:有的 Trace 只有一个 Span,有的 Trace 有上百个 Span。
-
数据量大:我们每天需要收集 8千万+ Span,这些 Span 组成 1千万+ Trace。
借鉴 Google 的 Dapper,我们选择 HBase 来存储 Trace 数据,它支持超大规模数据存储和稀疏存储动态列的特性可以满足存储 Trace 的需求,存储格式如下:

p3.png

p4.png
为了避免海量的 Trace 数据对 HBase 的冲击,我们使用 Kafka 在中间缓冲。Consumer 节点从 Kafka 拉取到 Span 后,以 TraceId 作为 RowKey,SpanId 作为 ColumnKey 存到 HBase 中。
问题
这种方式受限于 HBase 的写入速度(公司的的 HBase Trace 集群配置不高,且集群不大。因为 Trace 的使用特征是需要每时每刻收集和存储大量的数据,但是只有碰到链路问题时才可能会使用,所以为了节约成本,一般 Trace 的 H

本文介绍了针对分布式链路追踪系统存储的优化过程,包括从磁盘存储到重回HBase的解决方案。通过Span聚合、DirectByteBuffer、PreAllocate等优化,实现了查询延迟从小时级降至毫秒级,并构建了内存、磁盘、HBase的三级缓存结构,有效平衡性能与成本。
最低0.47元/天 解锁文章
6万+

被折叠的 条评论
为什么被折叠?



