您的位置:首页 > 大数据 > 人工智能

【每周论文】Design patterns for container-based distributed systems(HotCloud 2016)

2018-03-07 08:53 519 查看
首先介绍下第一作者Brendan Burns,他2008-2016年在Google工作,是Kubernetes的首席工程师,k8s容器编排的主要创始人之一,他在2016年的7月份宣布加入了Microsoft。

第二作者David Oppenheimer,他参与了Google的三大数据中心管理系统的开发——Kubernetes、Omega和Borg的开发,同时也是论文Borg的作者之一。

那篇非常有名的文章《Borg, Omega, and Kubernetes:Lessons learned from three container management systems over a decade》就出自这两位作者之手。

这篇论文发表在HotCloud 2016(The 8th Usenix Workshop on Hot Topics in Cloud Computing),在2018年的3月份,Brendan Burns出了一本书:《Designing Distributed Systems》,这本书对论文中提到的一些Design Pattern进行了更加详细的说明,目前正在啃这本书。

在20世纪80年代末和90年代初,面向对象编程彻底改变了软件开发,推广了将应用程序构建为模块化组件集合的方法。当下,随着容器化软件组件构建的微服务体系结构的日渐普及,凭借容器与外界的隔离性,容器特别适合作为分布式系统中的基本“对象”。随着这种架构风格的成熟,作者通过观察抽象出了更高层次的设计模式。

本文描述了作者在基于容器的分布式系统中观察到的三种类型的设计模式:

用于容器管理的单容器模式

用于紧密合作的容器的单节点模式

用于分布式算法的多节点模式。

下面对这三种模式进行简单的介绍。

1 基于容器管理的单容器模式

容器为接口的定义提供了一个自然边界(类似于对象的边界)。 容器不仅可以通过该接口对外开放特定应用程序的功能,而且还可以用来作为显示管理系统的钩子。

从容器角度“向上”来考虑,容器可以公开丰富的应用程序信息,包括特定应用的监控指标(QPS、应用程序运行状况等)、分析开发人员感兴趣的信息(threads、stack、 lock contention、 network message statistics等)、组件配置信息和组件日志。例如,Kubernetes、Aurora、Marathon和其他容器管理系统允许用户通过指定的HTTP endpoints(例如“/ health”)来定义健康检查。

从容器角度“向下”来考虑,容器所提供的接口为定义生命周期提供了天然的环境,这使得编写功能组件变得更加容易。例如,集群管理系统一般都会为任务分配优先级,对于优先级高的任务,即使集群中存在超卖的现象,高优先级任务也要能保证运行,一般是通过抢占低优先级作业的资源来实现的,通过kill掉低优先级作业,但到处可能会出现的任务死亡给开发带来了负担。相反,如果在应用程序和管理系统之间定义了一个正式的生命周期,那么应用程序组件会变得易于管理,例如,Kubernetes使用Docker的“优雅删除”功能,在发送SIGKILL信号之前的一段时间,通过给容器发送SIGTERM信号来警告容器它将被终止,这留给了容器一定的时间来完成正在进行的操作并将状态刷新到磁盘。这种机制为状态序列化和恢复提供了支持,使得分布式系统的状态管理变得更加容易。

2 用于紧密合作的容器的单节点模式

除去单个容器的接口之外,作者还看到了跨容器的设计模式,作者在15年的一篇博客上有探讨过几种模式:The Distributed System ToolKit: Patterns for Composite Containers。这些单节点模式由共同调度到同一台主机上的共生容器组成,容器管理系统支持将多个容器共同调度为一个原子单元,在Kubernetes中称为Pod。

2.1 Sidecar pattern

第一种也是最常见的多容器部署模式就是sidecar pattern,有些文章将其翻译为挎斗模式,就像是老式的摩托车,旁边会有一个小的挎斗,能让车多坐一个人。Sidecar容器就是像摩托车上的那个挎斗一样,用来延伸和增强主容器。例如,主容器可能是一个Web服务器,它可能与一个“logsaver”sidecar容器配对,该容器从本地磁盘收集Web服务器的日志并将它们传输到集群的存储系统。下图显示了sidecar模式的一个例子。



另一个常见的例子是一个Web服务器,它服务于本地磁盘内容,该sidecar容器定期同步来自git存储库、内容管理系统或其他数据源的内容。这两个例子在Google都很常见。由于同一台计算机上的容器可以共享本地磁盘卷,因此可以使用Sidecars。

虽然说可以将Sidecars容器里面的功能构建到主容器当中(例如将log saver的功能在主容器中实现),但是将主容器和Sidecars容器分开有以下几点好处:

