我们应该用龙卷风进行数据库调用异步吗

Should we do database calls async with tornado

据我了解,我们应该进行异步数据库调用,因为它会阻塞 IOLoop,而且我还发现一些 library/tools 正在处理此问题。 但是最近我在Whosebug

上发现了很多关于这个问题的帖子

Tornado Asynchronous Handler

How does async work in Tornado?

以及来自 wiki 的内容 https://github.com/tornadoweb/tornado/wiki/Threading-and-concurrency

Do it synchronously and block the IOLoop. This is most appropriate for things like memcache and database queries that are under your control and should always be fast. If it's not fast, make it fast by adding the appropriate indexes to the database, etc.

那么我们应该异步调用数据库吗?

和一个相关问题:据我所知,有两种方法可以进行异步数据库调用

它们基于龙卷风有何不同?

我也有类似的疑问,经过一些研究和挖掘,终于掌握了一些。

简短回答 - 是的,异步执行。

长答案: 数据库调用一般都是阻塞调用。当我们进行 async/Non-blocking I/O 调用以完全发挥其全部潜力时,Tornado 最适合作为框架。

现在,您可以通过以下方式在 Tornado 中进行数据库调用,我给出了每种方法的方法和原因。

方法 1Synchronous Database Calls - 在负载均衡器(例如 nginx)后面启动多个 Tornado 实例,并且进行同步数据库调用(如 wiki 中所述)。在这种情况下,发出阻塞数据库调用的特定请求的进程将被阻塞。因此 nginx 将通过将其他请求定向到其他 运行 龙卷风实例来处理请求来负载平衡其他请求。

注意 :那个 wiki 很旧,还没有更新,所以提到的方法是在 [= 提到的新版本的 Tornado 中添加协程之前21=],Tornado 的主要开发人员之一。

更新 : 最近Ben更新了wiki,您现在可以查看。

方法2:通过使用多处理或多线程,concurrent.futures,类似于你提到的:

For sync database(mysqldb), we can

executor = ThreadPoolExecutor(4)

result = yield executor.submit(mysqldb_operation)

方法 3 :通过使用异步库,例如如果您正在使用 MySql,那么您可以使用TorMySql, Tornado-MySQL, other links given here-Tornado 3rd-party libraries 等库,请转到 MySql 部分。这些库将与 Tornado 的异步装饰器一起使用,tornado.gen.coroutinetornado.web.asynchronous。同样,您需要为不同的数据库使用其他异步库。

注意 :您不能使用阻塞库,否则它与 Method 1

结论 : Method 3 是我提到的 Short AnswerMethod 2 是下一个最佳解决方案,其次是 Method 1。这符合您的性能要求。如果您的要求是每秒或每分钟处理不那么繁重(很少到中等)的请求,那么简单而通用的 Method 1 就足够了。