百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

阿里巴巴杨群高并发场景下Python的性能挑战

toyiye 2024-05-25 20:12 31 浏览 0 评论

导读:阿里云数据库提供了稳定可靠、可弹性伸缩的在线数据库服务,在数据库存储引擎、云原生技术、分析引擎、分布式处理、FPGA/GPU硬件加速、智能数据库、智能化管控平台、安全数据库等方面有较好的表现。

4月13日,在CSDN主办的“2019 Python开发者日”大会上,阿里云数据库专家杨群分享了《高并发场景下Python的性能挑战》的主题演讲。

以下为演讲整理,文章略有删减:

性能问题

▌(一)GIL

为什么大家都说Python慢?最主要的原因是全局解释器锁。今天讲的Python是官方的C版Python。CPython在创建变量时,首先对变量分配内存,然后开始计数变量的数量,大家提出称之为“引用计数”。在引用计数变为0时,从系统中释放变量的内存。如果多个线程同时对这个计数做操作,线程不安全,会导致很多问题。

综合垃圾回收机制问题,CPython引入了GIL,同一个时刻在一个进程允许一个线程使用解释器,意味着单进程下Python多线程的性能没有那么好。这样做的好处在于能够避免死锁和数据用户安全方面的问题。

Python有三种线程状态:Idle、Running、Failed GIL Acquire。曾经有人对GIL的性能影响做了两个测试。第一个测试案例是两个CPU密集线程,代码运行过程的大部分状态是Failed GIL Acquire,两个线程的运行没有达到双核的效果。

第二个案例是IO密集型的线程。仔细分析发现,IO没有达到想象的预期效果。所以IO密集型和CPU密集型同时存在时,IO密集型未必达到想要的运算速度,我们要区分好IO密集型和CPU密集型的服务。

小编准备了一份Python学习资料,给那些正在学习Python的同学,或者准备学习Python的同学,关注,转发,私信小编“01”即可免费获取!

▌(二)解释器

CPython要首先生成pcy字节码序列,之后才能被CPU理解,所以较慢。JAVA、.NET也有中间的翻译,但因为JAVA和.NET使用即时编辑(JIT),使用JIT可以检测哪些代码执行得比较多,意味着计算机应用程序需要重复做一件事情的时候它就会更快。

▌(三)动态语言

Python是动态语言类型,我们在做类型转化或者比较的时候比较耗时,因为读取、写入变量或者引用变量时会进行检查。静态类型语言没有这么高的灵活性,但它已经规定好了内存中的状态,所以很快。

Python这么慢,我们为什么还要用它?一是用Python优雅、简洁。二是大多数应用场景时,GIL或者解释器带来的性能未必是我们所担心的,比如科学计算或者平常做一些数据分析或小应用时不会考虑到这个问题。

服务选型

这是市面上常用的web框架针对Python的领域做服务选型分析的框架。无论使用什么web框架,在web服务中都会选择多进程。一方面考虑到服务需要一定的可用性,需要多进程来保证减少服务可用性的影响。另外,多个进程意味着多个解释器,多个解释器意味着我们尽量减少GIL带来的性能影响。

这是常见web服务的方法,前端的LoadBalancer,大家可能会选择常见的Nginx、apache或者云服务的SLB。

异步IO框架的选择是大家都关心的一个问题。GIL如果是IO密集型,我们用异步能够做到很快。但是它有很适合的应用场景,比如不想做Nginxluv插件,作为高性能的扩展方案,那就用tornado来写,如果内部代码全是异步的IO操作,它是非常好的,可以组装自己的逻辑,比如积数之类的都可以放在tornado里来做,性能可以得到保障。

另外,PyPy是Python的Just in time 编译器,性能一般要比CPython解释器至少好3倍。但是它和JIT编译器一样有启动慢的特点,所以适合对重启不是很敏感的服务。它的问题是不支持C扩展的Python库。

性能瓶颈分析

在现实业务开发中,最主要的是依靠业务日志分析,考虑我们的业务链路中是否存在网络耗时。对一些任务日志可以用AWK或者unit等,去分析出来哪些接口访问量比较多、耗时严重的,使用Cprofile等工具分析问题存在哪里,然后再找到合适的优化方向。

