; 介绍
seaborn可以非常便捷的将各种图表组合起来,如在上一章使用 row
和 col
参数可以非常快速的根据数据生成多个图表;
本章主要介绍根据我们自己的个性需求生成组合图表,这里组合图表分成两种形式:
- 多子图:在一个画布上绘制多个坐标系;
- 图表重叠:将多个图表在一个坐标系展示;
多子图
在之前的内容中我们讲到了 seaborn的图表层级, axes-level
图表是可以添加到matplotlib的复杂figure中的,seaborn中的 axes-level
都有添加一个 ax
参数用于指定在figure中的绘图位置;
如下面代码中,我们通过 plt.subplots()
创建一个1行2列的 figure
,我们可以非常便捷的将 seaborn的图表添加进去;
import matplotlib.pyplot as plt
import seaborn as sns
penguins = sns
Original: https://blog.csdn.net/qq_27484665/article/details/125018786
Author: AwesomeTang
Title: 【Seaborn】组合图表、多子图的实现
相关阅读
Title: Flask搭建服务(五):gunicorn使得服务性能降低问题及解决
使用ab进行压测,发现使用gunicorn后,服务性能反而下降了,这是ab结果:
压测命令:$ ab -c 10 -n 1000 -p post.txt -T application/json http://0.0.0.0:5000/b/embedding
条件处理每条请求所用时间(均值)90%时间 不用gunicorn
9.918ms
121
使用gunicorn:work=2
54ms
929
看到这,有点怀疑gunicorn的作用了,适得其反了。晚上查了一些gunicorn配置的优化,解决了这个性能 问题,并提速30%+。接下来看看什么原因导致服务性能下降,然后这个问题的解决方案是什么。
[1]服务器和客户端的通信,我们简略的分为三个部分:request,request handling,和response,即客户端向服务器发起请求,服务器端响应并处理请求,和将请求结果返回客户端,这三个过程。
通常,request handling这部分即服务端的计算,拼的是服务器的性能,处理是比较高效和稳定的,而request和response部分,影响因素比较多,如果这三个过程放到同一个进程中同步处理,如果request和response部分耗时比较多,会使计算资源被占据并无法及时释放,导致计算资源无法有效利用,降低服务器的处理能力。
上述”慢客户端行为”,指的就是request(或response)部分耗时比较多的情况,Gunicorn恰好会把上面三个过程放到同一个进程中,当出现”慢客户端行为”时,效率很低:
Gunicorn 是一个pre-forking的软件,这类软件对低延迟的通信,如负载均衡或服务间的互相通信,是非常有效的。但pre-forking系统的不足是,每个通信都会独占一个进程,当向服务器发出的请求多于服务器可用的进程时,由于服务器端没有更多进程响应新的请求,其响应效率会降低。
对于Web网站或服务而言,由于request和response延时是不可控的,我们需要在考虑处理高延迟客户端请求的情况。这些请求会占据服务器端的进程。当慢客户端直接与服务通信时,由于慢客户端请求会占据进程,可用于处理新请求的进程就会减少,如果有很多慢客户端请求把所有进程都占据后,新的请求只能等待有进程被释放掉后,得到响应。另外,如果应用希望有更高的并发,服务器与客户端的通信要更高效,异步的通信会比同步的通信更有效。
三种并发方式:
一、workers 模式,又名 UNIX 进程模式
每个 worker 都是一个加载 Python 应用程序的 UNIX 进程。worker 之间没有共享内存。 建议的 workers 数量是 (2*CPU)+1。对于一个双核(两个CPU)机器,5 就是建议的 worker 数量。
gunicorn --workers=5 main:app
当然也可以将--workers=5写到一个配置文件中,如下:
# gunicorn.py
workers = 2
timeout = 60
bind = '0.0.0.0:9501'
worker_class = 'gevent'
worker_connections = 1000
max_requests = 50000
max_requests_jitter = 2
起服务命令:
gunicorn -c gunicorn.py run:app
其中-c表示传入配置文件
run表示你flask服务所在的文件名
app表示你的flask服务实例
二、多线程[优胜之选]
Gunicorn 还允许每个 worker 拥有多个线程。在这种场景下,Python 应用程序每个 worker 都会加载一次,同一个 worker 生成的每个线程共享相同的内存空间。
为了在 Gunicorn 中使用多线程。我们使用了 threads 模式。每一次我们使用 threads 模式,worker 的类就会是 gthread:
gunicorn --workers=5 --threads=2 run:app
最大的并发请求数就是 worker * 线程,也就是10。
在使用 worker 和多线程模式时建议的最大并发数量仍然是(2*CPU)+1。
因此如果我们使用四核(4 个 CPU)机器并且我们想使用 workers 和多线程模式,我们可以使用 3 个 worker 和 3 个线程来得到最大为 9 的并发请求数量。
gunicorn --workers=3 --threads=3 run:app
三、”伪线程”
有一些 Python 库比如(gevent 和 Asyncio)可以在 Python 中启用多并发。那是基于协程实现的”伪线程”。
Gunicrn 允许通过设置对应的 worker 类来使用这些异步 Python 库。
这里的设置适用于我们想要在单核机器上运行的gevent:
gunicorn --worker-class=gevent --worker-connections=1000 --workers=3 run:app
worker-connections 是对于 gevent worker 类的特殊设置。
(2*CPU)+1 仍然是建议的workers 数量。因为我们仅有一核,我们将会使用 3 个worker。
在这种情况下,最大的并发请求数量是 3000。(3 个 worker * 1000 个连接/worker)
并发 vs. 并行
- 并发是指同时执行 2 个或更多任务,这可能意味着其中只有一个正在处理,而其他的处于暂停状态。
- 并行度是指两个或多个任务同时执行。
[En]
parallelism means that two or more tasks are executing at the same time.*
在 Python 中,线程和伪线程都是并发的一种方式,但并不是并行的。但是 workers 是一系列基于并发或者并行的方式。
参考:
Original: https://blog.csdn.net/pearl8899/article/details/113531389
Author: 凝眸伏笔
Title: Flask搭建服务(五):gunicorn使得服务性能降低问题及解决
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/325797/
转载文章受原作者版权保护。转载请注明原作者出处!