dapper 调用 存储过程返回值_分布式调用链路与Dapper论文阅读笔记

写写最近在做的:为srpc增加调用链路的追踪信息。这其实是个很简单的事情。

也算是为了锻炼一下自己设计能力和服务层面的整理把控,边做边思考并且在谢爷对层次拆分的指导下已经完成了初版功能,现在是时候系统地看看google中已经很成熟的系统:Dapper长什么样,所以本篇博客还是会从一个设计者的角度,先聊聊背景,进而看看Dapper论文中的重要知识点,最后是srpc相关以及个人的思考和总结。

本篇只是一篇个人技术博客,而我自己还是架构设计上的一只鶸渣,因此相关内容如有不准确或者还可以改进的地方,都非常欢迎大家帮我指出~

一、为什么需要分布式调用链路追踪

第一个背景大概需要先提一下restfulrpc的不同了。

以前接触的业务少,做了几年kv,接口基本是restful的,所以对资源定位是有固定的URL来进行标识,所以基本有URL就能知道请求如何路由、落到哪些kv节点。

但是rpc不一样,很多调用除了service或method根本没有固定的阈,那么跨机调用我们需要更加通用的信息。粗略了解过brpc、字节的压测链路和美团的leaf,大家基本都是用一个trace_id(或者log_id)来标示一次完整的调用,用一个span_id来标示这次调用链上的每一个逻辑节点,以下基于论文里的图,蓝字是我标的信息。

ba20b663e4a2047f3d53d92c6068642c.png

链路追踪的第二个背景是在于,随着服务的封装(各种rpc框架、边车、服务网格等),我们做业务开发时往往很难知道真正的对方ip,不太可能让业务开发去留下追踪信息,而且每个模块的开发往往不是同一个组,这必须是中间层去协商一个统一的做法。

二、Dapper基本阅读笔记

http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36356.pdf

这篇paper其实很浅显,但里边包含google大规模实践过的经验,具体做法可以因人而异,但思路值得借鉴。从公司层面的服务部署来说,Dapper其实不仅仅是调用链的信息采集系统,更是一套流式日志和监控系统,在这之上可以培育出各种分析模块的生态。但是如何做流式日志和监控,每个公司现有方案都是不同的,因此我这里着重梳理分布式调用链相关的部分。

1. 调用链包含的信息

一个调用链,需要的基本信息是:

  • trace_id,这是一个分布式全局唯一id,由我们全部系统中第一个被调起的模块生成;
  • span_id,用来区分本模块产生出来的请求。全局可以通过trace_id+span_id去唯一定位一个请求;
  • parent_span_id:我上游的span_id,这样树状结构就很清晰了;
  • annotation:用户自定义注释信息也很重要。

我们可以设想的是,这肯定由一个flag来控制。打开了,中间层就开始收集。那么这些信息,存放在中间层哪里?其实是看具体协议实现的。HTTP可以尽情使用header。而rpc系统的话一般协议中都有一个meta部分,meta部分如果可扩展,可以加到meta里。至于其他协议,可以额外提供lib接管他们的请求。在google内部,所有RPC都带了span功能。

2. 调用链层基本需求

  • 低开销:(收集的数据够小,部分采样实现减少系统消耗)
  • 应用层透明:(中间层有threading,control flow,RPC lib三种做法)
  • 可扩展:(提供接口让用户填入注释信息)
  • 收集及时:(google的做法是本地log + 本地dapper daemon + 全局dapper colletor + 全局入Bigtable + 其他监控系统,打造一套公司级的流式日志系统)

3. 请求信息收集的三种方式

这个和请求调用从哪里来是一样的:跨机和本机发起。其中本机请求也由于同步和异步,而导致上下文信息采集方式会有所不同。因此,google基本的三种采集方式是:

  • 同步请求用thread local。用来处理本地发起下一个请求时,trace_id可以传到下一个请求的;
  • 异步请求用Control flow接管callback。异步发起请求,上下文就不在了,因此只要用户使用的control flow层的lib可以接管调度和callback,那么在请求被executor调度器或固定某些线程执行的时候,就可以偷摸儿采集了;
  • RPC层自带,且google的RPC部署范围很广。

4. 采样sampling

上面提到,想要对性能影响小,需要做到两点:数据小和抽样记录。

论文里提到,默认的采样比例是1/1024,但是对于一些高QPS的服务可以少采一些,可以足以收集到有用的信息;而对于低QPS的服务可以全部都采集。目前google应该已经使用上自动调整采样频率的策略了。

