根据我的理解,我们应该进行数据库调用异步,因为它会阻止IOLoop,而且我还找到了一些处理这个问题的库/工具。 但最近我在stackoverflow上发现了很多关于这个问题的帖子
How does async work in Tornado?
来自wiki https://github.com/tornadoweb/tornado/wiki/Threading-and-concurrency
的内容同步执行并阻止IOLoop。这是最合适的 像你所掌控的memcache和数据库查询之类的东西 而且应该永远快。如果它不快,可以通过添加来加快速度 适当的数据库索引等。
那么我们应该进行数据库调用异步吗?
和一个相关问题:据我所知,有两种方法可以进行数据库调用async
对于同步数据库(mysqldb),我们可以
executor = ThreadPoolExecutor(4)
result = yield executor.submit(mysqldb_operation)
对于异步数据库(motor),我们可以直接使用它。
基于龙卷风的不同之处是什么?
答案 0 :(得分:3)
我有一个类似的疑问,经历了一些研究和挖掘,最后对此有所了解。
简答 - 是的,异步执行。
长答案: 数据库调用通常是阻塞调用。当我们进行异步/非阻塞I / O调用以充分发挥其潜力时,Tornado最适合作为框架。
现在,您可以通过以下方式在Tornado中进行数据库调用,我将为每种方法提供方法和原因。
方法1 :Synchronous Database Calls
- 在负载均衡器后面启动一些Tornado实例,例如nginx,并进行同步数据库调用(如上所述)维基)。在这种情况下,具有阻塞数据库调用的特定请求的进程将被阻止。所以nginx会通过将其他请求引导到其他正在运行的龙卷风实例来处理请求来平衡其他请求。
注意:该wiki已经过时,并且尚未更新,因此提到的方法是在Ben Darnell提到的较新版本的Tornado中添加协同程序之前龙卷风的主要开发者。
更新:最近Ben更新了wiki,您现在可以查看。
方法2 :使用多处理或多线程,concurrent.futures,类似于您提到的内容:
对于同步数据库(mysqldb),我们可以
executor = ThreadPoolExecutor(4) result = yield executor.submit(mysqldb_operation)
方法3 :通过使用异步库,例如,如果您使用的是MySql,则可以使用TorMySql,{{3}等库},这里给出的其他链接 - Tornado-MySQL,转到MySql部分。这些库将与Tornado的异步装饰器一起使用, tornado.gen.coroutine
或 tornado.web.asynchronous
。同样,您需要为不同的数据库使用其他异步库。
注意 :您不能使用阻止库,否则它与 Method 1
完全相同。
结论: Method 3
就是我提到的 Short Answer
。 Method 2
是下一个最佳解决方案,其次是 Method 1
。这符合您的性能要求。如果您的要求是每秒或每分钟不那么重(少到中等)请求处理,那么只需要简单而通用的 Method 1
就足够了。