赞
踩
作者 | wandb.ai
编译 | OneFlow社区
(原标题为“Ion Stoica:Spark,Ray和企业开源”)
Spark和Ray,一个是开源于2010年,专为大规模数据处理而设计的快速通用的计算引擎,另一个则是开源于2018年,由UC Berkeley RISELab推出的新一代高性能分布式计算框架,两者都已成为开源领域备受关注的明星项目,而它们成长的背后都离不开一个核心人物,Ion Stoica。
Ion Stoica 是分布式计算框架 Spark 和 Ray 的联合发起者,也是Databricks的原CEO,Databricks 和 Anyscale 的联合创始人兼执行主席。他还是加州大学伯克利分校的计算机科学教授和 RISELab的首席研究员。RISELab 是一个运作长达五年且致力于开发低延迟、智能决策技术的研究实验室,并孵化了过去十年中出现的许多令人兴奋的创业公司。
Spark和Ray不仅是业界影响力很大的开源项目,它们都以开源项目为基础发展成为商业上非常成功的公司。他们一定是做对了一连串难而正确的事才有今天,他们到底做对了什么?
在机器学习节目《Gradient Dissent》中,主持人Lukas Biewald与Ion Stoica进行了一场深度访谈,从中我们可以通过第一手资料了解到发起Spark和Ray、成立创业公司、重视开源、拥抱云这一系列关键决策是怎么做的。通过这篇文章,希望朋友们能找到Spark和Ray成功的秘笈。
1
Ray:如何解决分布式程序开发面临的性能和灵活性挑战
Lukas:很多听这个访谈的人都会知道Ray和Anyscale,但对于那些从事机器学习工作的人来说,他们并不知道Anyscale以及它在做什么。
Ion:基本来讲,如果你看一下新型应用的需求,比如机器学习应用或数据应用,其增长速度远远快于单个节点或单个处理器的能力。即使你考虑了专用硬件如GPU、TPU等,情况也是一样的。因此,除了用分布式技术处理这些工作负载之外,似乎没有其他办法了。
现在,编写分布式应用非常困难。而且,如果越来越多的应用采用分布式的形式,那么人们希望通过分布式来扩展工作负载的愿望与大多数程序员所拥有的专业知识之间的差距就会越来越大。
所以,在讨论Databricks之前,让我先从Ray说起。Ray的目标是让编写分布式应用变得更容易,通过提供一个非常灵活和极简的API来做到这一点。除此之外,我们还拥有非常强大的分布式库的生态。可能很多人都知道它们,比如用于强化学习的RLlib,用于超参数调优的Tune,以及最近的Serve,还有许多其他第三方库,如XGBoost、Horovod等。
归根结底,如果你查看最流行的语言,例如Java或Python,它们最成功并不是因为它们是最好的语言,而是因为他们有一个强大的库的生态,当然,这个worse is better的观点仍值得商榷。开发人员喜欢库,因为如果你有用于特定应用程序或工作负载的库,只需要调用一些API就可以完成,而不用编写数千行代码。
现在Ray是开源的。Anyscale是Ray的云托管产品。我们致力于构建开发、部署和管理Ray的最佳平台。这意味着当你在生产中部署应用时有更高的可用性、更好的安全性、自动扩容功能、工具和监控。
在开发人员方面,我们试图为他们提供无限笔记本电脑体验的错觉。我们完成的一项调查表明,大多数机器学习开发人员仍然喜欢他们的笔记本电脑,他们仍然在笔记本电脑上做很多事情。
我们希望在笔记本电脑上保留使用编辑器等工具的体验的同时,也希望将其扩展到云端。所以当你在笔记本电脑上做任何事情,你可以在云端处理。我们将应用打包到云端,在云端运行,自动扩容,它非常透明。这就是Anyscale提供的服务。但实际上Anyscale和Ray的目的都在于尽可能简单地扩展应用程序,尤其是机器学习应用程序。
Lukas:你在Ray和Anyscale上投入了很多工作,但显然很长一段时间以来都存在一个问题:是什么让开发一个简单的分布式框架真正具有挑战性?
Ion:这是一个好问题。我们学到的一个教训是,在某种意义上,用户和开发人员真正优先考虑的是性能和灵活性,甚至超过可靠性。
举几个例子,当我们开始开发Ray时,我们只用了任务抽象(Task),它们没有副作用(side-effect free)。任务从存储中获得一些输入,并在该输入上进行计算,将结果存储在此,然后可以被另一个任务消费。
这是一个非常简单的模型,你可以在此基础上构建一个非常强大的系统。这是我们从Spark中学到的经验:如果你丢失了一些数据,那可以保留最初创建该数据的任务链。基于无副作用的任务,一旦知道任务的顺序,就可以重新执行任务。如果任务无副作用并且它们是确定性的,那么重新执行将获得同样的输出。我们对这样的性质很满意。
但后来人们开始想要更高的性能,事情开始变得分崩离析。
对于GPU,你并不只是想运行任务、获取数据和存储数据。因为即使从RAM、计算机内存、GPU内存中传输数据,这也很昂贵。然后,如果你的任务也是像TensorFlow一样执行这个操作,启动它,初始化所有变量,至少需要几秒钟。实际上会花更长时间。
这种开销开始有点令人望而却步。人们希望状态实际上保留在GPU上,这就导致你不再继续享受那种纯粹(pure)无副作用的任务。这进而导致要提供非常好的容错性模型要困难得多。
还有另外一个例子,人们使用强化学习,并把它用于模拟或仿真、游戏。有些游戏不是开源的,对于这些不开源的游戏,它们会有隐藏在内部的状态。
它不会为你提供状态,你无法提取内部状态,它们让你采取向左、向右移动的操作,你只能看屏幕并阅读屏幕。
正因如此,我们必须用actor这样的抽象,但是用了actor,提供容错能力会变得更困难。我们在Ray的第一篇论文中尝试过,假设在每种类型的actor中,都有一个顺序性的单独线程。这样,基本上,你可以对在actor上执行的方法进行排序。通过顺序化,每执行一个命令,就记录下来,然后可以重新执行来重建状态。
但你猜猜怎么了?人们开始使用多线程。即使多线程在Python中不能很好的工作,他们仍然在使用它。然后我们就想要简化它,并尝试在多线程场景仍提供一些容错性。
我们就增加了以下限制:如果你创建一个actor,只有创建actor的一方才能调用该actor上的方法。对actor方法的调用只有一个来源,所以至少让序列化操作仍是可行的。
但后来,人们开始想做一些类似参数服务器的事情。对于参数服务器,不仅actor的创建者希望访问它,还可以通过另外一群actors来访问——所以其他人也需要调用actor的方法。这种来自不同actor或任务提交的不同方法就导致了复杂的并发行为。
因此,从某种意义上说,所有这些都增加了复杂性。如果你谈论容错性,它仍
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。