这是一个简单的Cprofile例子,执行def1、def2、def3,去分析一下它的耗时情况。

上面的代码中有多个函数的执行。可以看到,最后一次的运行耗时是237毫秒。当然,对于profile也可以输出pstat格式的数据,大家能通过可视化清楚的看到自己函数耗时占比。

优化方法

▌(一)原则

第一,优化时一定要靠数据说话。即使需要牺牲一次迭代去更新一下,也要把数据罗列出来,使之有理有据。我们优化的原则主要有四点:一是用数据说话,数据不只是优化的原因,也是优化的方向,把指标达到一定水准,目的才达到了;第二,不要过早优化或过度优化。否则有可能出现业务偏差;第三,深入理解业务。对产品更加负责;第四,选择好的衡量标准,比如CPU利用率降到多少了。

▌(二)IO密集型

如果是IO密集型的服务,使用多线程实际比单线程的性能提高很多。但是如果大量IO操作都比较耗时,它的性能未必像想象中那么好。这种情况下建议批量操作,或者改为协程,网络带宽性能会带来很大的提升。此外,减少IO操作也是可行方案。

▌(三)CPU密集型

多线程显然已经不适用于CPU密集型的服务,因为频繁的GIL争抢会导致序性能大幅度下降。多进程其实很适合CPU密集型服务。对于CPU密集型的服务,为了减少解释器的损耗 ,最好可以适用C的扩展库来提高程序性能,能够一定程度缓解类型转换带来的性能损耗 ,而且可以大幅度提高基础库的运行速度。

▌(四)缓存

缓存一直是系统性能优化的利器,这对Python是架构性的东西,可能跟语言的相关性没有那么大。但是Python的编程方法对缓存代码改造是非常便利的。

这是缓存的例子,这个业务逻辑很简单,在现有的生产模型里比较常用。

这是一个有缓存的函数,我们在性能调优时需要动态去允许开关函数不缓存,必须按照原来的方式执行一遍才能拿到结果。这里有一个计算缓存过程,mode是我们开发的模式,可以在函数动态的取mode,达到开关的值。我们可以通过这个开关去让函数得到它执行的方式。

另外,我们在存储序列化数据时最好使用高性能的库,比如cPickle,cPickle虽然比pickle,但是没有cJSON快。可以给存储层、DB层、计算的函数层、应用层都加上缓存,但是在Python应用程序之外也有很多架设高速缓存的方法。

多层缓存虽然是一个架构缓存,但是Python开发做扩展性应用时,用户体验是非常好的,简短的代码开发就可以完成通用功能,而且里面的语言不用动。

▌(五)懒加载

还有一些常用的方法,比如懒加载。这是常用的Lazy单例,调用一次之后就不再调用了,以后拿到的是初始化好的。

▌(六)一些技巧

对于generator需要谨慎对待。 对于循环遍历,比如遍历10万个数据,generator有可能更慢一些,这种东西是需要分场合的。如果在循环中不需要把所有列表生成出来,那么速度会稍微快一些。

这是一个命名空间问题。第一种状况可能更简单一些,但是它是147毫秒,第二种状况是把循环函数里,快了1倍时间。这是因为Python在执行代码时遇到了range。对于第一种,Python首先会在本地的变量里找这个range,如果没有找到会去gloabl变量里找range。

对于第二种,range的查找不需要再走gloabl,它走的是load-const,这是一个很快的过程。有些由于空间导致的性能微小的差距,执行少量数据时看不出来,但是大量数据时是非常明显的。

总结

Python这种便利的特性给我们带来很大的开发优势:

数据分析是第一位的,要去优化自己的Python服务。

第二,需要合理的测试环境,不要因为性能调优而影响增加的服务稳定性或者出现故障。

第三,要有的放矢,我们有时面对更多服务拆分或微服务化,对架构说不定有更多好处。比如把IO密集型服务和CPU密集型服务分开做,在前端使用IO密集型的操作。将所有的请求都集中在对外的入口,这样对外服务的性能会得到很大的提高,因为性能压力都分散到各个微服务里了,而同样的性能得到了最大的保障。大家可以多钻研一下,掌握一些技巧。

谢谢大家。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码