0%

"Google 内部曾对工程师做一次 调研,发现平均每位工程师每天会进行 5.3 次代码搜索会话 (session),执行 12 个代码搜索请求;在 Github/Gitlab 等仓库托管服务中,搜索是工程师最常用的功能之一。"

阅读全文 »

此文同时发表在伴鱼技术博客

理论篇 中,我们介绍了伴鱼在调用链追踪领域的调研工作,本篇继续介绍伴鱼的调用链追踪实践。在正式介绍前,简单交代一下背景:2015 年,在伴鱼服务端起步之时,技术团队就做出统一使用 Go 语言的决定。这个决定的影响主要体现在:

  1. 内部基础设施无需做跨语言支持
  2. 技术选型会有轻微的语言倾向
阅读全文 »

本文将调用链追踪系统的设计维度归结于以下 5 个:调用链数据模型、元数据结构、因果关系、采样策略以及数据可视化。我们可以把这 5 个维度当作一个分析框架,用它帮助我们在理论上解构市面上任意一个调用链追踪系统,在实践中根据使用场景进行技术选型和系统设计。如果你对调研相关系统很感兴趣,也欢迎参与到 Database of Tracing Systems 项目中,一起调研市面上的项目,建立起调用链追踪系统的数据库。

阅读全文 »

本文主要介绍一篇关于调用链追踪系统设计的论文。行文会尊从原论文的结构,但不是逐字翻译,以意译和加入个人理解的转述为主。

1. Introduction

如果把公司内部所有 IT 系统看作一个巨型分布式系统,通常其规模庞大、结构复杂,且拥有多层依赖和抽象,每层单拎出来也同样是个分布式系统。以 Google 的业务服务为例,如搜索、广告,会构建于内部基础服务之上,如 Bigtable;而 BigTable 又构建于 Google File System (GFS) 和 Chubby 之上。即便是业务服务本身,也可能存在多层 (multiple tiers) 结构,其中每层同样支持横向扩展。从巨石应用走向微服务,我们在组织架构和服务架构上都变得高效,但其代价就是下降的系统可观测性 (observability)。一个很现实的问题就是:几乎不存在一位工程师能够了解系统全貌,那么问题排查也将变得困难。从单机走向分布式,只关心单个进程、单台机器的性能指标已经远远不够,我们需要将监控的重心从以机器为中心 (machine-centric) 转向以流程为中心 (workflow-centric),后者的核心方法便是调用链追踪系统。分布式系统的终极理想可以描述为:在获得横向扩展性的同时不暴露自己分布式的本质,即向外提供与单机系统相同的体验。调用链追踪系统概莫能外。

按:原文将请求处理过程称为 workflow,下文会使用流程和请求来指代它;原文将以流程为中心的观测方法统称为 end-to-end tracing,由于现在分布式系统几乎是所有讨论的默认假设,本文将不再强调 end-to-end,将其直接译为调用链追踪。

尽管大家对调用链追踪的兴趣浓厚,但关于如何设计一个调用链追踪系统,市面上、社区中提供的信息十分有限。更令人担忧的是,现存的文献和实践都将调用链追踪当作多种场景的万能解决方案 (one-size-fits-all),然而我们以及 Dapper 的实践经验证明事实并非如此。因此在提出你的解决方案之前,最好明确你想要解决的问题是什么。

调用链追踪的基本原理和概念十分通俗易懂:就是在系统中的各个节点 (组件) 上埋点,当请求经过时将节点信息 (trace point) 上报,最后汇总信息重建调用链。我们从经验中总结了调用链追踪系统的 4 个设计维度,通过组合这些设计维度的选择就能得到不同应用场景的解决方案:

  1. which causal relationships should be preserved: 保留什么样的因果关系?
  2. how causal relationships are tracked: 如何追踪因果关系?
  3. how to reduce overhead by sampling: 如何通过采样降低成本?
  4. how end-to-end traces should be visualized: 如何将追踪的结果可视化?

如果对这 4 个设计维度以及它们之间的权衡关系没有足够的理解,设计一个调用链追踪系统将可能让实现与场景脱节。事实上,由于这些维度之前并未被实践者或研究者提出和充分理解,许多调用链追踪系统的实现并未能充分达成其设计理想。

2. Backgroud

本节主要陈述一些调用链追踪系统的背景信息,包括核心应用场景、解决方案分类以及本文所推崇的架构方案。

阅读全文 »

造一辆能跑在路上的车并非难事,但要这辆车能在各种路况、气候和突发事件下安全行驶,事情就不再简单。如果把写程序比喻成造车,构建程序的主要功能就是让车跑起来,而处理好错误就是让车安全地跑。错误是程序的重要组成部分,能否在程序中处理好错误决定了软件的质量上限。在这篇博客中,我将介绍个人在 Golang 项目中错误处理的思考。

阅读全文 »

最近在阅读 TiDB 源码 util/chunk package 的过程中,看到了 Apache Arrow 这个项目 (下文简称 Arrow):

