• 关于

    高并发 python

    的搜索结果

回答

首先强调背景: 1、GIL是什么?GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。 2、每个CPU在同一时间只能执行一个线程(在单核CPU下的多线程其实都只是并发,不是并行,并发和并行从宏观上来讲都是同时处理多路请求的概念。但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。)在Python多线程下,每个线程的执行方式:1、获取GIL2、执行代码直到sleep或者是python虚拟机将其挂起。3、释放GIL可见,某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。在Python2.x里,GIL的释放逻辑是当前线程遇见IO操作或者ticks计数达到100(ticks可以看作是Python自身的一个计数器,专门做用于GIL,每次释放后归零,这个计数可以通过 sys.setcheckinterval 来调整),进行释放。而每次释放GIL锁,线程进行锁竞争、切换线程,会消耗资源。并且由于GIL锁存在,python里一个进程永远只能同时执行一个线程(拿到GIL的线程才能执行),这就是为什么在多核CPU上,python的多线程效率并不高。

ylrf1212 2019-12-02 01:06:16 0 浏览量 回答数 0

回答

python 是一种解释性脚本语言,不像c++/java那样的高级语言,需要编译成字节码之后才能运行,python可以边运行边解释。python 主要应用于以下几个领域: web开发,基于python产生了许多优秀的web框架,像django[https://www.djangoproject.com/],web.py[http://baike.baidu.com/view/5493106.htm?fr=aladdin],许许多多伟大的开源社区的程序员为它们贡献了诸多的开源库,使得开发起来十分便捷。 爬虫开发,实际上这个只是一个小小的应用,基于python的http库有很多,比如常见的httplib,urllib2,requests等, 都很好的封装了http协议中的post,get等方法,也很方便的能够模拟浏览器去实现自己想要的功能,并且,对网页的解析也有诸多工具可以使用,如beautifulsoup等。 科学计算,不得不提的是python在科学计算领域也应用越来越广,如物理学领域,各种实验数据的处理以及相关实验模拟等,机器学习领域也产生了诸多的开源库,如sklearn,里面集成了机器学习领域常见的算法,接口良好,文档丰富,也有最近十分火热的Deep Learning的开源库,如theano。 高性能服务器后端,高性能不是说python执行有多快,其实python还是比较慢的,但是在开发高并发,高吞吐率的服务器的时候,还是具有自己独特的优势。 还有一切边边角角的应用,比如开发界面程序,QT也提供了python的支持,因为python的开源库中包括了对c/c++ lib库的调用。

红鱼 2019-12-02 01:06:55 0 浏览量 回答数 0

回答

python 是一种解释性脚本语言,不像c++/java那样的高级语言,需要编译成字节码之后才能运行,python可以边运行边解释。python 主要应用于以下几个领域: web开发,基于python产生了许多优秀的web框架,像django[https://www.djangoproject.com/],web.py[http://baike.baidu.com/view/5493106.htm?fr=aladdin],许许多多伟大的开源社区的程序员为它们贡献了诸多的开源库,使得开发起来十分便捷。 爬虫开发,实际上这个只是一个小小的应用,基于python的http库有很多,比如常见的httplib,urllib2,requests等, 都很好的封装了http协议中的post,get等方法,也很方便的能够模拟浏览器去实现自己想要的功能,并且,对网页的解析也有诸多工具可以使用,如beautifulsoup等。 科学计算,不得不提的是python在科学计算领域也应用越来越广,如物理学领域,各种实验数据的处理以及相关实验模拟等,机器学习领域也产生了诸多的开源库,如sklearn,里面集成了机器学习领域常见的算法,接口良好,文档丰富,也有最近十分火热的Deep Learning的开源库,如theano。 高性能服务器后端,高性能不是说python执行有多快,其实python还是比较慢的,但是在开发高并发,高吞吐率的服务器的时候,还是具有自己独特的优势。 还有一切边边角角的应用,比如开发界面程序,QT也提供了python的支持,因为python的开源库中包括了对c/c++ lib库的调用。

红鱼 2019-12-02 01:06:55 0 浏览量 回答数 0

回答

python 是一种解释性脚本语言,不像c++/java那样的高级语言,需要编译成字节码之后才能运行,python可以边运行边解释。python 主要应用于以下几个领域: web开发,基于python产生了许多优秀的web框架,像django[https://www.djangoproject.com/],web.py[http://baike.baidu.com/view/5493106.htm?fr=aladdin],许许多多伟大的开源社区的程序员为它们贡献了诸多的开源库,使得开发起来十分便捷。 爬虫开发,实际上这个只是一个小小的应用,基于python的http库有很多,比如常见的httplib,urllib2,requests等, 都很好的封装了http协议中的post,get等方法,也很方便的能够模拟浏览器去实现自己想要的功能,并且,对网页的解析也有诸多工具可以使用,如beautifulsoup等。 科学计算,不得不提的是python在科学计算领域也应用越来越广,如物理学领域,各种实验数据的处理以及相关实验模拟等,机器学习领域也产生了诸多的开源库,如sklearn,里面集成了机器学习领域常见的算法,接口良好,文档丰富,也有最近十分火热的Deep Learning的开源库,如theano。 高性能服务器后端,高性能不是说python执行有多快,其实python还是比较慢的,但是在开发高并发,高吞吐率的服务器的时候,还是具有自己独特的优势。 还有一切边边角角的应用,比如开发界面程序,QT也提供了python的支持,因为python的开源库中包括了对c/c++ lib库的调用。

元芳啊 2019-12-02 01:04:40 0 浏览量 回答数 0

回答

1,线程(Thread) 使用多线程可以有效的利用CPU资源(Python例外)。然而多线程所带来的程序的复杂度也不可避免,尤其是对竞争资源的同步问题。 然而在python中由于使用了全局解释锁(GIL)的原因,代码并不能同时在多核上并发的运行,也就是说,Python的多线程不能并发,使用多线程来改进自己的Python代码后,程序的运行效率却下降了。 实际上使用多线程的编程模型是很困难的,程序员很容易犯错,这并不是程序员的错误,因为并行思维是反人类的,我们大多数人的思维是串行,而且冯诺依曼设计的计算机架构也是以顺序执行为基础的。所以如果你总是不能把你的多线程程序搞定。 Python提供两组线程的接口:一是thread模块,提供基础的,低等级(Low Level)接口,使用Function作为线程的运行体。还有一组是threading模块,提供更容易使用的基于对象的接口(类似于Java),可以继承Thread对象来实现线程,还提供了其它一些线程相关的对象。例如Timer,Lock : 使用thread模块的例子: import threaddef worker(): """thread worker function""" print 'Worker' thread.start_new_thread(worker) 使用threading模块的例子: import threadingdef worker(): """thread worker function""" print 'Worker' t = threading.Thread(target=worker)t.start() 2,进程 (Process) 由于前文提到的全局解释锁的问题,Python下比较好的并行方式是使用多进程,这样可以非常有效的使用CPU资源,并实现真正意义上的并发。当然,进程的开销比线程要大,也就是说如果你要创建数量惊人的并发进程的话,需要考虑一下你的机器是不是有一颗强大的心。 Python的mutliprocess模块和threading具有类似的接口。 from multiprocessing import Process def worker(): """thread worker function""" print 'Worker' p = Process(target=worker)p.start()p.join() 由于线程共享相同的地址空间和内存,所以线程之间的通信是非常容易的,然而进程之间的通信就要复杂一些了。常见的进程间通信有: 管道,消息队列,Socket接口(TCP/IP)等等Python的mutliprocess模块提供了封装好的管道和队列,可以方便的在进程间传递消息。 Python进程间的同步使用锁,这一点和线程是一样的。 另外,Python还提供了进程池Pool对象,可以方便的管理和控制线程。 3,远程分布式主机 (Distributed Node) 随着大数据时代的到临,数据的计算和处理需要分布式的计算机网络来运行,程序并行的运行在多个主机节点上,已经是现在的软件架构所必需考虑的问题。 远程主机间的进程间通信有几种常见的方式 TCP/IP TCP/IP是所有远程通信的基础,然而API比较低级别,使用起来比较繁琐,所以一般不会考虑 ; 远程方法调用 Remote Function Call RPC是早期的远程进程间通信的手段。Python下有一个开源的实现RPyC ; 远程对象 Remote Object 远程对象是更高级别的封装,程序可以想操作本地对象一样去操作一个远程对象在本地的代理。

元芳啊 2019-12-02 01:09:33 0 浏览量 回答数 0

回答

关于python进程,线程,协程的关系。 1.进程可以按cpu核数去并发。 2.线程严格上说不是真正的多线程,因为GIL全局解释锁(这个自己去百度) 3.协程又叫微线程,这个本身只占用一个线程。是基于程序级切换。本身有自己的寄存器进行上下文切换。 所以协程真正支持成千上万的并发。 但是缺点也很明显,只能用一个核的cpu不能解决高利用。那么最佳搭配来了。 多进程+协程。 python并发推荐多进程+协程。

游客aasf2nc2ujisi 2019-12-02 03:10:10 0 浏览量 回答数 0

问题

pylot压力测试支持linux和windowsWebService性能和扩展性的工具

自娱自乐 2019-12-01 21:46:20 10158 浏览量 回答数 1

回答

OSC 第 128 期高手问答 -- Python3 开发实战 @壁_花 @idisikx @hell0cat @DarkAngel @北京老爷们儿      恭喜以上五位网友或获得《Python Web开发实战》图书一本  请私信 @博文视点   告知快递信息(格式:姓名+电话+地址+邮编号码)!  ######@dongwm :不知作者有没有涉及过大数据方向的?我看部分大数据相关的都要用到python这是为什么?Hadoop整个生态圈都是Java的,python的定位是什么?######@dongwm :其实我是一个狂热的Python爱好者,但是还是想问: 用Python来进行Web开发,与它的其他竞争者相比,有什么优势呢?比如,与Ruby On Rails相比,它能更敏捷(快速)地开发,用写尽量少的代码来完成任务吗?与Node.js和Golang相比,它在支持高并发、多线程、执行性能等方面有什么优势吗?如果一些性能方面的优化可以通过编写C扩展模块,或者通过cffi、Boost.Python、Cython等方式进行优化,Node.js、Ruby等同样可以做到。一句话概括上面的问题就是:是什么原因吸引我们使用Python来进行Web开发呢?######@dongwm : 按照“没有银弹”一说,python应该也有自己的适用范围吧,是不是比较适用于机器学习,不适合于web开发呢?######Python被称为「胶水语言」,虽然没有「统治」哪个领域,但是基本上个个领域都把手伸了进去。 机器学习我不熟不敢妄谈是不是更合适。我只能说,Python很适合web开发######使用豆瓣很多年,很喜欢豆瓣的风格。之前一直是在网页端浏览,后来又到了手机app端。我总体感觉豆瓣的进步很快。我想问的问题是,python web一直作为豆瓣的开发首选,是因为什么?还有关于豆瓣的权限模块的设计时,python web发挥了什么优势。作为手机端app的开发,python web会起到什么作用吗?######回复 @机器猫123 : 会的。也许不会开源,但是酱厂里面确实有很多不错的实现######回复 @dongwm : 未来豆瓣会继续用python web衍生开发新的产品吗?######回复 @dongwm : 谢谢老师的回答。######豆瓣选择Python,其实是公司和语言的风格很相似的缘故吧。我们做事喜欢优雅,清晰,高效,这这好也是Python希望的。 豆瓣的基础设施基本都是使用Python完成,包含权限部分,但是Python web和权限模块设计感觉没啥直接的关系,就是抽出来的库和使用它的关系,我也没懂有什么优势或者劣势。 豆瓣app的API后端是使用PythonWeb完成的###### 引用来自“DarkAngel”的评论 @dongwm :其实我是一个狂热的Python爱好者,但是还是想问: 用Python来进行Web开发,与它的其他竞争者相比,有什么优势呢?比如,与Ruby On Rails相比,它能更敏捷(快速)地开发,用写尽量少的代码来完成任务吗?与Node.js和Golang相比,它在支持高并发、多线程、执行性能等方面有什么优势吗?如果一些性能方面的优化可以通过编写C扩展模块,或者通过cffi、Boost.Python、Cython等方式进行优化,Node.js、Ruby等同样可以做到。一句话概括上面的问题就是:是什么原因吸引我们使用Python来进行Web开发呢? 引用来自“dongwm”的评论ROR我倒没有实际的用过,不敢妄言。Python最大的优势是他是一个「胶水」语言,在工作中的各个方向都能看到Python对应的库的身影,学会Python会让你的路比较宽,但是用ruby,可能在我印象里面就是Web开发比较有名。我现在还没有发现做Web开发有比Python效率高的方式。 其实很多人都担心Python的执行效率,然而其实绝大多数情况Python足够快,不快的话要先看看自己是不是用得不对或者不好。现在硬件资源很廉价,除非上升到BAT那种规模,否者基本还没有到达讨论语言瓶颈的问题。现在豆瓣绝大多数基础设施都是使用Python开发的。在Web开发中,我们很少通过写扩展的方式提高性能,其实编程语言一般都不是网站性能的瓶颈,还可以通过其他方式解决。 之前学ROR是因为老师要求用这个,我没有用Python进行Web开发的经验,稍微有一点了解的也只是Flask或者Falcon这种轻量级的,感觉能够快速开发小巧的应用,但是不知道有哪个特别出名的应用或者网站系统是由Python开发的(比如WordPress和Discuz用的PHP,Gitlab用的Ruby,OSC好像用的是Java吧)。Python确实是一种比较万能的语言,但有点万金油却不够专精的感觉。比如在科学计算方面很流行,但是论效率不如Julia,论支持库的丰富和使用广泛度不如Matlab(特别是学校里面,教授做研究或者教学一般都会用Matlab);在系统管理方面看,能用Python干的脚本化工作,用shell或者perl基本上都能干,而且需要写的代码行数说不定更少。如果说用Python进行Web开发效率高,是有特指某一个框架吗,还是泛指? 我在写程序时首先会想到用Python,是因为喜欢tial-and-error这种方式,能够在正式写代码前确认想法能不能实现,能够让我有兴趣和信心继续下去。但真要说起来,能够提供REPL特性的语言也不少。 Python的执行效率貌似永远是Python热门的讨论话题,比如GIL的存在必须要用特殊的方式来优化。像gevent和Tornado之类的存在也适用于高并发的网络连接(不过Python在这方面的性能不一定是最高的,没有看过相关的测试)。再说Python的实现,除了最出名的CPython和PyPy之外,甚至还有为嵌入式设备开发的MicroPython(这也在另一方面说明了Python的万能性)。Dropbox的技术栈中也使用了Python,并且有开发面向性能的Python实现pyston,此外还有Stackless Python(听名字感觉很厉害,虽然其实我并没有去了解这到底是什么),但它家也在用Golang和Rust开发高性能的东西。那么,豆瓣的基础设施实现中,用Python开发的应用效率如何?也有使用除了CPython之外的实现来进行优化吗?(我是不是扯得有点偏题了?) ######回复 @dongwm : 那么用Python来开发Web,是否属于那种会带来这种优势的选择呢?或者有没有哪家公司通过把技术栈切换到Python而带来了这种进步?######回复 @dongwm : 以现在的硬件发展水平,基本上任何数量级的访问都可以通过硬件的堆砌获得支持。不过经常会看到新闻,比如某某公司将它的某某技术构架从XX语言切换到了YY语言,然后获得了性能提升、提高了稳定性、减少了部署的服务器等优势,(我记忆中有看到Twitter的新闻,PHP 7的新闻,还有一些其他的)。######豆瓣每天服务着千万级别的用户(抱歉不能说具体数字)的请求,绝大多数应用和基础设施都是Python实现的。所以应用效率不用担心。虽然可以使用C/C++的扩展提高运行效率,但是我接触的场景里面很少。相当于写扩展的维护性和成本,大家更愿意从架构,算法等方面来解决。######嚯,你的问题好长。 进行Web开发效率高算是泛指,包含django和flask。效率高也体现在它们的第三方扩展和支持比较完善,基本能想到的都有对应的项目支持,这样少造了很多轮子。###### @dongwm :python的确很好,也很强大,我也一直在用,但我大都做的和web方面没有什么联系.而我对web方面挺感兴趣,但自学起来始终不得要领,进展有点慢,大神能否讲一讲web方面的学习经验,或者flask方面的心得.又或者推荐一些关于web好的学习资源.期待您的回答并致谢.###### @dongwm :了解Python基本知识,希望学习一门Python web框架学习后端开发。之前我对部分主流框架进行了一些了解:Django,Tornado,在知乎上有一个非常活跃的群体。在框架的选择问题上,只有最适合你自己、最适合你的团队的框架。编程语言选择也是一个道理,你的团队Python最熟就用Python好了,其实大部分人是没必要太关心框架的性能的,因为你开发的网站根本就是个小站,能上1万的IP的网站已经不多了,上10万的更是很少很少。在没有一定的访问量前谈性能其实是没有多大意义的,因为你的CPU和内存一直就闲着呢。而且语言和框架一般也不会是性能瓶颈,性能问题最常出现在数据库访问和文件读写上。 ######嗯 赞同你的观点。很多人在杞人忧天。先等活到有必要讨论语言的那一天,那时候早就有钱有人有时间,哪怕Python真的不满足,重构呗######@dongwm :Python确实越来越火了,知乎就是python做的,偶尔搞了一点,发现确实很高级,至少比java语言高级一些某些功能Java只需要写100行,而Python可能只要20行。做一些外维系统还是挺方便的,比如日志的提取等,之前学的是2.7版本,现在python3比之前的版本有哪些新特性呢? ######python 3是相当于站在Python2的肩膀上,摒弃了早年设计python 2的错误思想(所以有的地方向前不兼容),加了一些新的语法,比如asyncio,甚至type hint(我不喜欢)。 具体的内容可以看 https://docs.python.org/3/whatsnew/index.html。 总体上和Python 2区别不大。不用纠结Python 2/3###### @dongwm :初入门python,有c、java基础。再看《python基础教程(第二版)》。请问您有推荐的书籍吗?######我个人在知乎专栏写过一篇推荐书的文章 https://zhuanlan.zhihu.com/p/22198827。我建议有一些其他语言基础的同学好好地看看《Python学习手册》,如果你英语比较好,建议直接看原著。《Python基础教程》虽然是一个经典的入门教程,写作风格也相对轻松幽默,但是由于本书写作于2010年,书中有大量内容已经过时,所以不推荐! ========================== Python "RemoteError: Remote error: UnicodeEncodeError 'ascii' codec can't encode ch:报错 {   "traceback": "  File \"/opt/stackstorm/st2/lib/python2.7/site-packages/st2actions/container/base.py\", line 99, in _do_run\n    LOG.debug('Performing run for runner: %s' % (runner.runner_id), extra=extra)\n  File \"/opt/stackstorm/st2/lib/python2.7/site-packages/retrying.py\", line 49, in wrapped_f\n    def wrapped_f(*args, **kw):\n  File \"/opt/stackstorm/st2/lib/python2.7/site-packages/retrying.py\", line 206, in call\n    if not self.should_reject(attempt):\n  File \"/opt/stackstorm/st2/lib/python2.7/site-packages/retrying.py\", line 247, in get\n    else:\n  File \"/opt/stackstorm/st2/lib/python2.7/site-packages/retrying.py\", line 200, in call\n    try:\n  File \"/opt/stackstorm/runners/mistral_v2/mistral_v2.py\", line 219, in run\n    result = self.start(action_parameters=action_parameters)\n  File \"/opt/stackstorm/runners/mistral_v2/mistral_v2.py\", line 256, in start\n    **options)\n  File \"/opt/stackstorm/st2/lib/python2.7/site-packages/mistralclient/api/v2/executions.py\", line 56, in create\n    return self._create('/executions', data)\n  File \"/opt/stackstorm/st2/lib/python2.7/site-packages/mistralclient/api/base.py\", line 95, in _create\n    self._raise_api_exception(resp)\n  File \"/opt/stackstorm/st2/lib/python2.7/site-packages/mistralclient/api/base.py\", line 143, in _raise_api_exception\n    error_message=error_data)\n",         "error": "RemoteError: Remote error: UnicodeEncodeError 'ascii' codec can't encode character u'\\xae' in position 169: ordinal not in range(128)\n[u'Traceback (most recent call last):\\n', u'  File \"/opt/stackstorm/mistral/lib/python2.7/site-packages/oslo_messaging/rpc/server.py\", line 155, in _process_incoming\\n    failure = None\\n', u'  File \"/opt/stackstorm/mistral/lib/python2.7/site-packages/oslo_messaging/rpc/dispatcher.py\", line 222, in dispatch\\n    if hasattr(endpoint, method):\\n', u'  File \"/opt/stackstorm/mistral/lib/python2.7/site-packages/oslo_messaging/rpc/dispatcher.py\", line 192, in _do_dispatch\\n    new_args[argname] = self.serializer.deserialize_entity(ctxt, arg)\\n', u'  File \"/opt/stackstorm/mistral/lib/python2.7/site-packages/mistral/engine/engine_server.py\", line 98, in start_workflow\\n    (rpc_ctx, workflow_identifier, utils.cut(workflow_input),\\n', u'  File \"/opt/stackstorm/mistral/lib/python2.7/site-packages/mistral/utils/__init__.py\", line 284, in cut\\n    return cut_dict(data, length=length)\\n', u'  File \"/opt/stackstorm/mistral/lib/python2.7/site-packages/mistral/utils/__init__.py\", line 198, in cut_dict\\n    v = str(value)\\n', u\"UnicodeEncodeError: 'ascii' codec can't encode character u'\\\\xae' in position 169: ordinal not in range(128)\\n\"]." }

kun坤 2020-06-15 11:08:13 0 浏览量 回答数 0

回答

python不但性能差,还有GIL这个玩意。以至于我现在对高并发计算都采取多进程的模式。多进程模式的通讯效率肯定比多线程低,而且麻烦。

半指温柔乐 2019-12-02 01:09:08 0 浏览量 回答数 0

问题

【阿里云运维部署工具AppDeploy详细教程】之1:简介安装

阚俊宝 2019-12-01 20:58:50 19988 浏览量 回答数 7

回答

1、Java是企业级开发市场的第一大语言,诞生后的20多年几乎一直是第一。2019年1月的排名 还是第一。2、Java的生态系统太强大了,Web、互联网高并发、移动开发、大数据、微服务、物联网、包括AI也可以使用Java。3、Python是脚本语言,性能本身就不行,生态系统更是不行,最近火完全是因为谷歌的开源的Tensflow,API可以使用python。但是核心是C++编写。JVM语言Scala也可以调用。AI核心是算法,不是语言。4、Java依然免费,Oracle收取的是Oracle JDK2019年1月1号以后的 维护更新费用,大量的公司使用OPen JDK,免费。5、我之前写过的文章,2019Java依然免费,你应该知道的事实真相,不要被误导 https://yq.aliyun.com/articles/6840706、所以不可能取代,就好比三轮车能不能取代飞机一样。

徐雷frank 2019-12-02 01:46:39 0 浏览量 回答数 0

问题

django使用dwebsocket报错400?报错

爱吃鱼的程序员 2020-06-05 15:56:59 0 浏览量 回答数 1

问题

django使用dwebsocket报错400 400 请求报错 

kun坤 2020-05-29 11:26:37 2 浏览量 回答数 1

问题

产品概述

nicenelly 2019-12-01 20:56:55 987 浏览量 回答数 0

问题

django服务怎么样才能全部利用cpu资源 400 请求报错 

kun坤 2020-05-30 23:00:18 3 浏览量 回答数 1

回答

Python自带:urllib,urllib2 第 三 方:requests 框 架:Scrapy urllib和urllib2模块都做与请求URL相关的操作,但他们提供不同的功能。 urllib2.:urllib2.urlopen可以接受一个Request对象或者url,(在接受Request对象时候,并以此可以来设置一个URL 的headers),urllib.urlopen只接收一个url urllib 有urlencode,urllib2没有,因此总是urllib,urllib2常会一起使用的原因 scrapy是封装起来的框架,他包含了下载器,解析器,日志及异常处理,基于多线程, twisted的方式处理,对于固定单个网站的爬取开发,有优势,但是对于多网站爬取 100个网站,并发及分布式处理方面,不够灵活,不便调整与括展。 request 是一个HTTP库, 它只是用来,进行请求,对于HTTP请求,他是一个强大的库,下载,解析全部自己处理,灵活性更高,高并发与分布式部署也非常灵活,对于功能可以更好实现. Scrapy优缺点: 优点:scrapy 是异步的 采取可读性更强的xpath代替正则 强大的统计和log系统 同时在不同的url上爬行 支持shell方式,方便独立调试 写middleware,方便写一些统一的过滤器 通过管道的方式存入数据库 缺点:基于python的爬虫框架,扩展性比较差 基于twisted框架,运行中的exception是不会干掉reactor,并且异步框架出错后是不会停掉其他任务的,数据出错后难以察觉。

茶什i 2019-12-02 03:09:05 0 浏览量 回答数 0

回答

在批评Python的讨论中,常常说起Python多线程是多么的难用。还有人对 global interpreter lock(也被亲切的称为“GIL”)指指点点,说它阻碍了Python的多线程程序同时运行。因此,如果你是从其他语言(比如C++或Java)转过来的话,Python线程模块并不会像你想象的那样去运行。必须要说明的是,我们还是可以用Python写出能并发或并行的代码,并且能带来性能的显著提升,只要你能顾及到一些事情。如果你还没看过的话,我建议你看看Eqbal Quran的文章《Ruby中的并发和并行》。 在本文中,我们将会写一个小的Python脚本,用于下载Imgur上最热门的图片。我们将会从一个按顺序下载图片的版本开始做起,即一个一个地下载。在那之前,你得注册一个Imgur上的应用。如果你还没有Imgur账户,请先注册一个。 本文中的脚本在Python3.4.2中测试通过。稍微改一下,应该也能在Python2中运行——urllib是两个版本中区别最大的部分。 1、开始动手让我们从创建一个叫“download.py”的Python模块开始。这个文件包含了获取图片列表以及下载这些图片所需的所有函数。我们将这些功能分成三个单独的函数: get_links download_link setup_download_dir 第三个函数,“setup_download_dir”,用于创建下载的目标目录(如果不存在的话)。 Imgur的API要求HTTP请求能支持带有client ID的“Authorization”头部。你可以从你注册的Imgur应用的面板上找到这个client ID,而响应会以JSON进行编码。我们可以使用Python的标准JSON库去解码。下载图片更简单,你只需要根据它们的URL获取图片,然后写入到一个文件即可。 代码如下: import jsonimport loggingimport osfrom pathlib import Pathfrom urllib.request import urlopen, Request logger = logging.getLogger(__name__) def get_links(client_id): headers = {'Authorization': 'Client-ID {}'.format(client_id)} req = Request('https://api.imgur.com/3/gallery/', headers=headers, method='GET') with urlopen(req) as resp: data = json.loads(resp.readall().decode('utf-8')) return map(lambda item: item['link'], data['data']) def download_link(directory, link): logger.info('Downloading %s', link) download_path = directory / os.path.basename(link) with urlopen(link) as image, download_path.open('wb') as f: f.write(image.readall()) def setup_download_dir(): download_dir = Path('images') if not download_dir.exists(): download_dir.mkdir() return download_dir接下来,你需要写一个模块,利用这些函数去逐个下载图片。我们给它命名为“single.py”。它包含了我们最原始版本的Imgur图片下载器的主要函数。这个模块将会通过环境变量“IMGUR_CLIENT_ID”去获取Imgur的client ID。它将会调用“setup_download_dir”去创建下载目录。最后,使用get_links函数去获取图片的列表,过滤掉所有的GIF和专辑URL,然后用“download_link”去将图片下载并保存在磁盘中。下面是“single.py”的代码: import loggingimport osfrom time import time from download import setup_download_dir, get_links, download_link logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')logging.getLogger('requests').setLevel(logging.CRITICAL)logger = logging.getLogger(__name__) def main(): ts = time() client_id = os.getenv('IMGUR_CLIENT_ID') if not client_id: raise Exception("Couldn't find IMGUR_CLIENT_ID environment variable!") download_dir = setup_download_dir() links = [l for l in get_links(client_id) if l.endswith('.jpg')] for link in links: download_link(download_dir, link) print('Took {}s'.format(time() - ts)) if name == '__main__': main()注:为了测试方便,上面两段代码可以用如下代码替代演示: coding=utf-8 测试utf-8编码 from time import sleep, timeimport sys, threading reload(sys)sys.setdefaultencoding('utf-8') def getNums(N): return xrange(N) def processNum(num): num_add = num + 1 sleep(1) print str(threading.current_thread()) + ": " + str(num) + " → " + str(num_add) if name == "__main__": t1 = time() for i in getNums(3): processNum(i) print "cost time is: {:.2f}s".format(time() - t1) 结果: <_MainThread(MainThread, started 4436)>: 0 → 1<_MainThread(MainThread, started 4436)>: 1 → 2<_MainThread(MainThread, started 4436)>: 2 → 3cost time is: 3.00s在我的笔记本上,这个脚本花了19.4秒去下载91张图片。请注意这些数字在不同的网络上也会有所不同。19.4秒并不是非常的长,但是如果我们要下载更多的图片怎么办呢?或许是900张而不是90张。平均下载一张图片要0.2秒,900张的话大概需要3分钟。那么9000张图片将会花掉30分钟。好消息是使用了并发或者并行后,我们可以将这个速度显著地提高。 接下来的代码示例将只会显示导入特有模块和新模块的import语句。所有相关的Python脚本都可以在这方便地找到this GitHub repository。 2、使用线程线程是最出名的实现并发和并行的方式之一。操作系统一般提供了线程的特性。线程比进程要小,而且共享同一块内存空间。 在这里,我们将写一个替代“single.py”的新模块。它将创建一个有八个线程的池,加上主线程的话总共就是九个线程。之所以是八个线程,是因为我的电脑有8个CPU内核,而一个工作线程对应一个内核看起来还不错。在实践中,线程的数量是仔细考究的,需要考虑到其他的因素,比如在同一台机器上跑的的其他应用和服务。 下面的脚本几乎跟之前的一样,除了我们现在有个新的类,DownloadWorker,一个Thread类的子类。运行无限循环的run方法已经被重写。在每次迭代时,它调用“self.queue.get()”试图从一个线程安全的队列里获取一个URL。它将会一直堵塞,直到队列中出现一个要处理元素。一旦工作线程从队列中得到一个元素,它将会调用之前脚本中用来下载图片到目录中所用到的“download_link”方法。下载完成之后,工作线程向队列发送任务完成的信号。这非常重要,因为队列一直在跟踪队列中的任务数。如果工作线程没有发出任务完成的信号,“queue.join()”的调用将会令整个主线程都在阻塞状态。 from queue import Queuefrom threading import Thread class DownloadWorker(Thread): def __init__(self, queue): Thread.__init__(self) self.queue = queue def run(self): while True: # Get the work from the queue and expand the tuple # 从队列中获取任务并扩展tuple directory, link = self.queue.get() download_link(directory, link) self.queue.task_done() def main(): ts = time() client_id = os.getenv('IMGUR_CLIENT_ID') if not client_id: raise Exception("Couldn't find IMGUR_CLIENT_ID environment variable!") download_dir = setup_download_dir() links = [l for l in get_links(client_id) if l.endswith('.jpg')] # Create a queue to communicate with the worker threads queue = Queue() # Create 8 worker threads # 创建八个工作线程 for x in range(8): worker = DownloadWorker(queue) # Setting daemon to True will let the main thread exit even though the workers are blocking # 将daemon设置为True将会使主线程退出,即使worker都阻塞了 worker.daemon = True worker.start() # Put the tasks into the queue as a tuple # 将任务以tuple的形式放入队列中 for link in links: logger.info('Queueing {}'.format(link)) queue.put((download_dir, link)) # Causes the main thread to wait for the queue to finish processing all the tasks # 让主线程等待队列完成所有的任务 queue.join() print('Took {}'.format(time() - ts))注:为了测试方便,上面的代码可以用如下代码替代演示: coding=utf-8 测试utf-8编码 from Queue import Queuefrom threading import Threadfrom single import *import sys reload(sys)sys.setdefaultencoding('utf-8') class ProcessWorker(Thread): def __init__(self, queue): Thread.__init__(self) self.queue = queue def run(self): while True: # Get the work from the queue num = self.queue.get() processNum(num) self.queue.task_done() def main(): ts = time() nums = getNums(4) # Create a queue to communicate with the worker threads queue = Queue() # Create 4 worker threads # 创建四个工作线程 for x in range(4): worker = ProcessWorker(queue) # Setting daemon to True will let the main thread exit even though the workers are blocking # 将daemon设置为True将会使主线程退出,即使worker都阻塞了 worker.daemon = True worker.start() # Put the tasks into the queue for num in nums: queue.put(num) # Causes the main thread to wait for the queue to finish processing all the tasks # 让主线程等待队列完成所有的任务 queue.join() print("cost time is: {:.2f}s".format(time() - ts)) if name == "__main__": main() 结果: : 3 → 4: 2 → 3: 1 → 2 : 0 → 1cost time is: 1.01s在同一个机器上运行这个脚本,下载时间变成了4.1秒!即比之前的例子快4.7倍。虽然这快了很多,但还是要提一下,由于GIL的缘故,在这个进程中同一时间只有一个线程在运行。因此,这段代码是并发的但不是并行的。而它仍然变快的原因是这是一个IO密集型的任务。进程下载图片时根本毫不费力,而主要的时间都花在了等待网络上。这就是为什么线程可以提供很大的速度提升。每当线程中的一个准备工作时,进程可以不断转换线程。使用Python或其他有GIL的解释型语言中的线程模块实际上会降低性能。如果你的代码执行的是CPU密集型的任务,例如解压gzip文件,使用线程模块将会导致执行时间变长。对于CPU密集型任务和真正的并行执行,我们可以使用多进程(multiprocessing)模块。 官方的Python实现——CPython——带有GIL,但不是所有的Python实现都是这样的。比如,IronPython,使用.NET框架实现的Python就没有GIL,基于Java实现的Jython也同样没有。你可以点这查看现有的Python实现。 3、生成多进程多进程模块比线程模块更易使用,因为我们不需要像线程示例那样新增一个类。我们唯一需要做的改变在主函数中。 为了使用多进程,我们得建立一个多进程池。通过它提供的map方法,我们把URL列表传给池,然后8个新进程就会生成,它们将并行地去下载图片。这就是真正的并行,不过这是有代价的。整个脚本的内存将会被拷贝到各个子进程中。在我们的例子中这不算什么,但是在大型程序中它很容易导致严重的问题。 from functools import partialfrom multiprocessing.pool import Pool def main(): ts = time() client_id = os.getenv('IMGUR_CLIENT_ID') if not client_id: raise Exception("Couldn't find IMGUR_CLIENT_ID environment variable!") download_dir = setup_download_dir() links = [l for l in get_links(client_id) if l.endswith('.jpg')] download = partial(download_link, download_dir) with Pool(8) as p: p.map(download, links) print('Took {}s'.format(time() - ts))注:为了测试方便,上面的代码可以用如下代码替代演示: coding=utf-8 测试utf-8编码 from functools import partialfrom multiprocessing.pool import Poolfrom single import *from time import time import sys reload(sys)sys.setdefaultencoding('utf-8') def main(): ts = time() nums = getNums(4) p = Pool(4) p.map(processNum, nums) print("cost time is: {:.2f}s".format(time() - ts)) if name == "__main__": main() 结果: <_MainThread(MainThread, started 6188)>: 0 → 1<_MainThread(MainThread, started 3584)>: 1 → 2<_MainThread(MainThread, started 2572)>: 3 → 4<_MainThread(MainThread, started 4692)>: 2 → 3 cost time is: 1.21s4、分布式任务你已经知道了线程和多进程模块可以给你自己的电脑跑脚本时提供很大的帮助,那么在你想要在不同的机器上执行任务,或者在你需要扩大规模而超过一台机器的的能力范围时,你该怎么办呢?一个很好的使用案例是网络应用的长时间后台任务。如果你有一些很耗时的任务,你不会希望在同一台机器上占用一些其他的应用代码所需要的子进程或线程。这将会使你的应用的性能下降,影响到你的用户们。如果能在另外一台甚至很多台其他的机器上跑这些任务就好了。 Python库RQ非常适用于这类任务。它是一个简单却很强大的库。首先将一个函数和它的参数放入队列中。它将函数调用的表示序列化(pickle),然后将这些表示添加到一个Redis列表中。任务进入队列只是第一步,什么都还没有做。我们至少还需要一个能去监听任务队列的worker(工作线程)。 第一步是在你的电脑上安装和使用Redis服务器,或是拥有一台能正常的使用的Redis服务器的使用权。接着,对于现有的代码只需要一些小小的改动。先创建一个RQ队列的实例并通过redis-py 库传给一台Redis服务器。然后,我们执行“q.enqueue(download_link, download_dir, link)”,而不只是调用“download_link” 。enqueue方法的第一个参数是一个函数,当任务真正执行时,其他的参数或关键字参数将会传给该函数。 最后一步是启动一些worker。RQ提供了方便的脚本,可以在默认队列上运行起worker。只要在终端窗口中执行“rqworker”,就可以开始监听默认队列了。请确认你当前的工作目录与脚本所在的是同一个。如果你想监听别的队列,你可以执行“rqworker queue_name”,然后将会开始执行名为queue_name的队列。RQ的一个很好的点就是,只要你可以连接到Redis,你就可以在任意数量上的机器上跑起任意数量的worker;因此,它可以让你的应用扩展性得到提升。下面是RQ版本的代码: from redis import Redisfrom rq import Queue def main(): client_id = os.getenv('IMGUR_CLIENT_ID') if not client_id: raise Exception("Couldn't find IMGUR_CLIENT_ID environment variable!") download_dir = setup_download_dir() links = [l for l in get_links(client_id) if l.endswith('.jpg')] q = Queue(connection=Redis(host='localhost', port=6379)) for link in links: q.enqueue(download_link, download_dir, link) 然而RQ并不是Python任务队列的唯一解决方案。RQ确实易用并且能在简单的案例中起到很大的作用,但是如果有更高级的需求,我们可以使用其他的解决方案(例如 Celery)。 5、总结如果你的代码是IO密集型的,线程和多进程可以帮到你。多进程比线程更易用,但是消耗更多的内存。如果你的代码是CPU密集型的,多进程就明显是更好的选择——特别是所使用的机器是多核或多CPU的。对于网络应用,在你需要扩展到多台机器上执行任务,RQ是更好的选择。 6、注:关于并发、并行区别与联系并发是指,程序在运行的过程中存在多于一个的执行上下文。这些执行上下文一般对应着不同的调用栈。 在单处理器上,并发程序虽然有多个上下文运行环境,但某一个时刻只有一个任务在运行。 但在多处理器上,因为有了多个执行单元,就可以同时有数个任务在跑。 这种物理上同一时刻有多个任务同时运行的方式就是并行。 和并发相比,并行更加强调多个任务同时在运行。 而且并行还有一个层次问题,比如是指令间的并行还是任务间的并行。

xuning715 2019-12-02 01:10:11 0 浏览量 回答数 0

回答

在批评Python的讨论中,常常说起Python多线程是多么的难用。还有人对 global interpreter lock(也被亲切的称为“GIL”)指指点点,说它阻碍了Python的多线程程序同时运行。因此,如果你是从其他语言(比如C++或Java)转过来的话,Python线程模块并不会像你想象的那样去运行。必须要说明的是,我们还是可以用Python写出能并发或并行的代码,并且能带来性能的显著提升,只要你能顾及到一些事情。如果你还没看过的话,我建议你看看Eqbal Quran的文章《Ruby中的并发和并行》。 在本文中,我们将会写一个小的Python脚本,用于下载Imgur上最热门的图片。我们将会从一个按顺序下载图片的版本开始做起,即一个一个地下载。在那之前,你得注册一个Imgur上的应用。如果你还没有Imgur账户,请先注册一个。 本文中的脚本在Python3.4.2中测试通过。稍微改一下,应该也能在Python2中运行——urllib是两个版本中区别最大的部分。 1、开始动手让我们从创建一个叫“download.py”的Python模块开始。这个文件包含了获取图片列表以及下载这些图片所需的所有函数。我们将这些功能分成三个单独的函数: get_links download_link setup_download_dir 第三个函数,“setup_download_dir”,用于创建下载的目标目录(如果不存在的话)。 Imgur的API要求HTTP请求能支持带有client ID的“Authorization”头部。你可以从你注册的Imgur应用的面板上找到这个client ID,而响应会以JSON进行编码。我们可以使用Python的标准JSON库去解码。下载图片更简单,你只需要根据它们的URL获取图片,然后写入到一个文件即可。 代码如下: import jsonimport loggingimport osfrom pathlib import Pathfrom urllib.request import urlopen, Request logger = logging.getLogger(__name__) def get_links(client_id): headers = {'Authorization': 'Client-ID {}'.format(client_id)} req = Request('https://api.imgur.com/3/gallery/', headers=headers, method='GET') with urlopen(req) as resp: data = json.loads(resp.readall().decode('utf-8')) return map(lambda item: item['link'], data['data']) def download_link(directory, link): logger.info('Downloading %s', link) download_path = directory / os.path.basename(link) with urlopen(link) as image, download_path.open('wb') as f: f.write(image.readall()) def setup_download_dir(): download_dir = Path('images') if not download_dir.exists(): download_dir.mkdir() return download_dir接下来,你需要写一个模块,利用这些函数去逐个下载图片。我们给它命名为“single.py”。它包含了我们最原始版本的Imgur图片下载器的主要函数。这个模块将会通过环境变量“IMGUR_CLIENT_ID”去获取Imgur的client ID。它将会调用“setup_download_dir”去创建下载目录。最后,使用get_links函数去获取图片的列表,过滤掉所有的GIF和专辑URL,然后用“download_link”去将图片下载并保存在磁盘中。下面是“single.py”的代码: import loggingimport osfrom time import time from download import setup_download_dir, get_links, download_link logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')logging.getLogger('requests').setLevel(logging.CRITICAL)logger = logging.getLogger(__name__) def main(): ts = time() client_id = os.getenv('IMGUR_CLIENT_ID') if not client_id: raise Exception("Couldn't find IMGUR_CLIENT_ID environment variable!") download_dir = setup_download_dir() links = [l for l in get_links(client_id) if l.endswith('.jpg')] for link in links: download_link(download_dir, link) print('Took {}s'.format(time() - ts)) if name == '__main__': main()注:为了测试方便,上面两段代码可以用如下代码替代演示: coding=utf-8 测试utf-8编码 from time import sleep, timeimport sys, threading reload(sys)sys.setdefaultencoding('utf-8') def getNums(N): return xrange(N) def processNum(num): num_add = num + 1 sleep(1) print str(threading.current_thread()) + ": " + str(num) + " → " + str(num_add) if name == "__main__": t1 = time() for i in getNums(3): processNum(i) print "cost time is: {:.2f}s".format(time() - t1) 结果: <_MainThread(MainThread, started 4436)>: 0 → 1<_MainThread(MainThread, started 4436)>: 1 → 2<_MainThread(MainThread, started 4436)>: 2 → 3cost time is: 3.00s在我的笔记本上,这个脚本花了19.4秒去下载91张图片。请注意这些数字在不同的网络上也会有所不同。19.4秒并不是非常的长,但是如果我们要下载更多的图片怎么办呢?或许是900张而不是90张。平均下载一张图片要0.2秒,900张的话大概需要3分钟。那么9000张图片将会花掉30分钟。好消息是使用了并发或者并行后,我们可以将这个速度显著地提高。 接下来的代码示例将只会显示导入特有模块和新模块的import语句。所有相关的Python脚本都可以在这方便地找到this GitHub repository。 2、使用线程线程是最出名的实现并发和并行的方式之一。操作系统一般提供了线程的特性。线程比进程要小,而且共享同一块内存空间。 在这里,我们将写一个替代“single.py”的新模块。它将创建一个有八个线程的池,加上主线程的话总共就是九个线程。之所以是八个线程,是因为我的电脑有8个CPU内核,而一个工作线程对应一个内核看起来还不错。在实践中,线程的数量是仔细考究的,需要考虑到其他的因素,比如在同一台机器上跑的的其他应用和服务。 下面的脚本几乎跟之前的一样,除了我们现在有个新的类,DownloadWorker,一个Thread类的子类。运行无限循环的run方法已经被重写。在每次迭代时,它调用“self.queue.get()”试图从一个线程安全的队列里获取一个URL。它将会一直堵塞,直到队列中出现一个要处理元素。一旦工作线程从队列中得到一个元素,它将会调用之前脚本中用来下载图片到目录中所用到的“download_link”方法。下载完成之后,工作线程向队列发送任务完成的信号。这非常重要,因为队列一直在跟踪队列中的任务数。如果工作线程没有发出任务完成的信号,“queue.join()”的调用将会令整个主线程都在阻塞状态。 from queue import Queuefrom threading import Thread class DownloadWorker(Thread): def __init__(self, queue): Thread.__init__(self) self.queue = queue def run(self): while True: # Get the work from the queue and expand the tuple # 从队列中获取任务并扩展tuple directory, link = self.queue.get() download_link(directory, link) self.queue.task_done() def main(): ts = time() client_id = os.getenv('IMGUR_CLIENT_ID') if not client_id: raise Exception("Couldn't find IMGUR_CLIENT_ID environment variable!") download_dir = setup_download_dir() links = [l for l in get_links(client_id) if l.endswith('.jpg')] # Create a queue to communicate with the worker threads queue = Queue() # Create 8 worker threads # 创建八个工作线程 for x in range(8): worker = DownloadWorker(queue) # Setting daemon to True will let the main thread exit even though the workers are blocking # 将daemon设置为True将会使主线程退出,即使worker都阻塞了 worker.daemon = True worker.start() # Put the tasks into the queue as a tuple # 将任务以tuple的形式放入队列中 for link in links: logger.info('Queueing {}'.format(link)) queue.put((download_dir, link)) # Causes the main thread to wait for the queue to finish processing all the tasks # 让主线程等待队列完成所有的任务 queue.join() print('Took {}'.format(time() - ts))注:为了测试方便,上面的代码可以用如下代码替代演示: coding=utf-8 测试utf-8编码 from Queue import Queuefrom threading import Threadfrom single import *import sys reload(sys)sys.setdefaultencoding('utf-8') class ProcessWorker(Thread): def __init__(self, queue): Thread.__init__(self) self.queue = queue def run(self): while True: # Get the work from the queue num = self.queue.get() processNum(num) self.queue.task_done() def main(): ts = time() nums = getNums(4) # Create a queue to communicate with the worker threads queue = Queue() # Create 4 worker threads # 创建四个工作线程 for x in range(4): worker = ProcessWorker(queue) # Setting daemon to True will let the main thread exit even though the workers are blocking # 将daemon设置为True将会使主线程退出,即使worker都阻塞了 worker.daemon = True worker.start() # Put the tasks into the queue for num in nums: queue.put(num) # Causes the main thread to wait for the queue to finish processing all the tasks # 让主线程等待队列完成所有的任务 queue.join() print("cost time is: {:.2f}s".format(time() - ts)) if name == "__main__": main() 结果: : 3 → 4: 2 → 3: 1 → 2 : 0 → 1cost time is: 1.01s在同一个机器上运行这个脚本,下载时间变成了4.1秒!即比之前的例子快4.7倍。虽然这快了很多,但还是要提一下,由于GIL的缘故,在这个进程中同一时间只有一个线程在运行。因此,这段代码是并发的但不是并行的。而它仍然变快的原因是这是一个IO密集型的任务。进程下载图片时根本毫不费力,而主要的时间都花在了等待网络上。这就是为什么线程可以提供很大的速度提升。每当线程中的一个准备工作时,进程可以不断转换线程。使用Python或其他有GIL的解释型语言中的线程模块实际上会降低性能。如果你的代码执行的是CPU密集型的任务,例如解压gzip文件,使用线程模块将会导致执行时间变长。对于CPU密集型任务和真正的并行执行,我们可以使用多进程(multiprocessing)模块。 官方的Python实现——CPython——带有GIL,但不是所有的Python实现都是这样的。比如,IronPython,使用.NET框架实现的Python就没有GIL,基于Java实现的Jython也同样没有。你可以点这查看现有的Python实现。 3、生成多进程多进程模块比线程模块更易使用,因为我们不需要像线程示例那样新增一个类。我们唯一需要做的改变在主函数中。 为了使用多进程,我们得建立一个多进程池。通过它提供的map方法,我们把URL列表传给池,然后8个新进程就会生成,它们将并行地去下载图片。这就是真正的并行,不过这是有代价的。整个脚本的内存将会被拷贝到各个子进程中。在我们的例子中这不算什么,但是在大型程序中它很容易导致严重的问题。 from functools import partialfrom multiprocessing.pool import Pool def main(): ts = time() client_id = os.getenv('IMGUR_CLIENT_ID') if not client_id: raise Exception("Couldn't find IMGUR_CLIENT_ID environment variable!") download_dir = setup_download_dir() links = [l for l in get_links(client_id) if l.endswith('.jpg')] download = partial(download_link, download_dir) with Pool(8) as p: p.map(download, links) print('Took {}s'.format(time() - ts))注:为了测试方便,上面的代码可以用如下代码替代演示: coding=utf-8 测试utf-8编码 from functools import partialfrom multiprocessing.pool import Poolfrom single import *from time import time import sys reload(sys)sys.setdefaultencoding('utf-8') def main(): ts = time() nums = getNums(4) p = Pool(4) p.map(processNum, nums) print("cost time is: {:.2f}s".format(time() - ts)) if name == "__main__": main() 结果: <_MainThread(MainThread, started 6188)>: 0 → 1<_MainThread(MainThread, started 3584)>: 1 → 2<_MainThread(MainThread, started 2572)>: 3 → 4<_MainThread(MainThread, started 4692)>: 2 → 3 cost time is: 1.21s4、分布式任务你已经知道了线程和多进程模块可以给你自己的电脑跑脚本时提供很大的帮助,那么在你想要在不同的机器上执行任务,或者在你需要扩大规模而超过一台机器的的能力范围时,你该怎么办呢?一个很好的使用案例是网络应用的长时间后台任务。如果你有一些很耗时的任务,你不会希望在同一台机器上占用一些其他的应用代码所需要的子进程或线程。这将会使你的应用的性能下降,影响到你的用户们。如果能在另外一台甚至很多台其他的机器上跑这些任务就好了。 Python库RQ非常适用于这类任务。它是一个简单却很强大的库。首先将一个函数和它的参数放入队列中。它将函数调用的表示序列化(pickle),然后将这些表示添加到一个Redis列表中。任务进入队列只是第一步,什么都还没有做。我们至少还需要一个能去监听任务队列的worker(工作线程)。 第一步是在你的电脑上安装和使用Redis服务器,或是拥有一台能正常的使用的Redis服务器的使用权。接着,对于现有的代码只需要一些小小的改动。先创建一个RQ队列的实例并通过redis-py 库传给一台Redis服务器。然后,我们执行“q.enqueue(download_link, download_dir, link)”,而不只是调用“download_link” 。enqueue方法的第一个参数是一个函数,当任务真正执行时,其他的参数或关键字参数将会传给该函数。 最后一步是启动一些worker。RQ提供了方便的脚本,可以在默认队列上运行起worker。只要在终端窗口中执行“rqworker”,就可以开始监听默认队列了。请确认你当前的工作目录与脚本所在的是同一个。如果你想监听别的队列,你可以执行“rqworker queue_name”,然后将会开始执行名为queue_name的队列。RQ的一个很好的点就是,只要你可以连接到Redis,你就可以在任意数量上的机器上跑起任意数量的worker;因此,它可以让你的应用扩展性得到提升。下面是RQ版本的代码: from redis import Redisfrom rq import Queue def main(): client_id = os.getenv('IMGUR_CLIENT_ID') if not client_id: raise Exception("Couldn't find IMGUR_CLIENT_ID environment variable!") download_dir = setup_download_dir() links = [l for l in get_links(client_id) if l.endswith('.jpg')] q = Queue(connection=Redis(host='localhost', port=6379)) for link in links: q.enqueue(download_link, download_dir, link) 然而RQ并不是Python任务队列的唯一解决方案。RQ确实易用并且能在简单的案例中起到很大的作用,但是如果有更高级的需求,我们可以使用其他的解决方案(例如 Celery)。 5、总结如果你的代码是IO密集型的,线程和多进程可以帮到你。多进程比线程更易用,但是消耗更多的内存。如果你的代码是CPU密集型的,多进程就明显是更好的选择——特别是所使用的机器是多核或多CPU的。对于网络应用,在你需要扩展到多台机器上执行任务,RQ是更好的选择。 6、注:关于并发、并行区别与联系并发是指,程序在运行的过程中存在多于一个的执行上下文。这些执行上下文一般对应着不同的调用栈。 在单处理器上,并发程序虽然有多个上下文运行环境,但某一个时刻只有一个任务在运行。 但在多处理器上,因为有了多个执行单元,就可以同时有数个任务在跑。 这种物理上同一时刻有多个任务同时运行的方式就是并行。 和并发相比,并行更加强调多个任务同时在运行。 而且并行还有一个层次问题,比如是指令间的并行还是任务间的并行。

xuning715 2019-12-02 01:10:10 0 浏览量 回答数 0

回答

本文介绍了 Serverless 工作流的回调功能。相比较轮询,使用回调有效地降低了延迟、减少了轮询对服务器造成的不必要压力。另外,回调功能配合队列可以实现对非 FC 任务的编排,将 Serverless 工作流的编排范围扩展到任意类型的计算资源。 简介 长时间执行的任务通常会采用异步提交任务并返回任务标识 (ID),判断异步任务结束的方法通常有两种:轮询 (polling)和回调 (callback),在任务状态轮询中我们介绍了使用轮询来判断任务结束。Serverless 工作流的回调 (callback)功能,覆盖以下的痛点或场景: 消除轮询周期长带来的不必要延迟。 消除大流量场景下高并发的轮询造成不必要的服务器资源压力和浪费 。 编排非 FC Function 的任务,例如运行在自建机房或 ECS 上的进程 。 需要人工干预的步骤,例如通知审批通过。 下图展示了使用 MNS 队列服务集成结合回调 API 编排自建资源,拓宽了 Serverless 工作流的适用场景。 fnf-doc-service-integration-mns-queue 回调使用详解 在 Task 步骤中指定 pattern: waitForCallback,如下图状态机所示:该步骤会在提交 resourceArn 指定的任务后(如 FC invocation)该步骤会将一个 taskToken 存入到该步骤的 context 对象并进入一个暂停的状态,直到 Serverless 工作流收到回调或指定的任务超时。将 taskToken 传入 ReportTaskSucceed 或 ReportTaskFailed 接口去回调会使得该步骤继续执行。 fnf-doc-callback-state-machine - type: task name: mytask resourceArn: acs:fc:::services/{fc-service}/functions/{fc-function} pattern: waitForCallback # 指定该 Task 步骤在提交任务后等待回调。 inputMappings: - target: taskToken source: $context.task.token # 将 context 中的 taskToken 作为 input 传入 resourceArn 指定的函数。 outputMappings: - target: k source: $local.key # 将 ReportTaskSucceeded 中 output {"key": "value"} 映射成 {"k": "value"} 并作为该步骤的输出。 示例 该示例共分为以下 3 个步骤: 准备 Task Function 开始工作流 回调 步骤 1:准备 Task Function 创建下面一个简单的函数,该函数会将输入直接返回。 服务:fnf-demo。 函数:echo。 运行环境:python2.7。 函数入口:index.handler。 #!/usr/bin/env python import json def handler(event, context): return event 步骤 2:开始工作流 在 Serverless 工作流控制台创建下面的流程,并开始执行。 流程名称:fnf-demo-callback。 流程角色:配置一个有 FC Invocation 权限的角色。 version: v1 type: flow steps: - type: task name: mytask resourceArn: acs:fc:::services/fnf-demo/functions/echo pattern: waitForCallback inputMappings: - target: taskToken source: $context.task.token outputMappings: - target: s source: $local.status 流程开始后可以看到 mytask 步骤暂停在 TaskSubmitted 事件,等待回调。该事件的 output 中含有 taskToken 作为回调任务的标识。 Screen Shot 2019-08-15 at 11.00.09 AM 步骤 3:回调 使用 Serverless 工作流的 Python SDK 在本地(或其他可以运行 Python 的环境)运行 callback.py 脚本,将 {task-token} 替换为 TaskSubmitted 事件中的值。 cd /tmp mkdir fnf-demo-callback cd fnf-demo-callback 在虚拟环境中,安装 fnf python SDK。 virtualenv env source env/bin/activate pip install -t . aliyun-python-sdk-core pip install -t . aliyun-python-sdk-fnf 执行 worker 进程。 export ACCOUNT_ID={your-account-id}; export AK_ID={your-ak-id}; export AK_SECRET={your-ak-secret} python worker.py {task-token-from-TaskSubmitted} worker.py 代码: import os import sys from aliyunsdkcore.acs_exception.exceptions import ServerException from aliyunsdkcore.client import AcsClient from aliyunsdkfnf.request.v20190315 import ReportTaskSucceededRequest def main(): account_id = os.environ['ACCOUNT_ID'] akid = os.environ['AK_ID'] ak_secret = os.environ['AK_SECRET'] fnf_client = AcsClient(akid, ak_secret, "cn-hangzhou") task_token = sys.argv[1] print "task token " + task_token try: request = ReportTaskSucceededRequest.ReportTaskSucceededRequest() request.set_Output("{"status": "ok"}") request.set_TaskToken(task_token) resp = fnf_client.do_action_with_exception(request) print "Report task succeeded finished" except ServerException as e: print(e) if name == 'main': main() 上述脚本回调成功后可以看到 mytask 步骤继续执行, ReportTaskSucceeded 中指定的输出 "{"status": "ok"}" 经过 outputMappings 的映射后变成 "{"s": "ok"}"。

1934890530796658 2020-03-27 10:49:44 0 浏览量 回答数 0

问题

阿里云运维部署工具AppDeploy详细教程

阚俊宝 2019-12-01 20:59:13 17044 浏览量 回答数 1

回答

多进程简单了解:进程之间是独立的,是操作系统自己来维护和管理的,python通过C接口起了一个进程,多进程可以充分的利用多核CPU想更好的学习python吗?如果对Python感兴趣的话,可以加群308754087,学习交流,免费听课,收益多多。创建多进程:多进程间的通信:进程间独立,如果想相互访问,就必须有一个中间翻译,下面提供了几种进程间通信的方法进程Queuefrom multiprocessing import Process,Queue# import queue#子进程,内存独立,相当于数据的传递def f(subQueue): subQueue.put("雪芙")if name == '__main__': #进程Queue q = Queue() #创建进程 p = Process(target=f,args=(q,)) #执行进程 p.start() print(q.get())Pipe多进程还有一种数据传递方式叫管道原理和 Queue相同进程锁:虽然内存独立,但是即使是打印也会造成打印数据错误,为了防止进程间抢屏幕打印输出,加了进程锁from multiprocessing import Process,Lock#子进程执行方法def f(lock,num): lock.acquire() print("tztztz",num) lock.release()if name == '__main__': lock = Lock()#循环创建100个子进程 for num in range(100): Process(target=f,args=(lock,num)).start()进程池创建一个子进程相当于copy一份父进程内存数据,为了防止频繁创建,导致内存不足,所以有了进程池作为限制协程协程又称微线程,coroutne,协程是一种用户态的轻量级线程通俗点讲就是周末我在家里休息,假如我先洗漱,再煮饭,再下载电影看会很慢,用了协程的效果就好比,我在下载电影的时候去点火煮饭,此时我马上洗漱,等我洗漱好了,饭也好了,吃完饭了,电影下好了,我可以看了协程的创建和使用 :gevent 是一个三方库,可以轻松通过gevent实现并发同步或者异步编程.Author:TianTianBabyimport gevent#函数1def first(): print('运行 1') gevent.sleep(2) print('回到1')#精确的文本内容切换到 ..#函数2def second(): print('运行2') gevent.sleep(1) print('回到2')#函数3def third(): print("运行3") gevent.sleep(0) print("回到3")#创建并添加写成任务gevent.joinall([gevent.spawn(first), #生成 gevent.spawn(second), gevent.spawn(third)])解析:尝试运行发现,运行时间为Sleep最长的时间,也就是说协程能绕过IO,进行执行,极大的提高了效率.IO(从硬盘上读一块数据,从网络读数据,从内存里读一块数据) 操作不占用CPU,计算占用CPU协程简单爬网页 :协程实现socketServer:通过协程,我们可以写出一个socketServer,真正socketServer的底层是用多线程来实现,我们用写成写出的效率很高,而且非常节省内存

xuning715 2019-12-02 01:10:38 0 浏览量 回答数 0

回答

一、前言 Java语言长期以来一直霸占多数热门编程语言榜单的榜首,可见这是一个备受程序员热捧的编程语言。Java语言具有什么魅力?想必这都是已经为大多数人们所熟知的了,不值得过多赘述。而Java语言发展至今,面对发展势头迅猛又十分简单易学的python,以及各种层出不穷的高级语言,Java程序员的份额已经逐步下降,那它是否还能在未来保持领先的优势呢?本文就主要从Java语言所不擅长的领域,以及它在自己的领土内受到的对手入手,聊一聊Java语言在未来所面临的挑战。 二、Java帝国的今天 2.1 依然霸占TIOBE热门编程语言的榜首 这是来自权威开发语言排行榜TIOBE的最新数据(截止到2020年4月),可以看到Java语言依然在语言排行榜霸占第一的位置!虽然下面Python小老弟近几年搭上大数据的热潮,发展实为迅猛,在其他一些排行榜上面甚至超越大哥,但是在TIOBE这样权威的排行榜上面,Python依旧是小老弟! 2.2 曾经想扼杀Java的微软宣布加入OpenJDK 这又是一个IT界的真香现场,Sun 公司曾以“歧视使用 Java 软件”为由起诉微软。而微软在2001年推出新版操作系统 Windows XP 时,故意不安装 Java 软件,并且推出高仿 Java 的语言 C# 和 .net 框架。在现在,微软却宣布加入OpenJDK,拥抱Java技术。微软的宇宙第一 IDE Visual Studio也开始支持Java开发(通过VS的 Visual Studio Live Share ,可以关联到VS code上面的Java项目,协同编程,间接地支持了Java开发)。 2.3 Oracle发布开源全栈虚拟机GraalVM 这是大名鼎鼎的Oracle公司搞出来的开源产品,从官网“Run Programs Faster Anywhere”这句口号和产品的命名GraalVM就可以看出,GraalVM是升级版的JVM。在GraalVM上面执行Java程序的效率更高(得益于其中的JIT编译器技术)。最牛逼的地方在于,GraalVM支持多语言应用!在GraalVM里面,多种不同的语言可以互相传递数据,支持Java、Python、Ruby、R、Scala、Kotlin,JavaScript等多种语言。 三、Java帝国受到的挑战 3.1 后端服务器开发 J2EE作为Java平台的重要组成部分,现在广泛应用于Web后台服务器开发领域,在这个领域,Java拥有很多好朋友,比如Spring框架,Mybatis和Hibernate等,使得开发者可以快速构建Web应用程序。这是Java帝国一块重要的领土,但也有很多挑战。下面就是几个强大的竞争者。 3.1.1 Python 的竞争 Python语言和Java相比,具有下面这些优点: 语法简单直观,这意味着开发速度快第三方库强大,可以写复杂的逻辑 当然Python和Java相比执行效率上肯定是更低了,因此主要应用于小型的网站后台,像阿里这样的大厂就是拥抱Java后台的了。 3.1.2 C++ 的竞争 C++语言和Java相比,具有以下优点: 执行效率高对内存管理自由,而Java由GC来管理 C++适合大型高性能的服务器开发。腾讯更多的就是使用C++进行开发,这点和阿里不同。当然C++相比Java,学习和开发的难度更高。 3.1.3 node.js 的竞争 node.js的出现大概是前端程序员最高兴的事情了,因为node.js可以让他们写的JavaScript代码运行在服务端,这样就可以使得前端不用学Java也能自己写后台,摆脱后台爸爸的束缚(误)。得益于node.js的事件驱动机制,node.js具有很高的并发性能,可以应对大规模的http请求。但也有缺点,因为js只支持单核,因此没法充分利用服务器的性能,它不适合CPU密集型应用。 3.1.4 Go 的竞争 Go语言是最近很火的开发语言,适合用于开发高性能分布式系统。这是一个十分强大的竞争对手,被认为是未来的服务端语言。它具有下面这些优点: 学习难度低,容易上手,易于维护得益于协程,并发性能优越编译型语言,执行效率高 3.1.5 小结 可以看到,在后端服务器开发领域,Java在不同方面受到多种语言的竞争,轻量小型的服务器,人们可以选择Python,node.js或者PHP。而大型高性能服务器,人们可以选择C++。Go语言就更强大,兼具了比Java更简单的语法和更高的并发性能,背后又是Google爸爸。因此,在这一领域,Java面临巨大的竞争压力。 3.2 安卓系统应用开发 Java用于安卓应用程序开发已经是很成熟的方案了,目前绝大多数的安卓应用都是用Java写的。很多安卓程序员也都是学Java过来的。但是随着新语言不断推出,和安卓应用开发方式的演变,Java慢慢不再是安卓开发的首选。比如下面这些语言,就是比较热门的选择。 3.2.1 Kotlin 成为 Android 开发的首选语言 在2019年的Google I/O 大会上,Google 官方正式宣布,Kotlin 编程语言现在是 Android 应用程序开发人员的首选语言。Java 占据 Android 开发绝对统治的时代一去不复返了。Kotlin 可以编译成Java字节码,可以在JVM上面运行,也可以编译成JavaScript,在没有JVM的机器上运行。Kotlin语言比Java更安全,更简洁,随着谷歌爸爸推崇,将来的发展前景可期。 3.2.2 Flutter 框架和 Dart 语言 这两个都是谷歌最近推出的东西,Flutter是一款用于帮助开发者在iOS和Android两个平台构建高质量原生应用的全新移动UI框架,Dart是由Google开发的一门全新的计算机编程语言,而Flutter使用Dart语言开发。Fuchsia是谷歌开发的一款全新的操作系统,Flutter 是 Fuchsia 的开发框架。Flutter编写的代码可以同时生成IOS和Android两个平台下的应用程序,因此Flutter框架逐渐热门。 3.2.3 大前端时代下的H5应用 随着时代发展,现在的前端不再只是写web网页,而是逐渐发展为大前端,web,Android,IOS通吃,H5应用的流行就是一个例子,大家应该都发现,手机上开始出现快应用,小程序这些使用前端语言进行开发的app,这些应用使用HTML,JS和CSS进行开发,无需使用Java。相比之下,H5应用轻量级,启动快,跨平台,用户体验方面也逐渐开始接近原生应用的流畅度。因此大有流行的趋势。 3.2.4 小结 这一小节介绍了安卓开发的现状,Java作为曾经的安卓开发第一首选语言,正在面临诸如Kotlin语言,Flutter和Dart语言等新的开发语言的挑战,同时,随着安卓应用开发逐渐出现H5应用的趋势,前端语言也逐渐开始来到Java的地盘。 四、Java不擅长的领域 4.1 前后端分离和JSP的没落 JSP是一度火爆的技术,Java曾对其寄予厚望,希望通过JSP技术占领web应用程序领域。然而,随着网页开发越来越复杂,用JSP开发网页变得很麻烦,前端和后端混杂在一起,开发效率很低。因此前后端开始分离,而JSP这种运行于服务器端的网页程序也就慢慢退出了舞台。 4.2 C#和.NET抢占桌面程序地盘 Java曾经也被广泛用于开发桌面客户端,其中Swing框架就是一个有名的GUI框架。然而,曾经想要扼杀Java的微软,开发了C#语言。C#成为Java的竞争对手,C#编写运行于Windows系统的桌面应用程序上具有优势,Java写的桌面应用,虽然可以跨平台到处运行,这对于程序员当然是好事,但是对于用户来说,在Windows上运行个Java程序还得安装JRE,显得十分麻烦。而且,Java桌面程序运行起来比C#程序慢。因此,C#和.NET逐渐占领了桌面应用程序的市场。 4.3 C/C++活跃的嵌入式系统领域 Java曾经是为了嵌入式系统开发而设计的。然而,Java程序员并不能直接操作硬件,并且,Java是相对较重的语言,对内存等硬件资源不友好,执行效率也相对较低。而在嵌入式系统中,往往只有很少的内存空间,却对运行效率有很高的要求。因此,在嵌入式领域,更多的是C语言和C++甚至是汇编语言的天下。 4.4 小结 这一小节主要针对Java所不擅长的领域来讨论。可以看到,Java最为有名的特性“Write once, run anywhere”,也成了它最大的缺陷:在执行效率上做不到卓越。因此,在桌面应用程序和嵌入式系统两个领域Java不是王者。而随着时代发展,前后端分离,JSP也被时代所抛弃。 五、总结 综上所述,相信大家对于Java语言有了更全面的了解,看到了Java背后的芸芸众生,各种层出不穷的高级语言和新技术,和Java相爱相杀。Java作为现在世界上最热门的编程语言,依然在各个不同的领域具有重要的地位 ,Java的强大之处在于,它十分全能,几乎没有什么是Java不能做的,但它并不都是做得最好的,我们也可以看到许许多多的竞争者在不同方面比Java语言更加优越。 但是,我写这篇文章的目的,不在于比较各个语言的优劣,各种语言都有自己的优点和缺点,我们也不必因为某种语言更好就着急转语言。总而言之,语言只是工具,各种语言之间,语法的差别都不是特别大,背后的原理也是大同小异,往往只是多了几个新特性,而语言背后的编程思维才是最重要的。

剑曼红尘 2020-04-09 14:29:42 0 浏览量 回答数 0

回答

准备工作 使用 BatchCompute-cli 命令行工具,您可以快速提交作业,可以很方便的管理作业和集群。 注意:本工具只在 python2.7, 3.4, 3.5 版本测试通过,其他python版本慎用。 提交作业 1. 提交作业 (1) 最简单的作业 如果您已经按照准备工作里的步骤配置了默认镜像、实例类型和网络类型,可以通过以下的简单命令提交一个作业。 bcs sub "echo 123" # 提交一个单任务作业,运行: echo 123 如果您没有对命令行工具进行过默认配置,需要在提交的时候指定更多的选项。 bcs sub "echo 123" -t ecs.sn1ne.large -i img-ubuntu-vpc --vpc_cidr_block 192.168.0.0/16 文档的其余示例假设您已经执行了默认的配置步骤。 (2) 提交一个python脚本作业 bcs sub "python test.py" -p ./test.py # -p 表示在作业提交前,将 test.py 打包到 worker.tar.gz,然后上传到OSS. (3) 提交一个目录(多文件)的作业 一般这种情况:src目录下有多个文件, 如: src |-- test.py |-- dep.py 而 test.py 需要依赖dep.py, 则可以将整个目录一起打包 bcs sub "python test.py" -p ./src/ # 将src目录下的所有文件打包到 worker.tar.gz, 然后上传到OSS,再提交作业 当然,您也可以一次指定多个文件(逗号隔开): cd src #进入 src 目录 bcs sub "python test.py" -p test.py,dep.py # 将这个2个文件打包到 worker.tar.gz 如果您没有进入src目录, 则需要这样提交: bcs sub "python test.py" -p src/test.py,src/dep.py # 将这个2个文件打包到 worker.tar.gz 然后您可以使用命令查看worker.tar.gz的内容: tar -tvf worker.tar.gz 应该是这样的: test.py dep.py (4) 使用挂载任务程序的方式提交作业 如果我把 test.py 上传到 oss://mybucket/test/test.py,我可以把oss://mybucket/test/ 挂载到VM的本地目录如: /home/admin/test/, 然后我就可以使用 “python /home/admin/test/test.py” 命令运行了。 这么提交即可: bcs sub "python /home/admin/test/test.py" -r oss://mybucket/test/:/home/admin/test/ 其中参数 -r oss://mybucket/test/:/home/admin/test/ ,表示只读挂载,将oss://mybucket/test/ 挂载到 /home/admin/test/. 这样就无需打包成 worker.tar.gz了。 更多提交作业的信息请用: bcs sub -h 查看帮助 其他技巧 (1) 挂载输入数据 假如我的数据已经上传到 oss://my-bucket/inputs/ 目录下面. bcs sub "python test.py" -p ./src/ -r oss://my-bucket/inputs/:/home/admin/inputs/ -r 表示只读挂载,将 oss目录oss://my-bucket/inputs/ 挂载到 /home/admin/inputs/, 你的程序可以向读取本地文件一样读取/home/admin/inputs/目录下面的文件 所有挂载的目录,不能是系统目录, 如: /bin, /usr等,建议挂载到/home/下面. 如要挂载多个目录,使用英文逗号隔开, 如: -r oss://my-bucket/inputs/:/home/admin/inputs/,oss://my-bucket/inputs2/:/home/admin/inputs2/ 如果是 Windows 镜像,可以使用下面的命令来挂载: bcs sub "python test.py" -p ./src/ -r oss://my-bucket/inputs/:D (2) 程序运行结果使用挂载自动上传 我的程序会将运行的结果写到 /home/admin/outputs/ 目录下,我想把这个目录下面的所有数据上传到oss。 bcs sub "python test.py" -p ./src/ -r oss://my-bucket/inputs/:/home/admin/inputs/ -w oss://my-bucket/outputs/:/home/admin/outputs/ -w 表示可写挂载,写入到这个目录下的数据,将会在程序运行完后,由系统自动上传到对应的 oss 目录下。 所有挂载的目录,不能是系统目录, 如: /bin, /usr等,建议挂载到/home/下面. 如要挂载多个目录,使用英文逗号隔开, 如: -w oss://my-bucket/outputs/:/home/admin/outputs/,oss://my-bucket/outputs2/:/home/admin/outputs2/ (3) 使用自定义镜像和实例类型 bcs sub "python test.py" -p ./src/ -c img=img-ubuntu-vpc:type=ecs.sn1ne.large -c 表示使用集群,后面可以指定集群ID,也可以指定AutoCluster配置。 其中AutoCluster配置格式如:img=${ImageId}:type=${InstanceType}。 img=img-ubuntu-vpc 表示使用镜像,您也可以指定自定义镜像。 type=ecs.sn1ne.large 表示使用实例类型,可以用bcs it查看支持的实例类型列表。 可以只指定-c img=${ImageId} 或者只指定 -c type=${InstanceType}, 不指定则使用使用默认镜像和默认实例类型。 (4) 使用集群 bcs sub "python test.py" -p ./src/ -c cls-xxxxxxx -c cls-xxxxxxx 表示使用集群ID cls-xxxxxxx 更多请看如何使用集群. (5) 使用Docker bcs sub "python test.py" -p ./src/ --docker myubuntu@oss://my-bucket/dockers/ myubuntu 是 localhost:5000/myubuntu 的简写, oss://my-bucket/dockers/ 表示oss docker 镜像仓库的路径。 有关如何使用Docker的详细信息请参考使用 docker。 (6) 自定义磁盘 bcs sub "python test.py" --disk system:cloud_efficiency:50,data:cloud_efficiency:200 只在使用AutoCluster时有效, 支持系统盘配置和一块数据盘(可选)的配置, 使用方法如: —disk system:cloud_efficiency:40,data:cloud_efficiency:50:/home/disk1, 中间用逗号隔开。也可以只指定系统盘,或只指定数据盘。如:—disk system:cloud_efficiency:40 默认只挂载一个系统盘,大小为40GB。 系统盘配置格式: system:< cloud_efficiency|cloud_ssd>:<40-500>, 举例: system:cloud_efficiency:40, 表示系统盘挂载40GB的高效云盘。 数据盘配置格式: data:< cloud_efficiency|cloud_ssd>:<5-2000>:,举例: data:cloud_ssd:50:/home/disk1, 表示挂载一个50GB的SSD云盘作为数据盘, Windows下只能挂载到驱动,如挂载到E盘: data:cloud_ssd:50:E. 注意:对于bcs开头的老专有实例,磁盘类型请使用ephemeral,数据盘大小的取值范围限制为:[5-1024]GB)。 查看作业 查看我的作业列表 bcs job # 查看作业列表, 或者使用简写 bcs j joblist 所有的命令都可以在后面加 -h 查看帮助, 如: bcs j -h 2. 查看作业详情 bcs j 1 # 查看列表中第1个作业详情 注意: 凡是使用序号代替ID的命令,都要在获取列表之后运行,因为获取列表后才缓存序号和ID的对应关系 jobdetail 当然,你也可以使用 bcs j job-00000000573590DB0000224F00000107,效果同 bcs j 1。 3. 查看任务详情 bcs j 1 1 # 查看作业的第1个任务详情 taskdetail 当然,你也可以使用 bcs j job-00000000573590DB0000224F00000107 task,效果同 bcs j 1 1。 4. 查看实例详情 bcs j 1 1 0 # 查看作业的第1个任务的instanceId为0的实例详情,和日志 instancedetail 当然,你也可以使用 bcs j job-00000000573590DB0000224F00000107 task 0,效果同 bcs j 1 1 0。 5. 查看作业日志 bcs log 1 # 查看作业日志 joblog 当然,你也可以使用 bcs log job-00000000573590DB0000224F00000107,效果同 bcs log 1。 多任务支持 单个任务支持 job.cfg 内容: [taskname] cmd=python test.py job_name=demo cluster=img=img-ubuntu:type=ecs.sn1.medium description=test job nodes=1 pack=./src/ read_mount=oss://bucket/input/:/home/input/ write_mount=oss://bucket/output/:/home/output/ 这个配置文件含有一个section: [taskname], 这个taskname将作为task名提交。 除了cmd 和 job_name 外,其他的选项, 都是通过 bcs sub -h 看到的长选项名称, 等同于使用命令—${option}。 2. 多任务支持 config 文件也可以配置多个任务,可以指定任务间依赖关系。 job.cfg 内容: [DEFAULT] job_name=log-count description=demo force=True deps=split->count;count->merge #下面是任务公共配置 env=public_key:value,key2:value2 read_mount=oss://bucket/input/:/home/input/ write_mount=oss://bucket/output/:/home/output/ pack=./src/ [split] cmd=python split.py cluster=img=img-ubuntu:type=ecs.sn1.medium nodes=1 [count] cmd=python count.py cluster=img=img-ubuntu:type=ecs.sn1.medium nodes=3 [merge] cmd=python merge.py cluster=img=img-ubuntu:type=ecs.sn1.medium nodes=1 [DEFAULT] section中指定job级别的配置, 其他section指定task配置, 其他section名为task名 配置项优先级: 直接在命令行中的—${option}; 优先级最高,其次task section中指定的,最后是DEFAULT section中指定的。 env, read_mount, write_mount, mount 这4个配置项, 可merge, 其他配置项遇到高优先级直接被覆盖 deps=split->count;count->merge 指定依赖, split任务运行完成后,再运行count,count运行完成后,再运行merge. cluster配置用的img和type,不同region支持是不一样的,请根据当前region具体情况设置。 (1) 关于deps 如果DAG如下: DAG 则deps配置: deps=split->count1,count2;count1->merge;count2->merge 每个dep是一对多的形式: task1->task2,taks3 多个task之间用逗号隔开,多个dep用分号隔开。 (2) 关于 pack ./src/ |-- split.py |-- ... 如果指定目录:pack=./src/, 则打包src下面的所有文件到 worker.tar.gz, 指定cmd时,需要从 ./src/目录下开始指定,如: cmd=python split.py 如果指定文件: pack=./src/split.py, 则只打包文件到worker.tar.gz, 指定cmd时,只需要指定文件名, 如: cmd=python split.py pack可以在[DEFAULT]这个section中配置,也可以在每个task中配置, 当然也可以在命令行中指定。 (3) 关于 mount read_mount 为只读挂载,将oss目录挂载到运行程序的虚拟机的文件系统中,linux可以挂载为一个目录,window下只能挂载为一个Driver,如:”E:”。 如果挂载多个,可以使用英文逗号隔开,如:read_mount=oss://bucket/input/:/home/input/,oss://bucket/input2/:/home/input2/。write_mount和mount也是如此。 write_mount 为可写挂载,将oss目录映射到运行程序的虚拟机的目录,只能映射为一个目录,如果这个目录不存在,需要程序创建一下。写入到这个目录的所有文件将会被上传到相应的oss目录。 mount可以用于 NAS 的挂载,比如: mount=nas://xxxxxx-yyy50.cn-shenzhen.nas.aliyuncs.com:/:/home/mnt/:true vpc_id=vpc-xxxxxxxxxxyyyyyy vpc_cidr_block=192.168.0.0/16 注意:使用 NAS 时要指定 vpc_id 和 cidr_block。 这里mount信息中的 true/false 指的是是否支持可写。 (4) 关于cluster 有2种格式: AutoCluster格式: cluster=img= :type= AutoCluster指定任务运行时会自动创建相应配置的集群,运行完成后自动释放掉。 Cluster格式: cluster= 运行:bcs c 可以查看我的集群,如果没有,可以自行创建。 如: bcs cc -i -t -n 3 -n 3 表示期望启动3台虚拟机来运行程序 -i img-id 指定image ID -t instance-type 指定实例类型,可以使用 bcs it 查看可用的实例类型 其他选项可以使用 bcs cc -h 查看说明。 使用集群可以大大缩短作业启动时间,但是由于集群是一直运行着的,会一直计费,请自行权衡。 (5) 关于docker 格式如: docker=myubuntu@oss://bucket/dockers/ 使用docker,需要支持docker的ImageId才能运行成功。如果你没有指定cluster,默认的imageId是支持Docker的,或者你显式指定也行,或者使用clusterId,但是这个cluster的ImageId也要支持docker才行。 这里的myubuntu全名为:localhost:5000/myubuntu,制作docker镜像的时候,前缀必须为localhost:5000/, 因此这里可以省略掉前缀。后面的oss目录,是OSS私有docker镜像仓库目录,详情请看如何使用docker。 (6) 关于nodes nodes 表示指定使用多少台虚拟机运行任务程序。 (7) 关于force force 为 True,表示如果某台虚拟机运行程序出错,整个作业不会失败,继续运行。为False,则整个作业失败。默认为False。 多实例并发 1. 说明: 本例子将启动一个作业(job),该作业包含一个任务(task), 该任务将启动2个instance,并行在2个VM中运行。 2个VM中运行的程序是一样的,都是任务sum中指定的命令”python sum.py”, 程序中使用环境变量中的 BATCH_COMPUTE_DAG_INSTANCE_ID 获取InstanceId, 用来区分Input数据。 InstanceId是从0开始递增的。 每个VM中任务程序处理完 ${InstanceId}-input.txt 数据后,将结果写入到 /home/outputs/${InstanceId}-output.txt 文件, 系统会自动上传到对应的oss目录:oss://your-bucket/sum/outputs/ 目录下。 当2个VM中的程序都运行完成后,任务结束,作业结束。 例子可以在这里下载。 上传数据文件到OSS 数据文件在 data 目录下: 0-input.txt和1-input.txt。 0-input.txt的内容: 1 20 45 1-input.txt的内容: 5 85 103 将 0-input.txt和1-input.txt 上传到: oss://your-bucket/sum/inputs/0-input.txt oss://your-bucket/sum/inputs/1-input.txt 可以使用下面的命令上传: cd data bcs oss upload 0-input.txt oss://your-bucket/sum/inputs/ bcs oss upload 1-input.txt oss://your-bucket/sum/inputs/ 查看是否上传成功 bcs oss ls oss://your-bucket/sum/inputs/ 3. 启动任务 bcs sub --file job.cfg 4. 查看结果 结果数据在 oss://your-bucket/sum/outputs/中。 可以用下面的命令查看: bcs o ls oss://your-bucket/sum/outputs/ bcs o cat oss://your-bucket/sum/outputs/0-output.txt bcs o cat oss://your-bucket/sum/outputs/1-output.txt 使用集群 使用默认的AutoCluster方式提交作业,作业等待时间可能较长。 而如果使用集群的方式,可以避免等待,大大缩短等待时间。 详细介绍,请看使用AutoCluster还是Cluster。 查看我的集群 bcs cluster # 查看我的集群列表,或者简写 bcs c创建集群 (1) 创建一个默认配置的集群 bcs cc my-cluster 默认配置:使用默认镜像和默认实例类型 ,1台机器。 (2) 创建多台机器 bcs cc my-cluster -n 3 -i img-ubuntu -t ecs.sn1.medium -n 3 表示 3台机器 -i img-ubuntu 表示使用 img-ubuntu镜像,更多镜像请看这里 -t ecs.sn1.medium 表示使用 ecs.sn1.medium 实例类型(运行:bcs it 可以查看更多)删除集群 bcs dc cls-xxxxxxx 其他请加 -h 查看帮助

1934890530796658 2020-03-30 14:54:45 0 浏览量 回答数 0

问题

五大编程语言创始人的现状如何?

珍宝珠 2020-01-08 19:09:50 728 浏览量 回答数 2

问题

阿里云服务器好用吗?怎么用?可以用来做什么?

聚优云惠 2019-12-01 21:55:53 1405 浏览量 回答数 1

问题

日志通过什么方式采集?

轩墨 2019-12-01 21:51:34 1420 浏览量 回答数 0

问题

【技术干货】原来阿里云自助实验室的系统架构是这样的啊

驻云科技 2019-12-01 21:07:14 9011 浏览量 回答数 1

问题

【开源分享】-6期- Linkis 一款支持多种计算存储引擎的企业级计算中间件

montos 2020-05-08 10:55:23 9 浏览量 回答数 1

回答

详细解答可以参考官方帮助文档 如果您初次使用阿里云关系型数据库 RDS,请参阅 阿里云关系型数据库 RDS 快速入门 系列文档,帮助您了解 RDS 并快速迁移本地数据库到 RDS 上。 My SQL快速入门 SQL Server快速入门 PostgreSQL快速入门 PPAS快速入门 数据库引擎 以下是对四种数据库引擎的介绍: 阿里云数据库 MySQL 版 MySQL 是全球最受欢迎的开源数据库,作为开源软件组合 LAMP(Linux + Apache + MySQL + Perl/PHP/Python)中的重要一环,广泛应用于各类应用。 Web2.0 时代,风靡全网的社区论坛软件系统 Discuz! 和博客平台 WordPress 均基于 MySQL 实现底层架构。Web3.0 时代,阿里巴巴、Facebook、Google 等大型互联网公司都采用更为灵活的 MySQL 构建了成熟的大规模数据库集群。 阿里云数据库 MySQL 版基于 Alibaba 的 MySQL 源码分支,经过双 11 高并发、大数据量的考验,拥有优良的性能和吞吐量。除此之外,阿里云数据库 MySQL 版还拥有经过优化的读写分离、数据压缩、智能调优等高级功能。 当前 RDS for MySQL 支持 5.5、5.6 和 5.7 版本。 阿里云数据库 SQL Server 版 SQL Server 是发行最早的商用数据库产品之一,作为 Windows 平台(IIS + .NET + SQL Server)中的重要一环,支撑着大量的企业应用。SQL Server 自带的 Management Studio 管理软件内置了大量图形工具和丰富的脚本编辑器。您通过可视化界面即可快速上手各种数据库操作。 阿里云数据库 SQL Server 版不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的 License 费用,您无需再额外支出 License 费用。 当前 RDS for SQL Server 支持以下版本: SQL Server 2008 R2 企业版 SQL Server 2012 Web版、标准版、企业版 SQL Server 2016 Web版、标准版、企业版 阿里云数据库 PostgreSQL 版 PostgreSQL 是全球最先进的开源数据库。作为学院派关系型数据库管理系统的鼻祖,它的优点主要集中在对 SQL 规范的完整实现以及丰富多样的数据类型支持,包括JSON 数据、IP 数据和几何数据等,而这些数据类型大部分商业数据库都不支持。 除了完美支持事务、子查询、多版本控制(MVCC)、数据完整性检查等特性外,阿里云数据库 PostgreSQL 版还集成了高可用和备份恢复等重要功能,减轻您的运维压力。 当前 RDS for PostgreSQL 支持 9.4/10 版本。 阿里云数据库 PPAS 版 PPAS(Postgres Plus Advanced Server)是一个稳定、安全且可扩展的企业级关系型数据库,基于全球最先进的开源数据库 PostgreSQL,并在性能、应用方案和兼容性等方面进行了增强,提供直接运行 Oracle 应用的能力。您可以在 PPAS 上稳定地运行各种企业应用,同时得到更高性价比的服务。 阿里云数据库 PPAS 版集成了账号管理、资源监控、备份恢复和安全控制等功能,并将持续地更新完善。 当前 RDS for PPAS 支持 9.3/10 版本。

2019-12-01 22:57:16 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 如果您初次使用阿里云关系型数据库 RDS,请参阅 阿里云关系型数据库 RDS 快速入门 系列文档,帮助您了解 RDS 并快速迁移本地数据库到 RDS 上。 My SQL快速入门 SQL Server快速入门 PostgreSQL快速入门 PPAS快速入门 数据库引擎 以下是对四种数据库引擎的介绍: 阿里云数据库 MySQL 版 MySQL 是全球最受欢迎的开源数据库,作为开源软件组合 LAMP(Linux + Apache + MySQL + Perl/PHP/Python)中的重要一环,广泛应用于各类应用。 Web2.0 时代,风靡全网的社区论坛软件系统 Discuz! 和博客平台 WordPress 均基于 MySQL 实现底层架构。Web3.0 时代,阿里巴巴、Facebook、Google 等大型互联网公司都采用更为灵活的 MySQL 构建了成熟的大规模数据库集群。 阿里云数据库 MySQL 版基于 Alibaba 的 MySQL 源码分支,经过双 11 高并发、大数据量的考验,拥有优良的性能和吞吐量。除此之外,阿里云数据库 MySQL 版还拥有经过优化的读写分离、数据压缩、智能调优等高级功能。 当前 RDS for MySQL 支持 5.5、5.6 和 5.7 版本。 阿里云数据库 SQL Server 版 SQL Server 是发行最早的商用数据库产品之一,作为 Windows 平台(IIS + .NET + SQL Server)中的重要一环,支撑着大量的企业应用。SQL Server 自带的 Management Studio 管理软件内置了大量图形工具和丰富的脚本编辑器。您通过可视化界面即可快速上手各种数据库操作。 阿里云数据库 SQL Server 版不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的 License 费用,您无需再额外支出 License 费用。 当前 RDS for SQL Server 支持以下版本: SQL Server 2008 R2 企业版 SQL Server 2012 Web版、标准版、企业版 SQL Server 2016 Web版、标准版、企业版 阿里云数据库 PostgreSQL 版 PostgreSQL 是全球最先进的开源数据库。作为学院派关系型数据库管理系统的鼻祖,它的优点主要集中在对 SQL 规范的完整实现以及丰富多样的数据类型支持,包括JSON 数据、IP 数据和几何数据等,而这些数据类型大部分商业数据库都不支持。 除了完美支持事务、子查询、多版本控制(MVCC)、数据完整性检查等特性外,阿里云数据库 PostgreSQL 版还集成了高可用和备份恢复等重要功能,减轻您的运维压力。 当前 RDS for PostgreSQL 支持 9.4/10 版本。 阿里云数据库 PPAS 版 PPAS(Postgres Plus Advanced Server)是一个稳定、安全且可扩展的企业级关系型数据库,基于全球最先进的开源数据库 PostgreSQL,并在性能、应用方案和兼容性等方面进行了增强,提供直接运行 Oracle 应用的能力。您可以在 PPAS 上稳定地运行各种企业应用,同时得到更高性价比的服务。 阿里云数据库 PPAS 版集成了账号管理、资源监控、备份恢复和安全控制等功能,并将持续地更新完善。 当前 RDS for PPAS 支持 9.3/10 版本。

2019-12-01 22:57:16 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 企业建站模板