容器是资源计数和分配的单位。

容器是packing的单元。因此可以将服务和日志存储分隔到不同的容器中,可以很容易地在两个独立的编程队伍之间分配其开发的责任,并且可以进行单独和一起测试。

容器是重用的单元。所以Sidecars容器可以与不同的主容器进行配对,保证了可重用性。

容器提供了一个故障遏制的边界。这样出现问题时可以使得整个系统进行优雅地降级。

容器是部署的单位。它允许每个功能都可以独立地进行升级或者回滚

以上提到的五个优点适用于该论文中提到的所有容器模式。

2.2 Ambassador pattern

第二种模式是Ambassador pattern,也成为外交官模式或大使模式。这种模式主要利用同一Pod中的容器可以共享相同的localhost网络接口的特性。如下图所示,在一个Pod中给应用容器搭配一个大使容器作为代理服务器,大使容器帮助应用容器访问外部服务,使得应用容器访问服务时不需要使用外网的IP地址,而只需要用localhost访问本地服务。在这种模式下,作为代理服务器的大使容器很像外部服务派驻在Pod中的“大使”,使得应用容器办理业务时只需要跟本Pod的大使打交道就可以了。



这种大使模式通过三种方式简化了开发人员的工作:

他们只需要考虑并编程连接到本地主机上的单个服务器的应用程序。

他们可以通过在本地机器上运行真正的程序实例来测试其应用程序的独立性,而不是使用大使容器。

他们可以将大使容器与其他不同的主程序放在一起进行重用。

2.3 Adapter pattern

第三种模式是适配器模式。这种模式对于监控和管理分布式系统尤为重要,与大使模式不同的是,适配器模式对外界展示了一个简化的应用视图,它通过多个容器来标准化输出和标准化接口实现这一点。如下图所示,适配器模式常见的一个例子是确保系统中的所有容器具有相同的监控接口。当今的程序使用各种方法来导出其度量标准(如JMX,statsd等)。但是,如果所有应用程序都提供了一致的监视接口,单个监视工具就可以更容易地收集、汇总和显示异构应用程序集中的监控数据。



3 多结点模式

3.1 领导选举模式

在分布式系统中,最常见的一个问题就是领导选举。虽然副本(replica)多用于分流进行负载均衡,但是副本另外一个重要的用途就是用来选举领导者,如果领导者挂了则迅速从剩下的副本中选择新的领导。现在有很多可以进行领导选举的库,但是通常很难理解和使用,并且还受限于不同的编程语言。将领导选举库链接到应用程序的另一种方法就是使用领导选举容器。一组领导选举容器,每个容器与需要领导选举的应用实例一起调度,可以在他们自己之间进行选举,并且他们可以通过本地主机向每个需要领导选举的应用容器提供简化的HTTP API(例如成为领导者,更新领导力等)。这些领导选举容器可以构建一次,然后由开发人员重新使用简化的接口。

3.2 工作队列模式

虽然说工作队列像领导选举一样已经有很多框架实现了,但它也是分布式系统模式的一个例子,可以从面向容器的体系结构受益。实现run()和mount()接口的容器,其可用性使得实现一个通用工作队列框架非常简单,该工作队列框架可以将任意处理代码打包为一个容器和任意数据,并构建一个完整的工作队列系统。开发人员只需构建一个容器,该容器可以在文件系统上获取输入数据文件,并将其转换为输出文件;这个容器将成为工作队列的一个阶段。所有涉及开发完整工作队列的其他工作都可以由通用工作队列框架来处理,该框架可以在需要此类系统时重用。如下图所示,说明了用户代码集成到共享工作队列框架中的方式。



3.3 分散/聚集模式

最后一个多结点模式是分散/聚集模式。在这样的系统中,外部客户端向“根”或“父”节点发送初始请求。该root将请求发送给大量服务器并行执行计算。每个分片都会返回部分数据,并且root将这些数据收集到原始请求的单个响应中。这种模式在搜索引擎中很常见。开发这样一个分布式系统涉及大量的样板代码:分散请求,收集响应,与客户端交互等。这些代码中的大部分都是非常通用的,而且在面向对象的编程中,可以重构通过这种方式可以提供一个可以与任意容器一起使用的实现,只要它们实现了特定的接口就行。特别是,要实现分散/收集系统,用户需要提供两个容器:

叶节点计算的容器;该容器执行部分计算并返回相应的结果。

合并容器;这个容器获取所有叶子容器的聚合输出,并将它们分组为单个响应。

通过提供实现这些相对简单的接口的容器,可以很容易地看到用户如何实现任意深度的分散/聚集系统(如果需要的话,还包括父项)。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: