学习啦>学习电脑>操作系统>操作系统基础知识>

分布式操作系统Yarn

佳洲分享

  基于Yarn的分布式操作系统我们要怎么构想呢?下面由学习啦小编为大家整理了分布式操作系统Yarn相关知识,希望对大家有帮助!

  基于Yarn的分布式操作系统

  前言

  很多东西都不是突然被发明的,一定会有积累的过程,也就是说他依赖的一些关键技术得到解决,这好比燃烧,一定要到了燃点才能烧的起来。

  比如,深度学习,很早之前就提出来了,但是现在才火起来,究其原因,是因为刚提出来的时候有两个硬性条件当时达不到

  计算能力不足(现在GPU都搞起来了,而且动则几千台服务器,单机服务器性能也提升不是一丁点)

  数据规模(如果数据太少,解决不了过拟合问题)

  随着大数据以及计算机计算能力的发展,条件具备了,才让现在的深度学习成为可能。

  同样的,关于分布式操作系统,很早就被提出来了,但是却一直没有被实现,也没有被重视,原因也在此,以前的条件不具备,但是现在具备了。

  同样的,关于分布式操作系统,很早就被提出来了,但是却一直没有被实现,也没有被重视,原因也在此,以前的条件不具备,但是现在具备了。

  现在国内有人在提‘数据分布式操作系统’,基于Mesos来实现的,完成了一套大数据栈的集成,为分布式操作系统卖出了比较坚实的一步。

  分布式操作系统组件

  作为一个分布式操作系统,我们看看到都有哪些组件:

  分布式调度内核 (Yarn,通常我们会将Yarn再Wrap一层,也就是说Yarn是内核,再Wrap的那一层就是用户层了)

  分布式文件系统 (HDFS)

  进程模型 (Docker容器)

  服务注册API(Zookeeper)

  进程异步通讯模型(消息队列)

  进程通讯模型(HTTP/RPC)

  系统组件(针对Yarn编程即可)

  应用程序(Web,MySQl,Hadoop/Spark等)

  UI系统(Web化可视界面)

  在分布式系统中,一个应用的计算能力是通过多进程多线程协调来完成的。而单机的应用则更多的是依赖于多线程来完成。

  进程的交互一般避免使用共享内存,而是通过‘进程异步通讯模型’中的消息队列,或者直接通过HTTP/RPC来完成进程之间通讯。

  进程通讯无法直接感知对方,而必须通过分布式系统的内核级别服务’服务注册API’来完成。

  Yarn 分布式操作系统调度内核

  大资源的概念

  我在之前的文章里面提到:

  未来应用服务的话,也应该是放到一个资源池中,而不是传统的单一应用池。比如现在很多公司是把不同的服务种类单独成一个池子来进行维护管理,其实是将一个大池子划分为N个小池子,每个小池子功能比较单一。也就是说,现在的部署模式是大池子的一个特定实现而已。通过Yarn将所有的节点管理起来后,未来部署只是做资源申请,比如我要多少内存,多少CPU,启动多少个实例,然后Yarn根据大池子将资源分配出来,启动起来。启动后的实例都运行在Docker容器里。Yarn的资源隔离做的很差的,但是Docker在这块做的很好。按我刚才说的,如果调度策略是小池子,单一服务,那么就会形成现在传统的部署方式。如果是完全动态弹性的,则看起来会比较混乱,不同服务的实例混合运行,但对机器来说却没有混乱的概念。另外我们基于Yarn也可以完全取代kubernetes,比如完全可以基于Yarn来实现实例数稳定的功能。我们可以基于Yarn开发一套长期运行的程序,然后监控实例数,如果实例低于阈值,则重新做资源申请,保证实例不低于阈值。

  Yarn这种分布式调度系统有效的将多机变成了一个大的资源池,并且提供了一个很好的编程接口让你去控制对应的节点。

  其实很多公司现在的服务器利用率都很低,因为机器申请是按峰值来算的,为了保证稳定还要溢出25%–50%的计算/存储能力,所以一般一个集群利用率能达到50%就了不起了。大资源意味着可以动态调度,极端情况可以在低峰时引入离线计算任务,保证了服务器高利用率。

  MapReduce/Spark/MPI等工具在分布式系统的定位

  Yarn的可编程性让我们可以开发一些系统组件,从而让系统有了新的能力,比如MapReduce/Spark 等,让分布式系统有了执行批量离线(或者准实时)的功能。我们认为这是对分布式系统的一种增强。因为这套应用是直接基于分布式系统内核编程的。

  分布式系统的自动容量规划机制

  我们发现单机桌面软件运行时,大部分情况是不需要你写资源申请的。而事实上,即使在实际的线上部署,部署者也很难确切的知道我应该要多少CPU,多少内存比较合理,当然,磁盘理论可以预估的。

  前面我们提到,类似于Windows的注册表,一个进程启动后需要将自己告知系统,而且他如果要调用其他的进程需要通过分布式系统的注册API来完成,一旦获得依赖的其他进程信息,则通过操作系统提供的异步通讯模型-消息队列,或者直接的通讯模型(HTTP/RPC)来完成实际的数据传递。

  由此,我们可以知道,当一个服务被启动,分布式系统很容获取到这个应用的依赖,包括对外的RPC调用,Http调用,数据库调用,缓存调用(比如在ServiceFramework里,这些调用关系是可以通过配置文件静态分析出来的)。这和安卓一样,一个应用需要申明他是否需要联网,是否需要自启动,是否需要XXX。用户只需要提供一个预估调用量,或者需要他能承受的一个调用量给系统,系统结合这些数值,可以自动计算出需要启动多少个容器,配置多少CPU,多少内存,计算的方式非常多,其中还有一个小技巧,是可以参看有着类似外部依赖的已经部署在线上的服务,参看他的数值。当然,用户也可以直接通过配置文件告诉系统自己需要的资源申请。

  系统一旦计算出来后,用户确认即可,防止出现错误,这个时候,系统采用的是贪婪算法,它会采用比预估值大一倍的容量来启动这个服务群集。接着根据实际运行结果,比如一周的运行数据(各个容器的CPU,内存等)),来确定一个更合适的值,这个时候可以通过服务的自动伸缩性来解决减少服务的。

  服务注册API(Zookeeper)

  我们都知道Windows有注册表,而Linux则是通过一些环境变量甚至默认的存储路径来让一个应用可以感知到另一个应用。

  在分布式操作系统中,对应的组件API是Zookeeper。现在有大量的应用依赖于Zookeeper,从而实现进程之间的消息互通,实现协调。所以把Zookeeper变成注册表的标准实现,我想也不为过。

  进程模型

  分布式系统中,任何应用都需要被被容器给包裹后才能运行(除了一些系统组件除外)。容器解决了分布式系统中的资源隔离,环境打包两个非常重要的特性。因为分布式系统大资源池的概念使得多租户是必须的。

    3630810