SRE:Google运维解密
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

管理物理服务器的系统管理软件

为了管理和控制硬件设备,我们开发了一套支持大规模部署的系统管理软件。硬件故障是我们用软件系统所解决的一项主要问题。因为一个集群中包括很多硬件设备,每天硬件设备的损坏量很高。在一年内,一个单独集群中平均会发生几千起物理服务器损坏事件,会损失几千块硬盘。当把这些数字乘以Google现有的集群数量时,这些数字就有点令人难以置信了。所以,想将硬件故障与实际业务用户隔离开来。具体业务团队运行软件服务器的时候也并不想每天处理硬件故障。每个数据中心园区都配备专门的团队负责维护硬件设备和数据中心基础设施。

管理物理服务器

Borg,如图2-2所示,是一个分布式集群操作系统(参见文献[Ver15])。其与Apache Mesos类似,[5]Borg负责在集群层面管理任务的编排工作。

图2-2:Borg 集群管理系统架构抽象图

Borg负责运行用户提交的“任务”(job)。该任务可以是无限运行的软件服务器,或者是批量任务,例如MapReduce(参见文献[Dea04])。每个任务可以由一个或多个实例(task)组成(有时候甚至由几千个实例组成)。通常这样组织是为了提高冗余度,而且大多数情况下,一个实例并不能满足整个集群的流量需求。当Borg启动一个任务的时候,它会为每一个实例安排一台物理服务器,并且执行具体的程序启动它。Borg 同时会不断监控这些实例,如果发现某个实例出现异常,其会终止该实例,并且重启它,有时候会在另外一台物理服务器上重启。

因为任务实例与机器并没有一对一的固定对应关系,所以我们不能简单地用IP地址和端口来指代某一个具体任务实例。为了解决这个问题,我们增加了一个新的抽象层。每当Borg启动某一个任务的时候,它会给每个具体的任务实例分配一个名字和一个编号,这个系统称之为Borg名称解析系统(BNS)。当其他任务实例连接到某个任务实例时,使用BNS名称建立连接,BNS系统负责将这个名称转换成具体的IP地址和端口进行连接。举例如下,一个BNS地址可能是这样一个字符串:/bns/<集群名>/<用户名>/<任务名>/<实例名>,这个BNS地址最终将会被解析为IP地址:端口

Borg 还负责将具体资源分配给每个任务。每个任务都需要在配置文件中声明它需要的具体资源(例如:3CPU核心,2GB 内存等)。有了这样的信息,Borg 可以将所有的任务实例合理分配在不同的物理服务器上,以提高每个物理服务器的利用率。同时Borg还关注物理服务器的故障域(failure domain)属性。例如,Borg 不会将某个任务的全部实例都运行在某一个机柜上。因为这样一来,机柜交换机将成为整个任务的单点故障源。

如果一个任务实例资源使用超出了它的分配范围,Borg会杀掉这个实例,并且重启它。我们发现,一个缓慢的不断重启的实例要好过一个永远不重启一直泄露资源的实例。

存储

任务实例可以利用本地硬盘存储一些临时文件,但是我们有几个集群级别的存储系统可供选择作为永久性存储。甚至我们的临时文件存储也在向集群存储模型迁移。这些存储系统和开源的 Lustre,以及Hadoop文件系统(HDFS)类似。

这些存储系统负责向用户提供一套简单易用、可靠的集群存储服务。如图2-3所示,存储系统由多层结构组成:

1.最底层由称为D的服务提供(D代表磁盘 Disk,但是D可以同时使用磁盘和SSD)。D是一个文件服务器,几乎运行在整个集群的所有物理服务器上。然而,用户具体访问某个数据时并不需要记住具体到哪个服务器上去获取,这就是下一层做的事情。

2.D 服务的上一层被称之为Colossus,Colossus建立了一个覆盖了整个集群的文件系统。Colossus文件系统提供传统文件系统的操作接口,同时还支持复制与加密功能。Colossus是GFS的改进版本(参见文献[Ghe03])。

3.构建于Colossus之上,有几个类似数据库的服务可供选择:

a.Bigtable(参见文献[Cha06])是一个NoSQL 数据库。它可以处理高达数PB的数据。Bigtable是一个松散存储的、分布式的、有顺序的、持久化的多维映射表。它使用Row Key、Column Key以及时间戳做索引。映射表中的值是按原始字节存储的。Bigtable支持“最终一致”的跨数据中心复制模型。

b.Spanner(参见文献[Cor12])是可以提供 SQL 接口以及满足一致性要求的全球数据库。

c.另外几种数据库系统,例如Blobstore也可用。每一种数据库都有自己的优势与劣势。

图2-3:Google 存储系统(部分)

网络

Google的网络硬件设备是由以下几种方式控制的。如前文所述,我们使用一个基于OpenFlow协议的软件定义网络(SDN)。我们没有选择使用高级智能路由器,而是采用了普通的非智能交换组件结合集中化(有备份的)的控制器连接方式。该控制器负责计算网络中的最佳路径。我们可以将整个集群的复杂路由计算从具体交换硬件上分离开来,从而降低成本。

网络带宽也需要合理分配。就像Borg给每个任务实例分配计算资源一样,带宽控制器(Bandwidth Enforcer,BwE)负责管理所有可用带宽。优化带宽的使用的目的不仅仅是降低成本。利用中心化的路由计算,可以解决以前在分布式路由模式下难以解决的流量迁移问题(参见文献[Kum15])。有些服务包括运行在不同集群上的任务,这些集群通常是遍布全球的。为了降低分布式集群的服务延迟,我们希望能够将用户指派给距离最近的、有空余容量的数据中心处理。我们的全球负载均衡系统(GSLB)在三个层面上负责负载均衡工作:

● 利用地理位置信息进行负载均衡DNS请求(例如www.google.com的解析,具体描述参见第19章)。

● 在用户服务层面进行负载均衡,例如YouTube 和 Google Maps。

● 在远程调用(RPC)层面进行负载均衡(具体描述参见第20章)。

每个服务的管理者在配置文件中给服务起一个名称,同时指定一系列的BNS地址,以及每个BNS地址可用的容量(通常,容量的单位是QPS,每秒请求数量)。GSLB会自动将用户流量导向到合适的位置。