月经贴, tornado + sqlalchemy

2014-12-05 09:57:04 +08:00
 ryanking8215
网上搜了下tornado+sqlalchemy,发现都是直接用的,那tornado的non-blocking特性不是用不到了吗?
15196 次点击
所在节点    Python
38 条回复
qbeenslee
2014-12-05 17:25:31 +08:00
@ryanking8215 楼主在tornado上可以多多交流, 我最近也想用tornado做毕业设计...
halfelf
2014-12-05 19:45:28 +08:00
有没有人用过gevent + sqla + pymsql
sujin190
2014-12-05 21:24:20 +08:00
sujin190
2014-12-05 21:25:56 +08:00
使用greenlet实现异步,和pymongo的motor的实现机理一样,现在用在自己项目中
ponyfk
2014-12-05 22:14:44 +08:00
一定要用orm的话, 我推荐 ponyorm(配合ultramysql) + gevent + flask 完美解决异步
wingyiu
2014-12-05 22:21:15 +08:00
@zenliver
@sujin190

正好在找db async的解决方案
sujin190
2014-12-05 22:28:43 +08:00
@zenliver mysql协议是二进制解析的,有非常多的自己读取,每次调用iostream的read其实是效率非常低的
zenliver
2014-12-07 15:06:23 +08:00
@sujin190 的确如此
zhicheng
2014-12-07 21:03:06 +08:00
这个问题不用太担心,
一,一般 WebServer 和 DB 都是局域网直连,网络性能损失很小,在要求不是极高的情况下,能够满足需求。
二,因为 RDBMS 的特殊性,目前一个连接并不能同时执行多个请求。所以如果使用非阻塞IO,不仅会导致前端非常复杂,并且依然会卡在一个执行时间超长的 SQL 上,除非针对每次请求创建一个 DB 连接,这样一定程度上增加了 latency 和 DB 的负荷。
三,如果用多核 CPU (现在几乎全部都是)的服务器,可以同时创建多个 Web Server 的进程,能够缓解DB阻塞的问题。
四,不建议自己实现 DB Driver ,除非你知道你在做什么。
五,自己实现协议和DB的,都是走火入魔的标志。
ryanking8215
2014-12-07 21:31:31 +08:00
@zhicheng
一. 提出tornado,就是想探讨一下非阻塞模型下如何使用同步ORM的问题,不是说一定不能直接使用。只是如果后端没有压榨出non-blocking的效率,于心不忍。

二. 不是有连接池吗?

三. 同意,单线程的无法使用多核,需要多进程加入。目前看来,除了自带调度器的golang,erlang啥的,其他的语言要网络io的高并发,就是多进程+单线程的事件循环了。

四. 看个人角度了,对有些人来说是对的,对某些人来说这句话是错的。

五. 同上
zhicheng
2014-12-07 23:26:13 +08:00
一,如果实在想解决这个问题,中间加一层 API ,负责处理 Web Server 和 DB 的连接。
二,连接池确实能解决一定问题。
三,这跟是否自带调度器无关,而是因为 Python 有 GIL 。我现在在 C 部分的代码,即使多线程也是每个线程使用一个 event loop 。跟进程模型几乎一样的,只是节省了共享内存的部分。
四,如果你写过类似的,就会知道,像这样的产品,从开始到可用,最少需要一年的时间。
五,同上。
六,优秀的工程师必备条件之一就是不要高估自己的能力。
zhouquanbest
2014-12-08 00:24:32 +08:00
@lianghui
这确实是个解法 和celery一回事 就是让db操作和tornado分离
好像百度是这么干的吧

不过小项目这样做也挺累
Tornado麻烦在于 小项目sql也堵死你 只能提前优化
异步真是不能省心
toooddchen
2014-12-08 00:42:27 +08:00
tornado和sqlalchemy的使用, 对你提到的非阻塞特性没有什么影响.
db访问层面阻塞了, 不会影响tornado对其它请求的处理.

影响单线程ioloop性能的, 是cpu密集的操作, db访问不属于这一类.
MasterYoda
2014-12-08 09:57:04 +08:00
@toooddchen
你起一个tornado进程,然后来一个复杂的sql查询请求,阻塞后再来别的请求看看影响它对其它请求的 处理不。
ryanking8215
2014-12-08 10:06:25 +08:00
@MasterYoda 同意,其实time.sleep()就可以了

@toooddchen 为什么cpu密集操作会影响eventloop性能呢?因为event loop无法及时“归位”,同理,同步的ORM会阻塞当前执行的协程。影响event loop性能的不单单是cpu密集操作,比如time.sleep()。这是那啥充分必要条件,好久没整,整不清楚了。
beef9999
2014-12-17 11:32:27 +08:00
没错,tornado的特性之一是异步非阻塞,但是这不是根本,根本上来说它是一个使用了epoll的web server,能保证大量网络连接送到python代码的get或者Post的这个过程是高效的,只要你不阻塞get 或者post,剩下的你想干什么都行。不阻塞的方法很多,你可以用异步调用,这样语法就比较难看,即使是用了生成器,还是很反直觉,另外在python 2还有raise Return(response)这种诡异的东西。当然这些都不是问题,最主要的问题是很多ORM数据库不支持异步,所以最佳实践还应该是去开线程,使用线程池。tornado能够支持线程,并且经过仔细编写的代码也是能够达到线程安全的。最后有人说用gevent,理论可以,这样你就能写出不阻塞的同步代码,也支持数据库了。但是怎么集成tornado是个问题,目前看到的似乎没有成熟的项目
Pegasus
2016-01-19 15:49:50 +08:00
http://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/
这个是 SQLArchemy 作者的文章,可以看看为什么不推荐使用异步的 orm
dantangfan
2016-02-17 20:12:44 +08:00
@Pegasus 只是不推荐 python 实现的异步吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/151662

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX