2016-07-13 2 views
0

Обычно драйверы РСУБД блокируются, а Tornado - неблокирующий сервер. Это приводит к нерациональному использованию async при выполнении CRUD-операций, поскольку IOLoop будет заблокирован до завершения этого SQL-запроса.Интеграция RDBMS Tornado

Я работаю над проектом, использующим РСУБД как БД (из-за ACID), но который также требует, чтобы Websockets организовывали какую-то фантастическую функцию (то есть push-уведомления), а после некоторого googling я думаю об использовании Tornado, потому что оба обычные REST и Websockets могут быть реализованы в одном приложении.

Сидя в Интернете, я нашел этот фрагмент (здесь: https://gist.github.com/methane/2185380):

import time 

from tornado.concurrent import run_on_executor 
from concurrent.futures import ThreadPoolExecutor # `pip install futures` for python2 

MAX_WORKERS = 4 


class Handler(tornado.web.RequestHandler): 
    executor = ThreadPoolExecutor(max_workers=MAX_WORKERS) 

    @run_on_executor 
    def background_task(self, i): 
     """ This will be executed in `executor` pool. """ 
     time.sleep(10) 
     return i 

    @tornado.gen.coroutine 
    def get(self, idx): 
     """ Request that asynchronously calls background task. """ 
     res = yield self.background_task(idx) 
     self.write(res) 

Что в основном делает это толкает CRUD задачу в отдельном потоке. Мой вопрос: является ли это стандартным подходом к блокированию драйверов РСУБД при использовании асинхронного HTTP-сервера? Существуют ли какие-либо другие способы минимизации этих блокирующих узких мест? Можно ли даже использовать блокирующий драйвер RDBMS с асинхронным сервером?

ответ

1

Существует несколько способов борьбы с РСУБД в торнадо.

Есть несколько библиотек для различных БД для их асинхронного использования в Торнадо. https://github.com/tornadoweb/tornado/wiki/Links

Вы также можете использовать GEvent, чтобы получить доступ к асинхронному доступу к db в Tornado.

Другой вариант заключается в использовании асинхр Python3 ю библиотеку с Торнадо, такие как: https://aiopg.readthedocs.io/en/stable/

Как вы отметили другой вариант является, чтобы разгрузить нагрузку DB в других местах. Вы можете использовать очередь сообщений, такую ​​как ZeroMQ или RabbitMQ, несколько потоков, несколько процессов, API для другого.

Вы также можете использовать стандартные блокирующие механизмы доступа к базе данных, они все равно будут работать в Tornado, они просто блокируются до тех пор, пока не вернутся, это может быть или не быть проблемой.

Я дал поговорить о Момоко, Aiopg и GEvent в PyOhio в прошлом году: http://pyvideo.org/video/3698/from-synchronous-to-asynchronous-postgres-with-to

+0

Спасибо! Я читал, что все Python-асинхронные RDBMS-драйверы/ORM не настолько надежны. Люди говорят: «Трудно создать ОРМ, еще труднее сделать это правильно». Также, как насчет совместимости при использовании доступа к асинхронной базе данных? – lime

+0

Какова цель использования asyncio + Tornado? У них обоих есть IOLoops, почему бы просто не использовать по умолчанию Tornado? Даже для не веб-материалов петля Торнадо может быть успешно использована в том же манере. – lime

+0

1. Что касается надежности, у меня пока не было никаких проблем, но это не означает, что проблем нет. Есть намного меньше людей, использующих асинхронные вещи, чем синхронные вещи, поэтому с меньшим количеством глаз я ожидаю больше проблем. 2. Я согласен с тем, что ORM трудны. Я ненавижу ORM на основе реализации ActiveRecord. Поскольку я использую только Postgres, я создал один файл orm, который отображает только объекты и отношения, и ни один другой материал. 3. Параллелизм может быть проблемой в async, по крайней мере, в postgres, когда вы включаете async, вы не можете использовать и автоматически использовать txn, вам нужно позвонить begin and commit –