Dapper是Google开发的一种分布式监控系统
1.系统设计要求
-
广泛可部署性
设计出的监控系统应当能够对尽可能多的Google服务进行监控
-
不间断的监控
Google的服务是全天候的,如果不能对Google 的后台同样进行全天候的监控很可能会错过某些无法再现的关键性故障
2.系统设计目标
-
低开销
这个是广泛可部署性的必然要求。监控系统的开销越低,对于原系统的影响就越小,系统的开发人员也就越愿意接受这个监控系统。
-
可扩展性
Google的服务增长速度是惊人的,设计出的系统至少在未来几年里要能够满足Google服务和集群的需求。
-
应用层透明
监控系统对程序员应当是不可见的。如果监控系统的使用需要程序开发人员对其底层的一些细节进行调整才能正常工作的话,这个监控系统肯定不是一个完善的监控系统。
3.基本概念
-
请求应答过程
- 用户发出一个请求X,它期待得到系统对它做出的应答X
- 但是接收到该请求的前端A发现该请求的处理需要涉及服务器B和服务器C,因此A又向B和C发出两个 RPC
- B收到后立刻做出响应,但是C在接到后发现它还需要调用服务器D和E才能完成请求X,因此C对D和E分别发出了RPC
- D和E接到后分别做出了应答, 收到D和E的应答之后C才向A做出响应,在接收到B和C的应答之后A才对用户请求X做出 一个应答X
在监控系统中记录下所有这些消息不难,如何将这些消息记录同特定的请求 (本例中的X)关联起来才是分布式监控系统设计中需要解决的关键性问题之一
黑盒方案
:轻便,基于统计学,不准确基于注释的监控方案
:利用应用程序或中间件给每条记录赋予一个全局性的标示符
-
监控树
一个同特定事件相关的所有消息
区间名
: 主要是为了方便人们记忆和理解区间id
: 为了 在一棵监控树中区分不同的区间父id
: 是区间中非常重要的一个内容,正是通过父id才能 够对树中不同区间的关系进行重建, 没有父id的区间称为根区间监控id
: 一棵监控树中所有区间的监控id是相同的,这个监控 id是随机分配的,且在整个Dapper监控系统中是唯一的, 监控id是用来在整个Dapper监控系统中区分不同的监控
-
区间
区间实际上就是一条记录,一个区间既可以只有一台主机的信息,也可以包含来源于多个主机的信息,事实上每个RPC区间都包含来自客户端(Client)和服务器端(Server)的注释
-
注释
注释主要用来辅助推断区间关系,也可以包含一些自定义的内容
4.信息汇总
- 将区间的数据被写入到本地的日志文件
- 利用Dapper守护进程(Dapper daemon)和Dapper收集器(Dapper Collectors) 将所有机器上的本地日志文件汇集在一起
- 将汇集后的数据写入到Bigtable存储库中
5.关键技术
-
轻量级核心功能库
主要是为了实现对应用层透明
- 最关键的代码基础是基本RPC、线程和控制流函数库的实现
- 主要功能是实现区间创建、抽样和在本地磁盘上记录日志
- 将复杂的功能实现限制在一个轻量级的核心功能库中保证了Dapper的监控过程基本对应用层透明
-
二次抽样技术
主要是为了解决了低开销及广泛可部署性的问题
-
第一次抽样
实践中,设计人员发现当抽样率低至1/1024时也能够产生足够多的有效监控数据,即在1024个请求中抽取1个进行监控也是可行的,从而可以捕获有效数据
-
第二次抽样
发生在数据写入Bigtable前,具体方法是将监控id散列(hash,压缩映射)成一个标量z(0≤z≤1),如果某个区间的z小于事先定义好的汇总抽样系数,则保留这个区间并将它写入Bigtable,否则丢弃
-
6.常用工具
-
存储API
Dapper的“存储API”简称为 DAPI,提供了对分散在区域Dapper存储库(DEPOTS)的监控记录的直接访问。
- 通过监控id访问:利用全局唯一的监控id直接访问所需的监控数据
- 块访问:借助MapReduce对数以十亿计的Dapper监控数据的并行访问
- 索引访问:Dapper存储库支持单索引
-
用户界面
通过GUI界面对Dapper进行管理
-
首先用户需要选择监控对象,包括监控的起止时间、区分监控模式的信息及一个衡量开销的标准
-
用户可以按其意愿对这些执行模式进行排序并选择某一个查看更多的细节
-
分布式执行模式图形化描述呈现给用户
-
根据最初选择的开销度量标准,Dapper以频度直方图的形式将步骤(3)中选中的执行模式的开销分布展示出来
-
用户选择了某个监控样例后,就会进入所谓的监控审查视图
7.使用经验
-
新服务部署中Dapper的使用
利用Dapper对系统延迟情况进行一系列的跟踪,进而发现存在的问题
-
定位长尾延迟
端到端性能和关键路径上的网络延迟有着极大的关系
-
推断服务间的依存关系
Google的“服务依存关系”项目使用监控注释和DPAI的MapReduce接口实现了服务依存关系确定的自动化
-
确定不同服务的网络使用情况
利用Dapper平台构建了一个连续不断更新的控制台,用来显示内部集群网络通信中最活跃的应用层终端
-
分层的共享式存储系统
没有Dapper之类的工具的情况下对于这种共享式服务资源的争用也同样难以调试
-
利用Dapper进行“火拼”
Dapper用户可以通过和Dapper守护进程的直接通信,将所需的最新数据汇总在一起