当前位置: 首页 > 科技观察

以简单的方式创建分布式应用

时间:2023-03-12 18:10:37 科技观察

面对计算密集型任务,除了多进程,就是分布式计算。如何使用Python实现分布式计算?今天分享一个很简单的方法,就是借助Ray。什么是RayRay是一个基于Python的分布式计算框架,采用动态图计算模型,提供简单通用的API来创建分布式应用程序。使用起来非常方便。可以使用装饰器对代码进行极少的修改,让原本运行在单机上的Python代码轻松实现分布式计算,目前多用于机器学习。Ray的特点:1.为构建和运行分布式应用程序提供简单的原语。2.使用户能够在很少甚至零代码更改的情况下并行化独立代码。3.RayCore包括一个庞大的应用程序、库和工具生态系统,以支持复杂的应用程序。例如Tune、RLlib、RaySGD、Serve、Datasets、Workflows。安装Ray官方版最简单的安装方式:pipinstall-Uraypipinstall'ray[default]'如果是Windows系统,需要安装VisualC++runtime。其他安装方式请参考官方文档。使用Ray作为装饰器来处理分布式计算:importrayray.init()@ray.remotedeff(x):returnx*xfutures=[f.remote(i)foriinrange(4)]print(ray.get(futures))#[0,1,4,9]先执行ray.init(),然后在执行分布式任务的函数前添加装饰器@ray.remote,实现分布式计算。装饰器@ray.remote也可以装饰一个类:importrayray.init()@ray.remoteclassCounter(object):def__init__(self):self.n=0defincrement(self):self.n+=1defread(self):returnsself。ncounters=[Counter.remote()foriinrange(4)]tmp1=[c.increment.remote()forcincounters]tmp2=[c.increment.remote()forcincounters]tmp3=[c.increment.remote()forcincounters]期货=[c.read.remote()forcincounters]print(ray.get(futures))#[3,3,3,3]当然,上面的分布式计算还是在自己的电脑上进行,只是以分布式的形式.程序执行过程中,可以输入http://127.0.0.1:8265/#/查看分布式任务的执行情况:那么如何实现Ray集群计算呢?然后往下看。使用RayClusteringRay的优势之一是能够在同一程序中利用多台机器。当然,Ray可以在一台机器上运行,因为通常情况下,你只有一台机器。但真正的力量在于在一组机器上使用Ray。Ray集群由一个头节点和一组工作节点组成。需要先启动头节点,将头节点的地址分配给worker节点,形成集群:可以使用RayClusterLauncher配置机器,启动多节点Ray集群。您可以在AWS、GCP、Azure、Kubernetes、阿里云、本地和Staroid上使用集群启动器,甚至可以在您的自定义节点提供商上使用。Ray集群还可以利用RayAutoscaler,它允许Ray与云提供商交互,根据规范和应用程序工作负载请求或释放实例。现在,让我们快速演示一下Ray集群的功能。这里我们使用Docker启动两个Ubuntu容器来模拟集群:环境一:172.17.0.2作为头节点环境二:172.17.0.3作为工作节点,可以有多个工作节点具体步骤:1.下载ubuntuimagedockerpullubuntu2.启动ubuntu容器并安装依赖-f"{{.NetworkSettings.IPAddress}}"ubuntu-01172.17.0.2$dockerinspect-f"{{.NetworkSettings.IPAddress}}"ubuntu-02172.17.0.3然后在容器内安装python、pip、rayaptupdate&&aptinstallpython3aptinstallpython3-pippip3installray3。启动头节点和worker节点,选择其中一个容器作为头节点,这里选择172.17.0.2,执行:raystart--head--node-ip-address172.17.0.2默认端口为6379,可以使用--port参数修改默认端口,启动后结果如下:忽略警告,可以看到有提示,如果要绑定其他节点到头部,可以这样做:raystart--address='172.17.0.2:6379'--redis-password='5241590000000000'在另外一个节点上执行上面的命令,启动worker节点:如果要关闭,执行:raystop4,执行任务,选择一个节点在随机执行以下脚本,修改ray.init()函数参数:fromcollectionsimportCounterimportsocketimporttimeimportrayray.init(address='172.17.0.2:6379',_redis_password='5241590000000000')print('''Thisclusterconsistsof{}nodesintotal{}CPUResourcesintotal'''.format(len(ray.nodes()),ray.cluster_resources()['CPU']))@ray.remotedeff():time.sleep(0.001)#ReturnIPaddress.returnsocket.gethostbyname(socket.gethostname())object_ids=[f.remote()for_inrange(10000)]ip_addresses=ray.get(object_ids)print('Tasksexecuted')forip_address,num_tasksinCounter(ip_addresses).items():print('{}taskson{}'.format(num_tasks,ip_address))执行结果如下:可以看到172.17.0.2执行了4751个任务,172.17.0.3执行了5249个任务,实现了分布式计算的效果。终于有了Ray,不用Python的多进程就可以实现并行计算。现在的机器学习主要是计算密集型任务,没有分布式计算速度会很慢。Ray提供了一个简单的解决方案来实现分布式计算。官方文档提供了非常详细的教程和示例,有兴趣的可以多了解下。如果有帮助,不妨点个关注,每天学习一些Python技能。