1、背景
1.1、场景
在业务场景中一般由商家端服务维护商家和商品等信息,用户端服务从商家端服务同步各种业务数据。同步到的数据会通过接口调用实时扩散到用户端其它线上服务使用。线上服务一般会将商家信息存储在本地内存,这样数据访问效率会更高。
1.2、问题
线上服务都是使用内存数据。如果数据没有实时同步正确,这对商家和用户的体验都可能会造成极大的影响。假如商家已经置休了,在用户端却看到商家还在营业,用户下单后却发现商家不会接单了,这个对用户的体验非常的不友好。同时数据同步场景还存在以下问题:
数据同步日志一般散落在各个系统,查询同步日志会比较麻烦。
数据同步日志没办法进行关联,没有唯一ID关联所有的同步日志,导致问题定位比较麻烦。
即使通过某些数据的唯一键进行关联,在数据频繁更新的情况下还可能会出现关联错误的问题。
数据同步过程中若出现同步问题,没办法快速定位。
2、方案
针对数据同步场景设计数据同步链路跟踪方案,一方面可以获取到所有数据同步的过程信息,方便跟踪排查问题。另一方面实时计算服务可以基于同步日志自动发现数据同步过程中可能出现的数据不一致问题。
2.1、分布式会话跟踪原理
基本概念
-
traceId
全局唯一,标识一次请求,会在调用链路中传递。
-
spanId
用于标识一次分布式请求中所在的位置,如1.2表示1节点服务调用的第2个服务。
-
annotation
业务自定义埋点,如设置用户ID、压测标识等。
annotation是业务必要的扩展,压测标识的传递是其典型的场景应用。
基本示例
此处服务调用链路traceId为123,traceId在各个服务中传递。服务A是调用链的起点,假定其spanId为1。那么服务B是服务A调用的第一个下游服务,其spanId为1.1。一般spanId会设计成层级结构,这样很容易知道服务调用的位置层级。服务D是服务B调用的第二个下游服务,其spanId为1.2。spanId会在传递过程中根据调用位置来变更,能明确表示下游服务的调用顺序。
基本思路
一般情况下会通过ThreadLocal维护调用链的上下文,在发起请求时序列化上下文信息进行传递,在接收请求时反序列化上下文信息并存储到ThreadLocal中。在结束请求时清空调用链上下文信息。
2.2、数据同步流程拆分
数据同步拆分成3个阶段:接收数据(receive)=>处理数据(process)=>存储数据(write)。
存储数据的方式包括数据库DB存储、缓存存储,还包括rpc接口调用这类特殊的存储方式。从存储层面的意义来说,这是把数据存储到了在线的实时服务而已。由此我们可以将线上数据同步流程日志规范化,按标准流程拆分。
2.3、数据同步链路还原
利用分布式会话跟踪跟踪的原理为每次数据同步链路,traceID为同步链路的唯一键ID,spanID为服务调用位置ID,借助同步链路日志traceID和spanID还原数据同步的链路。数据同步链路拓扑示例如下:
2.4、数据同步链路问题检测
基于数据同步链路的拓扑信息,可以知道哪些环节数据没有正常同步。存在的问题一般是服务正常接收到数据后没有正常存储、或者调用下游服务进行数据存储时下游并没有接收到相应的数据等,因此可以通过实时计算服务根据同步日志去判断同步链路是否存储问题环节。基本的检测流程如下所示:
实时消费日志,根据调用链traceID汇总日志,日志可汇总在外部缓存。
实时任务延迟处理汇总的日志,然后根据spanID对日志进行分层处理。
对日志进行分析,确保每个层级数据都被正常处理,数据接收后都有数据存储流程。数据存储后若有下游服务,下游服务也需要有对应的数据接收日志。
2.5、其它
数据同步链路日志更多是辅助我们排查问题,我们还有更简单直接的方式比对商家端和用户端数据是否一致。在接收到商家数据变更的请求后,直接延时比对两端的数据是否一致。当数据不一致时,我们可以根据同步日志来确认问题是如何产生的。
3、小结
本文简单介绍了如何基于分布式会话跟踪原理实现数据同步链路的检测,这只是在公司的分布式跟踪系统上的小应用。
很多互联网公司都有自己的分布式跟踪系统,比如Google的Dapper、阿里的鹰眼、美团的Mtrace等,主要是对服务进行实时监控,能对各个调用环节进行性能分析、故障快速定位。当我们了解其基本原理后可基于其机制扩展我们需要的功能。