关于采样,个人思考比较多,以下抛出几个问题:

  1. 是否只有频率这个因素会影响到要不要采样呢?如果不是,这个策略应该是要抽出来的,但是论文里只提到频率相关。

2. 如果有策略,策略生效的范围是否一定是与生成span_id的单位一致的?

3. 是否只要打开了flag,所有请求都需要包含span信息,采样只影响某些请求写log?

这些问题后续陆续可以找到答案。

5. 实际性能数据

Google内部提供了C++和Java的lib,代码量都是1k的量级,非常轻巧。而对于实际性能影响,以下有一些数据给我们参考,确实可以做到low overhead:

769ca28aea98a033a0d9c3ce64edb9ab.png

这里也可以看到,google并不是全部请求都产生的,而是需要采样的节点才有span信息。

另外可以看到的是,产生trace_id的消耗是纳秒级,因此这个全局唯一的trace_id也是本地生成的,同样srpc内部我也是用SnowFlake的做法来生成的。

而对于收集回来的数据能被使用的时效,虽然不是我当前要做的,但可以给大家参考一下:论文中也提到基本能在15s内收集到、高峰期少部分长尾数据也可以几小时内到位。

6. Out-of-band 的方式

对于一个节点,把trace_id,span_id发送出去之后,是否需要response回来的数据呢?先前看过一篇公众号写的是需要的,但是Dapper论文中表示不需要,考虑到以下两点:

  1. 对回来的网络是个额外的开销;
  2. 许多调用链本身往往不是完整地nested的,比如一些只发完就返回的模块,你根本也没办法完整追踪到。

个人认为,有些协议本身也是只发不收,协议上也没办法做到收集。

7. 工程意义

基于Dapper做生态,有许多方面的收益,包括协助用户提升系统performance、理解系统瓶颈、排查系统正确性、测试中的链路追踪、进而帮助解决系统级别的长尾问题。

三、srpc的调用链定位及思考

这里列一些思考,主要是给小伙伴参考我的经历以便进一步了解分布式调用链路追踪,也是个人的一些项目总结,感兴趣的前辈如果发现问题,也可以帮我指出~

1. srpc的调用链定位

看完论文,大概知道调用链本身的价值,是要配合公司级的流式日志收集系统、分布式存储系统、监控系统才能打通整个服务中间层的调用链追踪的意义。而我作为一个rpc层,我能做的事情就是为使用rpc的小伙伴提供一个本地采集的功能,并且拆出定制化的日志收集接口,而不要关心用户如何写log、如何存储等等,这是公司级后续要统一打通的事情。

2. 用户态上下文

上边提到的三种采样方式,其实跨机大家的做法都是一样的:往rpc的meta层放数据,用户无需关心。那么本机的做法,是否还有别的呢?显然是有的。

这里无论是thread_local还是异步请求下的callback接管,想要解决的问题都是用户态上下文的传递。这方面我其实不是很熟,但是由于每个系统的调度实现不同,则每个系统都可以有自己的一套方法。看过brpc的代码,bthread就是用来套一层thread上下文的极佳载体。而如果某些是基于用户态协程做的,那么协程栈上或许也是可以保存这些上下文的。

3. 采样的机制与策略(中间层的设计)

上面说到,Dapper的采样机制是按比例去采,策略是高QPS的服务器比例低点、低QPS的服务器比例高点。

但老大认为这还不够。所以目前srpc的采样机制是用户派生SpanLogger类实现对应的虚函数,返回一个对应的task(在workflow的机制内,类似行为都应该封装成task),而策略是用户自己实现的,这样就可以更灵活,采样的策略不仅仅取决于全局的数据(比如采样频率),更可以取决于span的信息本身。

最近思考发现我们开发一个框架,需要更多地留空间给中间层。Dapper提供给用户可填的annotation就是中间层,我们的采样机制也是一个中间层。系统除了直接使用代码run的用户,还有一些开发者,必须留有接口让系统的二次开发者或者后续功能有可扩展的地方。

4. 其他

现在觉得最难的不是代码实现能力或者给出一套设计方案的能力,而是对项目的品控

你能够立刻实现一个功能,这不牛逼;你可以知道很多上层架构,设计出我们的生态有100种做法,也不牛逼;但是当你拿着自己的项目,让它以一个优秀而统一的方向去进行演进,无论是功能实现还是新的设计,都是一件需要把项目时刻放在心上琢磨的事情。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值