1
2
3
4
5
// Chunk stores multiple rows of data in Apache Arrow format.
// See https://arrow.apache.org/docs/format/Columnar.html#physical-memory-layout
// Values are appended in compact format and can be directly accessed without decoding.
// When the chunk is done processing, we can reuse the allocated memory by resetting it.
type Chunk struct { /*...*/ }

心里自然而然会产生疑问:为什么要使用这个项目规定的数据存储格式?于是在阅读完 TiDB 相关源码和单测后,顺便搜寻并浏览一些有趣的资料 (见文末参考部分),现在将这次调研的收获小结在这篇博客中。

阅读全文 »

引言

最近因为工作的关系接触 ElasticSearch,发现搜索引擎也是计算机应用的一个有意思的分支。于是通过 Freiburg 的 Information Retrieval 公开课开始系统地了解信息检索这个领域,感觉收获颇丰。周末一时兴起,上 Google Research 找到了 Google 的开山之作,近距离地感受一下 19800+ 引用量、造就如今 Google 万亿市值的这篇文章。

本文介绍会尽可能地忠于原文,但不是完全逐字逐句的翻译。

1. 简介

近年来,网络中的信息量和非专业的用户都在快速增长,为信息检索领域带来了新的挑战。从行为上看,人们更倾向于以门户网站,如 Yahoo,或搜索引擎为起点,利用网页间的链接来浏览所需信息。门户网站的索引来自于人工维护,聚合效果好、主观性高、维护成本高、改进速度慢,且通常不会覆盖小众话题。自动化的搜索引擎则相反,其它都满足,但聚合效果差,依赖于关键词匹配的检索方式返回的匹配项质量过低。一些广告商为了获取更多的流量,通过逆向工程来误导搜索引擎,使其结果靠前,进一步加剧问题的严重性。我们搭建了一个大型搜索引擎来当前系统的这些已知问题,它通过重度利用网页文本中的特殊结构来提供更高质量的检索结果。我们为这个系统取名为 Google,因为它是 googol (即 ) 的常用拼写,后者的含义恰好与构建大型搜索引擎的目标体量相契合

网络搜索引擎的扩张:1994 - 2000

为了跟上网络信息扩张的速度,搜索引擎技术也必须加速规模化。1994 年,World Wide Web Worm (WWWW),第一代网络搜索引擎 (web search engine) 之一,对 11 万网页或文件建立了索引;到了 1997 年末,行业领先的网络搜索引擎建立索引的数量已达到 200 万 (WebCrawler),甚至 1 亿 (Search Engine Watch)。可以预见这个数量在 2000 年将超过 10 亿。与此同时,网络上的搜索引擎处理的查询也在飞速增长。在 1994 年初,WWWW 大约每日需要处理 1500 次查询,到了 1997 年末,Altavista 已经声称自己每日处理的请求量达到 2 千万。同样可以预见,这个数量在 2000 年也将达到亿级。Google 的目标就是要提供相应规模、高质量的网络搜索服务。

Google: 与网络一同扩张

即便是搭建一个满足当前规模的网络搜索引擎也需要面对许多挑战,如:

  • 高性能的网页抓取技术保证原始数据全而新
  • 充足的存储空间用以存放索引和网页本身 (如果需要的话)
  • 索引系统必须能够高效地处理百 G 级别的数据
  • 查询必须能被快速处理,QPS 过千
阅读全文 »

I ❤ Logs 出版于 2014 年,是一本很短小的书,100 页不到,利用这周的零散时间就看完了。作者 Jay Kreps,是前 LinkedIn 的 Principal Staff Engineer,也是 LinkedIn 许多著名开源项目的负责人及联合作者,如 Kafka、Voldemort 等。他是现任 Confluent 的 CEO,主要工作在于围绕实时数据提供企业级服务支持。这本书算是 Jay Kreps 过去多年实践的思考结晶。

阅读全文 »

Jaeger Walkthrough 系列文章之一,旨在深入理解 Jaeger 项目内部的实现细节。本文介绍的是 Jaeger 的 Go 客户端,jaeger-client-go

简介

jaeger-client-go 是 Jaeger 对 opentracing-go 标准接口的实现,主要解决的是两个问题:

  • 如何在进程内部管理调用链追踪信息 (tracer, span)
  • 如何在进程间传递调用链追踪信息 (span context, propagation)

但在调用链追踪实践中,jaeger-client-go 仅仅解决上述两个问题还不够,它还需要考虑的问题包括:

  • 如何将数据上报到存储中心
  • 如何对数据抽样,支持不同的抽样策略
  • 需要收集哪些统计指标

接下来,我们就着源码对这些问题一一分析。

进程内调用链追踪信息管理

Tracer

Tracer 是 opentracing.Tracer 的实现,它负责与应用程序沟通,接收应用程序的请求,协调 jaeger-client-go 中各个模块完成相应工作。

阅读全文 »