- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在努力思考 Tornado 和与 Postgresql 的异步连接。我在 http://peewee-async.readthedocs.io/en/latest/ 找到了可以执行此操作的库.
我设计了一个小测试来比较传统的 Peewee 和 Peewee 异步,但不知何故异步工作速度较慢。
这是我的应用:
import peewee
import tornado.web
import logging
import asyncio
import peewee_async
import tornado.gen
import tornado.httpclient
from tornado.platform.asyncio import AsyncIOMainLoop
AsyncIOMainLoop().install()
app = tornado.web.Application(debug=True)
app.listen(port=8888)
# ===========
# Defining Async model
async_db = peewee_async.PooledPostgresqlDatabase(
'reminderbot',
user='reminderbot',
password='reminderbot',
host='localhost'
)
app.objects = peewee_async.Manager(async_db)
class AsyncHuman(peewee.Model):
first_name = peewee.CharField()
messenger_id = peewee.CharField()
class Meta:
database = async_db
db_table = 'chats_human'
# ==========
# Defining Sync model
sync_db = peewee.PostgresqlDatabase(
'reminderbot',
user='reminderbot',
password='reminderbot',
host='localhost'
)
class SyncHuman(peewee.Model):
first_name = peewee.CharField()
messenger_id = peewee.CharField()
class Meta:
database = sync_db
db_table = 'chats_human'
# defining two handlers - async and sync
class AsyncHandler(tornado.web.RequestHandler):
async def get(self):
"""
An asynchronous way to create an object and return its ID
"""
obj = await self.application.objects.create(
AsyncHuman, messenger_id='12345')
self.write(
{'id': obj.id,
'messenger_id': obj.messenger_id}
)
class SyncHandler(tornado.web.RequestHandler):
def get(self):
"""
An traditional synchronous way
"""
obj = SyncHuman.create(messenger_id='12345')
self.write({
'id': obj.id,
'messenger_id': obj.messenger_id
})
app.add_handlers('', [
(r"/receive_async", AsyncHandler),
(r"/receive_sync", SyncHandler),
])
# Run loop
loop = asyncio.get_event_loop()
try:
loop.run_forever()
except KeyboardInterrupt:
print(" server stopped")
这是我从 Apache Benchmark 得到的结果:
ab -n 100 -c 100 http://127.0.0.1:8888/receive_async
Connection Times (ms)
min mean[+/-sd] median max
Connect: 2 4 1.5 5 7
Processing: 621 1049 256.6 1054 1486
Waiting: 621 1048 256.6 1053 1485
Total: 628 1053 255.3 1058 1492
Percentage of the requests served within a certain time (ms)
50% 1058
66% 1196
75% 1274
80% 1324
90% 1409
95% 1452
98% 1485
99% 1492
100% 1492 (longest request)
ab -n 100 -c 100 http://127.0.0.1:8888/receive_sync
Connection Times (ms)
min mean[+/-sd] median max
Connect: 2 5 1.9 5 8
Processing: 8 476 277.7 479 1052
Waiting: 7 476 277.7 478 1052
Total: 15 481 276.2 483 1060
Percentage of the requests served within a certain time (ms)
50% 483
66% 629
75% 714
80% 759
90% 853
95% 899
98% 1051
99% 1060
100% 1060 (longest request)
为什么同步更快?我缺少的瓶颈在哪里?
最佳答案
详细解释:
http://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/
简短说明:同步Python代码简单,主要在标准库的套接字模块中实现,它是纯C语言。异步Python代码比同步代码更复杂。每个请求都需要多次执行主事件循环代码,该代码是用 Python 编写的(在此处的 asyncio
案例中),因此与 C 代码相比有很多开销。
像您这样的基准测试显着地显示了异步的开销,因为您的应用程序和数据库之间没有网络延迟,而且您正在执行大量非常小的数据库操作。由于基准测试的每个其他方面都很快,因此事件循环逻辑的这么多次执行增加了总运行时间的很大一部分。
上面链接的 Mike Bayer 的论点是,像这样的低延迟场景对于数据库应用程序来说是典型的,因此数据库操作不应该在事件循环中运行。
异步最适合高延迟场景,例如 websocket 和网络爬虫,在这些场景中,应用程序将大部分时间用于等待对等点,而不是将大部分时间用于执行 Python。
总而言之:如果您的应用程序有充分的理由采用异步(它处理速度较慢的对等点),那么为了保持代码的一致性,使用异步数据库驱动程序是个好主意,但需要一些开销。
如果您出于其他原因不需要异步,请不要执行异步数据库调用,因为它们有点慢。
关于python - peewee 和 peewee 异步 : why is async slower,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39803746/
我正在将 Peewee 用于我正在进行的一个项目,并且我正在尝试弄清楚如何动态设置数据库,以便我可以使用一个用于生产,一个用于测试。我见过的所有示例在任何类之外都有以下行: database = Sq
我正在努力思考 Tornado 和与 Postgresql 的异步连接。我在 http://peewee-async.readthedocs.io/en/latest/ 找到了可以执行此操作的库. 我
我有一个记录温度数据的表,其中有 120 万行。 虽然它有一个候选键,但目前没有主键。 由于 Peewee 要求所有表都有一个 ID AUTO_INCRMENT 列,我应该简单地向表中添加一个列,还是
作为练习,我从 API 中提取数据并将其插入到 psql 数据库中。我最初遵循每次拉取 1000 个条目的默认限制,但我决定尝试获取大约 40K 行的所有数据。经过一些实验后,我可以拉出 4800,但
几个月来,我一直在广泛使用 peewee 和 postgresql。突然间,这开始发生了。如果我运行任何查询命令并收到错误,则所有后续命令开始返回 peewee.InternalError: curr
我被难住了。因此,我在 peewee 中定义了三个模型: class Patient(BaseModel): patientIdx = IntegerField() gender =
有没有一种方法可以在peewee中定义自动递增字段。 我知道我们可以定义序列,但是手动创建序列而不需要由create_tables管理的需求使我无法使用它。 (构建过程由创建表管理,我不希望不添加手动
在 Peewee 中是否有一种方法或设置可以让我打印出正在执行的所有查询,以便调试和了解潜在的性能问题。 最佳答案 是的,是记录在案 :http://docs.peewee-orm.com/en/la
我需要更新整个用户表的字段。 docs中有说明我不应该遍历所有表记录。但为了计算新的字段值,我需要使用循环、用户关系和其他依赖于具体模型的复杂逻辑来执行计算。 我尝试将此计算包含在模型的属性中,但我得
我有一个表,我需要向其中添加列,其中之一是指示业务逻辑的列。因此,请将其视为“优先级”列,并且它必须是唯一的并且是整数字段。它不能是主键,但对于业务逻辑目的来说它是唯一的。 我搜索了文档,但找不到添加
class Parent(BaseModel): name = peewee.CharField() class Child(BaseModel): name = peewee.Cha
这就是我所拥有的: SomeTable.select.where(reduce(operator.or_, (SomeTable.stuff == entry for entry in big_lis
我如何知道记录是否确实已更新?这是我的代码: for team, rating in team_ratings.items(): query1 = Ratings.update(sagar
我使用 pewee 和以下查询: for row in Group.select(): group_data = process_group(row.link) Group.upda
这是一个基本示例 - 帖子由用户拥有和喜欢。如何为特定用户选择喜欢的帖子? import datetime import peewee class User(peewee.Model): na
我有一个 sqlite 数据库,用作我用 python 开发的应用程序的数据存储文件。 现在新功能的开发需要我在数据库中定义新字段。有没有一种方法可以使用 peewee 加载使用旧表定义(没有新字段)
我有一个模型,其中有一个名为 data 的字段,其类型为 jsonb: class Post(Model): ... data: Dict[str,Any] = BinaryJSONF
我希望能够连接到数据库 (PostgreSQL),其中 url 和凭据作为参数接收,而无需事先了解该方案。所以我已经知道我可以像这样在 python 中创建新类型: MyModel = type('M
我创建了一个像这样的mysql连接池: database = PooledMySQLDatabase('test', max_connections=10,
在使用 peewee + MySQL 数据库的 Python 中,是否可以在更新函数中使用一些变量作为关键字? 例如: what = raw_input('What you want to chang
我是一名优秀的程序员,十分优秀!