China (googlegroups) - [CPyUG] 用gevent来host wsgi server,mysql能否长连接
11 posts
|
基于gevent的高性能,nonblock,开始学习gevent。 如果用gevent来host wsgi(比如django、web.py),连接mysql的时候,MySQLdb肯定是不能用的了,因为MySQLdb直接用c把对socket的操作都给封装了,调用monkey.patch_all()来打patch,并不会起作用,所以此时mysql操作仍然是blocking的。 也在网上查询了几个基于gevent的mysql client driver,比如gevent-mysql。但是我觉得gevent-mysql虽然是nonblocking,但是貌似仍然不能使用长连接,这样的话,几个协程公用一个mysql conneciton,就是出现“协程安全“的问题吧。gevent-mysql官方给的例子里面,几个协程都是分别起一个mysql connection的, https://github.com/mthurlin/gevent-MySQL/blob/master/examples/benchmark.py 不知说的对不对,希望大家拍砖。 -- 来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表) 发言: [hidden email] 退订: [hidden email] (向此发空信即退!) 详情: http://code.google.com/p/cpyug/wiki/PythonCn 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp 强烈: 建议使用技巧: 如何有效地报告Bug http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html
|
Threaded
|
More
Print post |
Permalink |
Nov 15, 2011; 8:15pm
Re: [CPyUG] 用gevent来host wsgi server,mysql能否长连接
1507 posts
|
你的长连接,是什么意思呢?longpull一般是说一个请求保持不返回。正常来说,这样的情况下,请求不会阻塞在mysql调用上,而是一般阻塞在了事件上。在调用mysql这个问题上,一般会碰到的是另外两个术语,连接池/连接复用。
简单来说,一个请求,从过来后,就会开始获得一个sql连接来进行数据查询。在查询的时候,有可能sql响应比较慢(而且很有可 能),因此发生上下文切换。所以,第一个需要知道的事情就是,在异步编程模式下,即使是被框架封装了,在“阻塞”调用的后面,可能发生上下文调度。这和线 程/进程模型不大一样,因为线程和进程模型在任何位置都可能发生上下文调度。
在这种情况下,如果要设计一个连接池进行连接复用,就要考虑到,将sql对象绑定到具体的上下文上。一旦一 个sql连接被分配后,就要考虑不可被其他上下文使用(否则即使线程安全,也会出现transaction的问题)。在java连接池的年代,我记得一般 是用TLS来做这个工作的。当然,如果粗糙一点,可以直接把连接给出去,然后不闻不问了。直到上下文销毁的时候归还连接,或者一直不归还就被销毁,导致连 接减少(连接本身会自动被关闭,但是连接池的可用连接总量就减少了)。
后者看似粗糙,其实并不糟糕。我记得mysql可以检查目前活动连接数,如果连接池耗尽,先检查活动连接。低于阀值就再分配一批就好了。
但是,在连接池结合长连接的问题上,一般要注意,进入长时间的事件阻塞前,必须先归还连接。我们说过,sql连接是绑定到具体上下文的。如果不归还连接就进入长期的事件阻塞,就会导致sql连接一并被冻结到了这个事件上。这样没几个长连接下来,sql连接池就会先耗尽。
在 2011年11月15日 下午7:48,Yang Juven
<[hidden email]>
写道:
--
--
|
Threaded
|
More
Print post |
Permalink |
Nov 15, 2011; 8:24pm
[CPyUG] Re: 用gevent来host wsgi server,mysql能否长连接
124 posts
|
In reply to
this post by Yang Juven
postgresql 支持异步,还是换数据库吧 On 11月15日, 下午7时48分, Yang Juven < [hidden email] > wrote: > 基于gevent的高性能,nonblock,开始学习gevent。 > 如果用gevent来host wsgi(比如django、web.py),连接mysql的时候,MySQLdb肯定是不能用的了,因为MySQLdb直接用c把对socket的操作都给封装了,调用monkey.patch_all()来打patch,并不会起作用,所以此时mysql操作仍然是blocking的。 > 也在网上查询了几个基于gevent的mysql client > driver,比如gevent-mysql。但是我觉得gevent-mysql虽然是nonblocking,但是貌似仍然不能使用长连接,这样的话,几个协程公用一个mysql > conneciton,就是出现“协程安全“的问题吧。gevent-mysql官方给的例子里面,几个协程都是分别起一个mysql > connection的, https://github.com/mthurlin/gevent-MySQL/blob/master/examples/benchma ... > 不知说的对不对,希望大家拍砖。 -- 来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表) 发言: [hidden email] 退订: [hidden email] (向此发空信即退!) 详情: http://code.google.com/p/cpyug/wiki/PythonCn 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp 强烈: 建议使用技巧: 如何有效地报告Bug http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html
|
Threaded
|
More
Print post |
Permalink |
Nov 15, 2011; 8:45pm
Re: [CPyUG] 用gevent来host wsgi server,mysql能否长连接
11 posts
|
In reply to
this post by Shell Xu
谢谢你详细的答复,我明白了。我所说的:长连接是指连接复用,区别于短连接,并不是"请求来了,就重新创建一个mysql新连接;请求完毕后,就关闭这个连接"。gevent对Greenlet采用了"阻塞调度"机制,因此在mysql查询时,确实会发生Greenlet切换,此时将mysql connection与"绑定到具体的Greenlet",就没有问题了。连接池+连接复用是解决方案。 2011/11/15 Shell Xu < [hidden email] >: > 你的长连接,是什么意思呢?longpull一般是说一个请求保持不返回。正常来说,这样的情况下,请求不会阻塞在mysql调用上,而是一般阻塞在了事件上。在调用mysql这个问题上,一般会碰到的是另外两个术语,连接池/连接复用。 > 简单来说,一个请求,从过来后,就会开始获得一个sql连接来进行数据查询。在查询的时候,有可能sql响应比较慢(而且很有可能),因此发生上下文切 换。所以,第一个需要知道的事情就是,在异步编程模式下,即使是被框架封装了,在"阻塞"调用的后面,可能发生上下文调度。这和线程/进程模型不大一样, 因为线程和进程模型在任何位置都可能发生上下文调度。 > 在这种情况下,如果要设计一个连接池进行连接复用,就要考虑到,将sql对象绑定到具体的上下文上。一旦一个sql连接被分配后,就要考虑不可被其他上下 文使用(否则即使线程安全,也会出现transaction的问题)。在java连接池的年代,我记得一般是用TLS来做这个工作的。当然,如果粗糙一 点,可以直接把连接给出去,然后不闻不问了。直到上下文销毁的时候归还连接,或者一直不归还就被销毁,导致连接减少(连接本身会自动被关闭,但是连接池的 可用连接总量就减少了)。 > 后者看似粗糙,其实并不糟糕。我记得mysql可以检查目前活动连接数,如果连接池耗尽,先检查活动连接。低于阀值就再分配一批就好了。 > 但是,在连接池结合长连接的问题上,一般要注意,进入长时间的事件阻塞前,必须先归还连接。我们说过,sql连接是绑定到具体上下文的。如果不归还连接就 进入长期的事件阻塞,就会导致sql连接一并被冻结到了这个事件上。这样没几个长连接下来,sql连接池就会先耗尽。 > 在 2011年11月15日 下午7:48,Yang Juven < [hidden email] >写道: >> >> 基于gevent的高性能,nonblock,开始学习gevent。 >> 如果用gevent来host >> wsgi(比如django、web.py),连接mysql的时候,MySQLdb肯定是不能用的了,因为MySQLdb直接用c把对socket的操作都给封装了,调用monkey.patch_all()来打patch,并不会起作用,所以此时mysql操作仍然是blocking的。 >> 也在网上查询了几个基于gevent的mysql client >> >> driver,比如gevent-mysql。但是我觉得gevent-mysql虽然是nonblocking,但是貌似仍然不能使用长连接,这样的话,几个协程公用一个mysql >> conneciton,就是出现"协程安全"的问题吧。gevent-mysql官方给的例子里面,几个协程都是分别起一个mysql >> >> connection的, https://github.com/mthurlin/gevent-MySQL/blob/master/examples/benchmark.py >> 不知说的对不对,希望大家拍砖。 >> >> -- >> 来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表) >> 发言: [hidden email] >> 退订: [hidden email] (向此发空信即退!) >> 详情: http://code.google.com/p/cpyug/wiki/PythonCn >> 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp >> 强烈: 建议使用技巧: 如何有效地报告Bug >> http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html > > > > -- > 无能者无所求,饱食而遨游,泛若不系之舟 > blog: http://shell909090.com/blog/ > twitter: http://twitter.com/shell909090 > > -- > 来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表) > 发言: [hidden email] > 退订: [hidden email] (向此发空信即退!) > 详情: http://code.google.com/p/cpyug/wiki/PythonCn > 严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp > 强烈: 建议使用技巧: 如何有效地报告Bug > http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html >
... [
show rest of quote]
|